mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-02-09 05:52:52 +08:00
Open state framework (#1483)
* Added more server debug options * made server debug code prettier * fixed initialization bug * Enables logging of packets contained in UnionCmdNotify, when debug level is WHITELIST or BLACKLIST * Fully Implement OpenState Framework * added devOpenStates * Commented out newPlayerOpenStates * Removed OPEN_STATE_NONE from devOpenStates
This commit is contained in:
parent
ae8b5e30ac
commit
b5a4ab7524
@ -104,7 +104,7 @@ public class Player {
|
||||
private Position rotation;
|
||||
private PlayerBirthday birthday;
|
||||
private PlayerCodex codex;
|
||||
|
||||
@Getter private PlayerOpenStateManager openStateManager;
|
||||
private Map<Integer, Integer> properties;
|
||||
private Set<Integer> nameCardList;
|
||||
private Set<Integer> flyCloakList;
|
||||
@ -187,7 +187,7 @@ public class Player {
|
||||
@Transient private FurnitureManager furnitureManager;
|
||||
@Transient private BattlePassManager battlePassManager;
|
||||
@Transient private CookingManager cookingManager;
|
||||
// @Transient private
|
||||
// @Transient private
|
||||
@Getter @Transient private ActivityManager activityManager;
|
||||
|
||||
@Transient private CollectionManager collectionManager;
|
||||
@ -248,7 +248,7 @@ public class Player {
|
||||
this.rewardedLevels = new HashSet<>();
|
||||
this.moonCardGetTimes = new HashSet<>();
|
||||
this.codex = new PlayerCodex(this);
|
||||
|
||||
this.openStateManager = new PlayerOpenStateManager(this);
|
||||
this.shopLimit = new ArrayList<>();
|
||||
this.expeditionInfo = new HashMap<>();
|
||||
this.messageHandler = null;
|
||||
@ -468,7 +468,7 @@ public class Player {
|
||||
public int getWorldLevel() {
|
||||
return this.getProperty(PlayerProperty.PROP_PLAYER_WORLD_LEVEL);
|
||||
}
|
||||
|
||||
|
||||
public boolean setWorldLevel(int level) {
|
||||
if (this.setProperty(PlayerProperty.PROP_PLAYER_WORLD_LEVEL, level)) {
|
||||
if (this.world.getHost() == this) // Don't update World's WL if we are in someone else's world
|
||||
@ -1445,6 +1445,7 @@ public class Player {
|
||||
@PostLoad
|
||||
private void onLoad() {
|
||||
this.getCodex().setPlayer(this);
|
||||
this.getOpenStateManager().setPlayer(this);
|
||||
this.getTeamManager().setPlayer(this);
|
||||
this.getTowerManager().setPlayer(this);
|
||||
}
|
||||
@ -1465,6 +1466,9 @@ public class Player {
|
||||
if (this.getCodex() == null) {
|
||||
this.codex = new PlayerCodex(this);
|
||||
}
|
||||
if (this.getOpenStateManager() == null) {
|
||||
this.openStateManager = new PlayerOpenStateManager(this);
|
||||
}
|
||||
if (this.getProfile().getUid() == 0) {
|
||||
this.getProfile().syncWithCharacter(this);
|
||||
}
|
||||
@ -1525,6 +1529,7 @@ public class Player {
|
||||
this.forgingManager.sendForgeDataNotify();
|
||||
this.resinManager.onPlayerLogin();
|
||||
this.cookingManager.sendCookDataNofity();
|
||||
this.openStateManager.onPlayerLogin();
|
||||
getTodayMoonCard(); // The timer works at 0:0, some users log in after that, use this method to check if they have received a reward today or not. If not, send the reward.
|
||||
|
||||
// Battle Pass trigger
|
||||
@ -1539,7 +1544,7 @@ public class Player {
|
||||
|
||||
session.send(new PacketPlayerEnterSceneNotify(this)); // Enter game world
|
||||
session.send(new PacketPlayerLevelRewardUpdateNotify(rewardedLevels));
|
||||
session.send(new PacketOpenStateUpdateNotify());
|
||||
|
||||
|
||||
// First notify packets sent
|
||||
this.setHasSentAvatarDataNotify(true);
|
||||
|
@ -0,0 +1,246 @@
|
||||
package emu.grasscutter.game.player;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Transient;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.OpenState;
|
||||
import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketOpenStateUpdateNotify;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static emu.grasscutter.game.props.OpenState.*;
|
||||
|
||||
@Entity
|
||||
public class PlayerOpenStateManager {
|
||||
|
||||
@Transient private Player player;
|
||||
@Getter private Map<Integer,Integer> openStateMap;
|
||||
/*
|
||||
//DO NOT MODIFY. Based on conversation of official server and client, game version 2.7
|
||||
private static Set<OpenState> newPlayerOpenStates = Set.of(OPEN_STATE_DERIVATIVE_MALL,OPEN_STATE_PHOTOGRAPH,OPEN_STATE_BATTLE_PASS,OPEN_STATE_SHOP_TYPE_GENESISCRYSTAL,OPEN_STATE_SHOP_TYPE_RECOMMANDED,
|
||||
OPEN_STATE_SHOP_TYPE_GIFTPACKAGE,OPEN_STATE_GUIDE_RELIC_PROM,OPEN_STATE_GUIDE_TALENT,OPEN_STATE_SHOP_TYPE_BLACKSMITH,OPEN_STATE_SHOP_TYPE_PAIMON,OPEN_STATE_WEAPON_AWAKEN,
|
||||
OPEN_STATE_WEAPON_PROMOTE,OPEN_STATE_AVATAR_PROMOTE,OPEN_STATE_AVATAR_TALENT,OPEN_STATE_WEAPON_UPGRADE,OPEN_STATE_RESIN,OPEN_STATE_RELIQUARY_UPGRADE,
|
||||
OPEN_STATE_SHOP_TYPE_VIRTUAL_SHOP,OPEN_STATE_RELIQUARY_PROMOTE);
|
||||
*/
|
||||
//For development. Remove entry when properly implemented
|
||||
private static Set<OpenState> devOpenStates = Set.of(
|
||||
OPEN_STATE_PAIMON,
|
||||
OPEN_STATE_PAIMON_NAVIGATION,
|
||||
OPEN_STATE_AVATAR_PROMOTE,
|
||||
OPEN_STATE_AVATAR_TALENT,
|
||||
OPEN_STATE_WEAPON_PROMOTE,
|
||||
OPEN_STATE_WEAPON_AWAKEN,
|
||||
OPEN_STATE_QUEST_REMIND,
|
||||
OPEN_STATE_GAME_GUIDE,
|
||||
OPEN_STATE_COOK,
|
||||
OPEN_STATE_WEAPON_UPGRADE,
|
||||
OPEN_STATE_RELIQUARY_UPGRADE,
|
||||
OPEN_STATE_RELIQUARY_PROMOTE,
|
||||
OPEN_STATE_WEAPON_PROMOTE_GUIDE,
|
||||
OPEN_STATE_WEAPON_CHANGE_GUIDE,
|
||||
OPEN_STATE_PLAYER_LVUP_GUIDE,
|
||||
OPEN_STATE_FRESHMAN_GUIDE,
|
||||
OPEN_STATE_SKIP_FRESHMAN_GUIDE,
|
||||
OPEN_STATE_GUIDE_MOVE_CAMERA,
|
||||
OPEN_STATE_GUIDE_SCALE_CAMERA,
|
||||
OPEN_STATE_GUIDE_KEYBOARD,
|
||||
OPEN_STATE_GUIDE_MOVE,
|
||||
OPEN_STATE_GUIDE_JUMP,
|
||||
OPEN_STATE_GUIDE_SPRINT,
|
||||
OPEN_STATE_GUIDE_MAP,
|
||||
OPEN_STATE_GUIDE_ATTACK,
|
||||
OPEN_STATE_GUIDE_FLY,
|
||||
OPEN_STATE_GUIDE_TALENT,
|
||||
OPEN_STATE_GUIDE_RELIC,
|
||||
OPEN_STATE_GUIDE_RELIC_PROM,
|
||||
OPEN_STATE_COMBINE,
|
||||
OPEN_STATE_GACHA,
|
||||
OPEN_STATE_GUIDE_GACHA,
|
||||
OPEN_STATE_GUIDE_TEAM,
|
||||
OPEN_STATE_GUIDE_PROUD,
|
||||
OPEN_STATE_GUIDE_AVATAR_PROMOTE,
|
||||
OPEN_STATE_GUIDE_ADVENTURE_CARD,
|
||||
OPEN_STATE_FORGE,
|
||||
OPEN_STATE_GUIDE_BAG,
|
||||
OPEN_STATE_EXPEDITION,
|
||||
OPEN_STATE_GUIDE_ADVENTURE_DAILYTASK,
|
||||
OPEN_STATE_GUIDE_ADVENTURE_DUNGEON,
|
||||
OPEN_STATE_TOWER,
|
||||
OPEN_STATE_WORLD_STAMINA,
|
||||
OPEN_STATE_TOWER_FIRST_ENTER,
|
||||
OPEN_STATE_RESIN,
|
||||
OPEN_STATE_LIMIT_REGION_FRESHMEAT,
|
||||
OPEN_STATE_LIMIT_REGION_GLOBAL,
|
||||
OPEN_STATE_MULTIPLAYER,
|
||||
OPEN_STATE_GUIDE_MOUSEPC,
|
||||
OPEN_STATE_GUIDE_MULTIPLAYER,
|
||||
OPEN_STATE_GUIDE_DUNGEONREWARD,
|
||||
OPEN_STATE_GUIDE_BLOSSOM,
|
||||
OPEN_STATE_AVATAR_FASHION,
|
||||
OPEN_STATE_PHOTOGRAPH,
|
||||
OPEN_STATE_GUIDE_KSLQUEST,
|
||||
OPEN_STATE_PERSONAL_LINE,
|
||||
OPEN_STATE_GUIDE_PERSONAL_LINE,
|
||||
OPEN_STATE_GUIDE_APPEARANCE,
|
||||
OPEN_STATE_GUIDE_PROCESS,
|
||||
OPEN_STATE_GUIDE_PERSONAL_LINE_KEY,
|
||||
OPEN_STATE_GUIDE_WIDGET,
|
||||
OPEN_STATE_GUIDE_ACTIVITY_SKILL_ASTER,
|
||||
OPEN_STATE_GUIDE_COLDCLIMATE,
|
||||
OPEN_STATE_DERIVATIVE_MALL,
|
||||
OPEN_STATE_GUIDE_EXITMULTIPLAYER,
|
||||
OPEN_STATE_GUIDE_THEATREMACHANICUS_BUILD,
|
||||
OPEN_STATE_GUIDE_THEATREMACHANICUS_REBUILD,
|
||||
OPEN_STATE_GUIDE_THEATREMACHANICUS_CARD,
|
||||
OPEN_STATE_GUIDE_THEATREMACHANICUS_MONSTER,
|
||||
OPEN_STATE_GUIDE_THEATREMACHANICUS_MISSION_CHECK,
|
||||
OPEN_STATE_GUIDE_THEATREMACHANICUS_BUILD_SELECT,
|
||||
OPEN_STATE_GUIDE_THEATREMACHANICUS_CHALLENGE_START,
|
||||
OPEN_STATE_GUIDE_CONVERT,
|
||||
OPEN_STATE_GUIDE_THEATREMACHANICUS_MULTIPLAYER,
|
||||
OPEN_STATE_GUIDE_COOP_TASK,
|
||||
OPEN_STATE_GUIDE_HOMEWORLD_ADEPTIABODE,
|
||||
OPEN_STATE_GUIDE_HOMEWORLD_DEPLOY,
|
||||
OPEN_STATE_GUIDE_CHANNELLERSLAB_EQUIP,
|
||||
OPEN_STATE_GUIDE_CHANNELLERSLAB_MP_SOLUTION,
|
||||
OPEN_STATE_GUIDE_CHANNELLERSLAB_POWER,
|
||||
OPEN_STATE_GUIDE_HIDEANDSEEK_SKILL,
|
||||
OPEN_STATE_GUIDE_HOMEWORLD_MAPLIST,
|
||||
OPEN_STATE_GUIDE_RELICRESOLVE,
|
||||
OPEN_STATE_GUIDE_GGUIDE,
|
||||
OPEN_STATE_GUIDE_GGUIDE_HINT,
|
||||
OPEN_STATE_GUIDE_RIGHT_TEAM, // mobile phone only!
|
||||
OPEN_STATE_CITY_REPUATION_MENGDE,
|
||||
OPEN_STATE_CITY_REPUATION_LIYUE,
|
||||
OPEN_STATE_CITY_REPUATION_UI_HINT,
|
||||
OPEN_STATE_CITY_REPUATION_INAZUMA,
|
||||
OPEN_STATE_SHOP_TYPE_MALL,
|
||||
OPEN_STATE_SHOP_TYPE_RECOMMANDED,
|
||||
OPEN_STATE_SHOP_TYPE_GENESISCRYSTAL,
|
||||
OPEN_STATE_SHOP_TYPE_GIFTPACKAGE,
|
||||
OPEN_STATE_SHOP_TYPE_PAIMON,
|
||||
OPEN_STATE_SHOP_TYPE_CITY,
|
||||
OPEN_STATE_SHOP_TYPE_BLACKSMITH,
|
||||
OPEN_STATE_SHOP_TYPE_GROCERY,
|
||||
OPEN_STATE_SHOP_TYPE_FOOD,
|
||||
OPEN_STATE_SHOP_TYPE_SEA_LAMP,
|
||||
OPEN_STATE_SHOP_TYPE_VIRTUAL_SHOP,
|
||||
OPEN_STATE_SHOP_TYPE_LIYUE_GROCERY,
|
||||
OPEN_STATE_SHOP_TYPE_LIYUE_SOUVENIR,
|
||||
OPEN_STATE_SHOP_TYPE_LIYUE_RESTAURANT,
|
||||
OPEN_STATE_SHOP_TYPE_INAZUMA_SOUVENIR,
|
||||
OPEN_STATE_SHOP_TYPE_NPC_TOMOKI,
|
||||
OPEN_ADVENTURE_MANUAL,
|
||||
OPEN_ADVENTURE_MANUAL_CITY_MENGDE,
|
||||
OPEN_ADVENTURE_MANUAL_CITY_LIYUE,
|
||||
OPEN_ADVENTURE_MANUAL_MONSTER,
|
||||
OPEN_ADVENTURE_MANUAL_BOSS_DUNGEON,
|
||||
OPEN_STATE_ACTIVITY_SEALAMP,
|
||||
OPEN_STATE_ACTIVITY_SEALAMP_TAB2,
|
||||
OPEN_STATE_ACTIVITY_SEALAMP_TAB3,
|
||||
OPEN_STATE_BATTLE_PASS,
|
||||
OPEN_STATE_BATTLE_PASS_ENTRY,
|
||||
OPEN_STATE_ACTIVITY_CRUCIBLE,
|
||||
OPEN_STATE_ACTIVITY_NEWBEEBOUNS_OPEN,
|
||||
OPEN_STATE_ACTIVITY_NEWBEEBOUNS_CLOSE,
|
||||
OPEN_STATE_ACTIVITY_ENTRY_OPEN,
|
||||
OPEN_STATE_MENGDE_INFUSEDCRYSTAL,
|
||||
OPEN_STATE_LIYUE_INFUSEDCRYSTAL,
|
||||
OPEN_STATE_SNOW_MOUNTAIN_ELDER_TREE,
|
||||
OPEN_STATE_MIRACLE_RING,
|
||||
OPEN_STATE_COOP_LINE,
|
||||
OPEN_STATE_INAZUMA_INFUSEDCRYSTAL,
|
||||
OPEN_STATE_FISH,
|
||||
OPEN_STATE_GUIDE_SUMO_TEAM_SKILL,
|
||||
OPEN_STATE_GUIDE_FISH_RECIPE,
|
||||
OPEN_STATE_HOME,
|
||||
OPEN_STATE_ACTIVITY_HOMEWORLD,
|
||||
OPEN_STATE_ADEPTIABODE,
|
||||
OPEN_STATE_HOME_AVATAR,
|
||||
OPEN_STATE_HOME_EDIT,
|
||||
OPEN_STATE_HOME_EDIT_TIPS,
|
||||
OPEN_STATE_RELIQUARY_DECOMPOSE,
|
||||
OPEN_STATE_ACTIVITY_H5,
|
||||
OPEN_STATE_ORAIONOKAMI,
|
||||
OPEN_STATE_GUIDE_CHESS_MISSION_CHECK,
|
||||
OPEN_STATE_GUIDE_CHESS_BUILD,
|
||||
OPEN_STATE_GUIDE_CHESS_WIND_TOWER_CIRCLE,
|
||||
OPEN_STATE_GUIDE_CHESS_CARD_SELECT,
|
||||
OPEN_STATE_INAZUMA_MAINQUEST_FINISHED,
|
||||
OPEN_STATE_PAIMON_LVINFO,
|
||||
OPEN_STATE_TELEPORT_HUD,
|
||||
OPEN_STATE_GUIDE_MAP_UNLOCK,
|
||||
OPEN_STATE_GUIDE_PAIMON_LVINFO,
|
||||
OPEN_STATE_GUIDE_AMBORTRANSPORT,
|
||||
OPEN_STATE_GUIDE_FLY_SECOND,
|
||||
OPEN_STATE_GUIDE_KAEYA_CLUE,
|
||||
OPEN_STATE_CAPTURE_CODEX,
|
||||
OPEN_STATE_ACTIVITY_FISH_OPEN,
|
||||
OPEN_STATE_ACTIVITY_FISH_CLOSE,
|
||||
OPEN_STATE_GUIDE_ROGUE_MAP,
|
||||
OPEN_STATE_GUIDE_ROGUE_RUNE,
|
||||
OPEN_STATE_GUIDE_BARTENDER_FORMULA,
|
||||
OPEN_STATE_GUIDE_BARTENDER_MIX,
|
||||
OPEN_STATE_GUIDE_BARTENDER_CUP,
|
||||
OPEN_STATE_GUIDE_MAIL_FAVORITES,
|
||||
OPEN_STATE_GUIDE_POTION_CONFIGURE,
|
||||
OPEN_STATE_GUIDE_LANV2_FIREWORK,
|
||||
OPEN_STATE_LOADINGTIPS_ENKANOMIYA,
|
||||
OPEN_STATE_MICHIAE_CASKET,
|
||||
OPEN_STATE_MAIL_COLLECT_UNLOCK_RED_POINT,
|
||||
OPEN_STATE_LUMEN_STONE,
|
||||
OPEN_STATE_GUIDE_CRYSTALLINK_BUFF
|
||||
);
|
||||
|
||||
public PlayerOpenStateManager(Player player) {
|
||||
this.openStateMap = new HashMap<>();
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public Integer getOpenState(OpenState openState) {
|
||||
return this.openStateMap.getOrDefault(openState.getValue(), 0);
|
||||
}
|
||||
public void setOpenState(OpenState openState, Integer value) {
|
||||
Integer previousValue = this.openStateMap.getOrDefault(openState.getValue(),0);
|
||||
if(!(value == previousValue)) {
|
||||
this.openStateMap.put(openState.getValue(), value);
|
||||
player.getSession().send(new PacketOpenStateChangeNotify(openState.getValue(),value));
|
||||
} else {
|
||||
Grasscutter.getLogger().debug("Warning: OpenState {} is already set to {}!", openState, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOpenStates(Map<OpenState,Integer> openStatesChanged) {
|
||||
for(Map.Entry<OpenState, Integer> entry : openStatesChanged.entrySet()) {
|
||||
setOpenState(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void onNewPlayerCreate() {
|
||||
//newPlayerOpenStates.forEach(os -> this.setOpenState(os, 1));
|
||||
//setAllOpenStates();
|
||||
devOpenStates.forEach(os -> this.setOpenState(os, 1));
|
||||
}
|
||||
public void onPlayerLogin() {
|
||||
/*
|
||||
//little hack to give all openStates on second login
|
||||
if(openStateMap.containsKey(OPEN_STATE_FRESHMAN_GUIDE.getValue())) {
|
||||
setAllOpenStates();
|
||||
}
|
||||
*/
|
||||
player.getSession().send(new PacketOpenStateUpdateNotify(player));
|
||||
}
|
||||
|
||||
public void setAllOpenStates() {
|
||||
Stream.of(OpenState.values()).forEach(os -> this.setOpenState(os, 1));
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ import static emu.grasscutter.Configuration.ACCOUNT;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerLoginReq) // Sends initial data packets
|
||||
public class HandlerPlayerLoginReq extends PacketHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Check
|
||||
@ -28,18 +28,20 @@ public class HandlerPlayerLoginReq extends PacketHandler {
|
||||
|
||||
// Parse request
|
||||
PlayerLoginReq req = PlayerLoginReq.parseFrom(payload);
|
||||
|
||||
|
||||
// Authenticate session
|
||||
if (!req.getToken().equals(session.getAccount().getToken())) {
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Load character from db
|
||||
Player player = session.getPlayer();
|
||||
|
||||
|
||||
// Show opening cutscene if player has no avatars
|
||||
if (player.getAvatars().getAvatarCount() == 0) {
|
||||
// Set New Player OpenStates
|
||||
player.getOpenStateManager().onNewPlayerCreate();
|
||||
// Pick character
|
||||
session.setState(SessionState.PICKING_CHARACTER);
|
||||
session.send(new BasePacket(PacketOpcodes.DoSetPlayerBornDataNotify));
|
||||
|
@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.game.props.OpenState;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetOpenStateReqOuterClass.SetOpenStateReq;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketSetOpenStateRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetOpenStateReq)
|
||||
public class HandlerSetOpenStateReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req = SetOpenStateReq.parseFrom(payload);
|
||||
int openState = req.getKey();
|
||||
int value = req.getValue();
|
||||
|
||||
session.getPlayer().getOpenStateManager().setOpenState(OpenState.getTypeByValue(openState), value);
|
||||
//Client Automatically Updates its OpenStateMap, no need to send OpenStateUpdateNotify
|
||||
|
||||
session.send(new PacketSetOpenStateRsp(openState,value));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.OpenStateChangeNotifyOuterClass.OpenStateChangeNotify;
|
||||
|
||||
//Sets openState to value
|
||||
public class PacketOpenStateChangeNotify extends BasePacket {
|
||||
|
||||
public PacketOpenStateChangeNotify(int openState, int value) {
|
||||
super(PacketOpcodes.OpenStateChangeNotify);
|
||||
|
||||
OpenStateChangeNotify proto = OpenStateChangeNotify.newBuilder()
|
||||
.putOpenStateMap(openState,value).build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
}
|
@ -1,22 +1,25 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.player.PlayerOpenStateManager;
|
||||
import emu.grasscutter.game.props.OpenState;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.OpenStateUpdateNotifyOuterClass.OpenStateUpdateNotify;
|
||||
|
||||
import java.util.Map;
|
||||
/*
|
||||
Must be sent on login for openStates to work
|
||||
Tells the client to update its openStateMap for the keys sent. value is irrelevant
|
||||
*/
|
||||
public class PacketOpenStateUpdateNotify extends BasePacket {
|
||||
|
||||
public PacketOpenStateUpdateNotify() {
|
||||
|
||||
public PacketOpenStateUpdateNotify(Player player) {
|
||||
super(PacketOpcodes.OpenStateUpdateNotify);
|
||||
|
||||
|
||||
OpenStateUpdateNotify.Builder proto = OpenStateUpdateNotify.newBuilder();
|
||||
|
||||
for (OpenState type : OpenState.values()) {
|
||||
if (type.getValue() > 0) {
|
||||
proto.putOpenStateMap(type.getValue(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
proto.putAllOpenStateMap(player.getOpenStateManager().getOpenStateMap()).build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetOpenStateRspOuterClass.SetOpenStateRsp;
|
||||
|
||||
public class PacketSetOpenStateRsp extends BasePacket {
|
||||
|
||||
public PacketSetOpenStateRsp(int openState, int value) {
|
||||
super(PacketOpcodes.SetOpenStateRsp);
|
||||
|
||||
SetOpenStateRsp proto = SetOpenStateRsp.newBuilder()
|
||||
.setKey(openState).setValue(value).build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user