diff --git a/proto/HomeChooseModuleReq.proto b/proto/HomeChooseModuleReq.proto new file mode 100644 index 000000000..9be2b91ab --- /dev/null +++ b/proto/HomeChooseModuleReq.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + + +message HomeChooseModuleReq { + enum CmdId { + option allow_alias = true; + ENET_CHANNEL_ID = 0; + NONE = 0; + ENET_IS_RELIABLE = 1; + IS_ALLOW_CLIENT = 1; + CMD_ID = 4530; + } + + uint32 module_id = 1; +} \ No newline at end of file diff --git a/proto/HomeChooseModuleRsp.proto b/proto/HomeChooseModuleRsp.proto new file mode 100644 index 000000000..7425d419e --- /dev/null +++ b/proto/HomeChooseModuleRsp.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + + +message HomeChooseModuleRsp { + enum CmdId { + option allow_alias = true; + NONE = 0; + ENET_CHANNEL_ID = 0; + ENET_IS_RELIABLE = 1; + CMD_ID = 4653; + } + + int32 retcode = 1; + uint32 module_id = 2; +} \ No newline at end of file diff --git a/proto/HomeComfortInfoNotify.proto b/proto/HomeComfortInfoNotify.proto new file mode 100644 index 000000000..e66e14d06 --- /dev/null +++ b/proto/HomeComfortInfoNotify.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "HomeModuleComfortInfo.proto"; + +message HomeComfortInfoNotify { + enum CmdId { + option allow_alias = true; + NONE = 0; + ENET_CHANNEL_ID = 0; + ENET_IS_RELIABLE = 1; + CMD_ID = 4557; + } + + repeated HomeModuleComfortInfo module_info_list = 1; +} \ No newline at end of file diff --git a/proto/HomeModuleComfortInfo.proto b/proto/HomeModuleComfortInfo.proto new file mode 100644 index 000000000..d7d54fc31 --- /dev/null +++ b/proto/HomeModuleComfortInfo.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + + +message HomeModuleComfortInfo { + uint32 module_id = 1; + repeated uint32 world_scene_block_comfort_value_list = 2; + uint32 room_scene_comfort_value = 3; +} \ No newline at end of file diff --git a/proto/PlayerHomeCompInfo.proto b/proto/PlayerHomeCompInfo.proto new file mode 100644 index 000000000..a3015df84 --- /dev/null +++ b/proto/PlayerHomeCompInfo.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "FriendEnterHomeOption.proto"; + +message PlayerHomeCompInfo { + FriendEnterHomeOption friend_enter_home_option = 1; + repeated uint32 unlocked_module_id_list = 2; + repeated uint32 levelup_reward_got_level_list = 3; + repeated uint32 seen_module_id_list = 4; +} \ No newline at end of file diff --git a/proto/PlayerHomeCompInfoNotify.proto b/proto/PlayerHomeCompInfoNotify.proto new file mode 100644 index 000000000..61ec3e7f2 --- /dev/null +++ b/proto/PlayerHomeCompInfoNotify.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "PlayerHomeCompInfo.proto"; + +message PlayerHomeCompInfoNotify { + enum CmdId { + option allow_alias = true; + NONE = 0; + ENET_CHANNEL_ID = 0; + ENET_IS_RELIABLE = 1; + CMD_ID = 4628; + } + + PlayerHomeCompInfo comp_info = 1; +} \ No newline at end of file diff --git a/proto/TryEnterHomeReq.proto b/proto/TryEnterHomeReq.proto new file mode 100644 index 000000000..220787898 --- /dev/null +++ b/proto/TryEnterHomeReq.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + + +message TryEnterHomeReq { + enum CmdId { + option allow_alias = true; + ENET_CHANNEL_ID = 0; + NONE = 0; + ENET_IS_RELIABLE = 1; + IS_ALLOW_CLIENT = 1; + CMD_ID = 4792; + } + + uint32 target_uid = 1; + uint32 target_point = 2; +} \ No newline at end of file diff --git a/proto/TryEnterHomeRsp.proto b/proto/TryEnterHomeRsp.proto new file mode 100644 index 000000000..a1e1f8c22 --- /dev/null +++ b/proto/TryEnterHomeRsp.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + + +message TryEnterHomeRsp { + enum CmdId { + option allow_alias = true; + NONE = 0; + ENET_CHANNEL_ID = 0; + ENET_IS_RELIABLE = 1; + CMD_ID = 4690; + } + + int32 retcode = 1; + uint32 target_uid = 2; + repeated uint32 param_list = 3; +} \ No newline at end of file diff --git a/src/main/java/emu/grasscutter/game/player/Player.java b/src/main/java/emu/grasscutter/game/player/Player.java index b7d8470bf..9c9f1ea56 100644 --- a/src/main/java/emu/grasscutter/game/player/Player.java +++ b/src/main/java/emu/grasscutter/game/player/Player.java @@ -87,6 +87,9 @@ public class Player { private Integer widgetId; + private Set realmList; + private Integer currentRealmId; + @Transient private long nextGuid = 0; @Transient private int peerId; @Transient private World world; @@ -313,6 +316,31 @@ public class Player { this.widgetId = widgetId; } + public Set getRealmList() { + return realmList; + } + + public void setRealmList(Set realmList) { + this.realmList = realmList; + } + + public void addRealmList(int realmId) { + if (this.realmList == null) { + this.realmList = new HashSet<>(); + } else if (this.realmList.contains(realmId)) { + return; + } + this.realmList.add(realmId); + } + + public Integer getCurrentRealmId() { + return currentRealmId; + } + + public void setCurrentRealmId(Integer currentRealmId) { + this.currentRealmId = currentRealmId; + } + public Position getPos() { return pos; } @@ -1187,6 +1215,8 @@ public class Player { session.send(new PacketServerCondMeetQuestListUpdateNotify(this)); session.send(new PacketAllWidgetDataNotify(this)); session.send(new PacketWidgetGadgetAllDataNotify()); + session.send(new PacketPlayerHomeCompInfoNotify(this)); + session.send(new PacketHomeComfortInfoNotify(this)); 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. diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeChooseModuleReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeChooseModuleReq.java new file mode 100644 index 000000000..5a7c0dbe5 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeChooseModuleReq.java @@ -0,0 +1,26 @@ +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.net.packet.Opcodes; +import emu.grasscutter.net.packet.PacketHandler; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.HomeChooseModuleReqOuterClass; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketHomeChooseModuleRsp; +import emu.grasscutter.server.packet.send.PacketHomeComfortInfoNotify; +import emu.grasscutter.server.packet.send.PacketPlayerHomeCompInfoNotify; + + +@Opcodes(PacketOpcodes.HomeChooseModuleReq) +public class HandlerHomeChooseModuleReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + HomeChooseModuleReqOuterClass.HomeChooseModuleReq req = + HomeChooseModuleReqOuterClass.HomeChooseModuleReq.parseFrom(payload); + session.getPlayer().addRealmList(req.getModuleId()); + session.getPlayer().setCurrentRealmId(req.getModuleId()); + session.send(new PacketHomeChooseModuleRsp(req.getModuleId())); + session.send(new PacketPlayerHomeCompInfoNotify(session.getPlayer())); + session.send(new PacketHomeComfortInfoNotify(session.getPlayer())); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerTryEnterHomeReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerTryEnterHomeReq.java new file mode 100644 index 000000000..3e78bcb3a --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerTryEnterHomeReq.java @@ -0,0 +1,68 @@ +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.Grasscutter; +import emu.grasscutter.net.packet.Opcodes; +import emu.grasscutter.net.packet.PacketHandler; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.TryEnterHomeReqOuterClass; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketTryEnterHomeRsp; +import emu.grasscutter.utils.Position; + +@Opcodes(PacketOpcodes.TryEnterHomeReq) +public class HandlerTryEnterHomeReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + TryEnterHomeReqOuterClass.TryEnterHomeReq req = + TryEnterHomeReqOuterClass.TryEnterHomeReq.parseFrom(payload); + + if (req.getTargetUid() != session.getPlayer().getUid()) { + // I hope that tomorrow there will be a hero who can support multiplayer mode and write code like a poem + session.send(new PacketTryEnterHomeRsp()); + return; + } + + // Hardcoded for now + switch (session.getPlayer().getCurrentRealmId()) { + case 1: + session.getPlayer().getWorld().transferPlayerToScene( + session.getPlayer(), + 2001, + new Position(839, 319, 137) + ); + break; + + case 2: + session.getPlayer().getWorld().transferPlayerToScene( + session.getPlayer(), + 2002, + new Position(605, 444, 554) + ); + break; + + case 3: + session.getPlayer().getWorld().transferPlayerToScene( + session.getPlayer(), + 2003, + new Position(511, 229, 605) + ); + break; + + case 4: + session.getPlayer().getWorld().transferPlayerToScene( + session.getPlayer(), + 2004, + new Position(239, 187, 536) + ); + break; + + default: + session.send(new PacketTryEnterHomeRsp()); + return; + } + + + session.send(new PacketTryEnterHomeRsp(req.getTargetUid())); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeChooseModuleRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeChooseModuleRsp.java new file mode 100644 index 000000000..e7b3ff1ea --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeChooseModuleRsp.java @@ -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.HomeChooseModuleRspOuterClass; + +public class PacketHomeChooseModuleRsp extends BasePacket { + + public PacketHomeChooseModuleRsp(int moduleId) { + super(PacketOpcodes.HomeChooseModuleRsp); + + HomeChooseModuleRspOuterClass.HomeChooseModuleRsp proto = HomeChooseModuleRspOuterClass.HomeChooseModuleRsp.newBuilder() + .setRetcode(0) + .setModuleId(moduleId) + .build(); + + this.setData(proto); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeComfortInfoNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeComfortInfoNotify.java new file mode 100644 index 000000000..47e46dfdb --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeComfortInfoNotify.java @@ -0,0 +1,40 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.game.player.Player; +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.HomeComfortInfoNotifyOuterClass; +import emu.grasscutter.net.proto.HomeModuleComfortInfoOuterClass; + +import java.util.ArrayList; +import java.util.List; + +public class PacketHomeComfortInfoNotify extends BasePacket { + + public PacketHomeComfortInfoNotify(Player player) { + super(PacketOpcodes.HomeComfortInfoNotify); + + if (player.getRealmList() == null) { + // Do not send + return; + } + + List comfortInfoList = new ArrayList<>(); + + for (int moduleId : player.getRealmList()) { + comfortInfoList.add( + HomeModuleComfortInfoOuterClass.HomeModuleComfortInfo.newBuilder() + .setModuleId(moduleId) + .build() + ); + } + + HomeComfortInfoNotifyOuterClass.HomeComfortInfoNotify proto = HomeComfortInfoNotifyOuterClass.HomeComfortInfoNotify + .newBuilder() + .addAllModuleInfoList(comfortInfoList) + .build(); + + + this.setData(proto); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketPlayerHomeCompInfoNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketPlayerHomeCompInfoNotify.java new file mode 100644 index 000000000..29a6964b5 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketPlayerHomeCompInfoNotify.java @@ -0,0 +1,32 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.game.player.Player; +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.PlayerHomeCompInfoNotifyOuterClass; +import emu.grasscutter.net.proto.PlayerHomeCompInfoOuterClass; + +import java.util.List; + +public class PacketPlayerHomeCompInfoNotify extends BasePacket { + + public PacketPlayerHomeCompInfoNotify(Player player) { + super(PacketOpcodes.PlayerHomeCompInfoNotify); + + if (player.getRealmList() == null) { + // Do not send + return; + } + + PlayerHomeCompInfoNotifyOuterClass.PlayerHomeCompInfoNotify proto = PlayerHomeCompInfoNotifyOuterClass.PlayerHomeCompInfoNotify.newBuilder() + .setCompInfo( + PlayerHomeCompInfoOuterClass.PlayerHomeCompInfo.newBuilder() + .addAllUnlockedModuleIdList(player.getRealmList()) + .addAllLevelupRewardGotLevelList(List.of(1)) // Hardcoded + .build() + ) + .build(); + + this.setData(proto); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketTryEnterHomeRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketTryEnterHomeRsp.java new file mode 100644 index 000000000..369c44140 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketTryEnterHomeRsp.java @@ -0,0 +1,30 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.RetcodeOuterClass; +import emu.grasscutter.net.proto.TryEnterHomeRspOuterClass; + +public class PacketTryEnterHomeRsp extends BasePacket { + + public PacketTryEnterHomeRsp() { + super(PacketOpcodes.TryEnterHomeRsp); + + TryEnterHomeRspOuterClass.TryEnterHomeRsp proto = TryEnterHomeRspOuterClass.TryEnterHomeRsp.newBuilder() + .setRetcode(RetcodeOuterClass.Retcode.RET_SVR_ERROR_VALUE) + .build(); + + this.setData(proto); + } + + public PacketTryEnterHomeRsp(int uid) { + super(PacketOpcodes.TryEnterHomeRsp); + + TryEnterHomeRspOuterClass.TryEnterHomeRsp proto = TryEnterHomeRspOuterClass.TryEnterHomeRsp.newBuilder() + .setRetcode(0) + .setTargetUid(uid) + .build(); + + this.setData(proto); + } +}