From e16633e34b9a7c6281ee42411cb67266d8098f55 Mon Sep 17 00:00:00 2001 From: Akka <104902222+Akka0@users.noreply.github.com> Date: Tue, 14 Jun 2022 20:51:13 +0800 Subject: [PATCH] Implement the Home System (Serenitea Pot) --- build.gradle | 2 +- .../java/emu/grasscutter/data/GameData.java | 14 +-- .../emu/grasscutter/data/ResourceLoader.java | 64 +++++++++++-- .../data/binout/HomeworldDefaultSaveData.java | 52 +++++++++++ .../emu/grasscutter/data/excels/ItemData.java | 72 +++++++++++---- .../grasscutter/database/DatabaseHelper.java | 7 ++ .../grasscutter/database/DatabaseManager.java | 3 +- .../emu/grasscutter/game/home/GameHome.java | 70 ++++++++++++++ .../grasscutter/game/home/HomeBlockItem.java | 64 +++++++++++++ .../game/home/HomeFurnitureItem.java | 66 ++++++++++++++ .../grasscutter/game/home/HomeSceneItem.java | 91 +++++++++++++++++++ .../grasscutter/game/inventory/Inventory.java | 6 ++ .../emu/grasscutter/game/player/Player.java | 21 ++++- .../emu/grasscutter/game/world/Scene.java | 4 + .../emu/grasscutter/game/world/World.java | 2 + .../grasscutter/net/packet/PacketOpcodes.java | 3 + ...rGetFurnitureCurModuleArrangeCountReq.java | 17 ++++ .../recv/HandlerGetPlayerHomeCompInfoReq.java | 17 ++++ .../recv/HandlerHomeChangeEditModeReq.java | 24 +++++ .../HandlerHomeGetArrangementInfoReq.java | 20 ++++ .../recv/HandlerHomeGetBasicInfoReq.java | 18 ++++ .../recv/HandlerHomeSceneInitFinishReq.java | 17 ++++ .../packet/recv/HandlerHomeSceneJumpReq.java | 42 +++++++++ .../packet/recv/HandlerHomeUnknown2Req.java | 20 ++++ .../HandlerHomeUpdateArrangementInfoReq.java | 27 ++++++ .../packet/recv/HandlerTryEnterHomeReq.java | 9 +- ...tFurnitureCurModuleArrangeCountNotify.java | 57 ++++++++++++ .../send/PacketHomeBasicInfoNotify.java | 50 ++++++++++ .../send/PacketHomeChangeEditModeRsp.java | 18 ++++ .../send/PacketHomeComfortInfoNotify.java | 5 + .../send/PacketHomeGetArrangementInfoRsp.java | 31 +++++++ .../send/PacketHomeMarkPointNotify.java | 19 ++++ .../send/PacketHomeSceneInitFinishRsp.java | 17 ++++ .../packet/send/PacketHomeSceneJumpRsp.java | 18 ++++ .../packet/send/PacketHomeUnknown1Notify.java | 18 ++++ .../packet/send/PacketHomeUnknown2Rsp.java | 12 +++ .../PacketHomeUpdateArrangementInfoRsp.java | 12 +++ ...ketUnlockedFurnitureFormulaDataNotify.java | 27 ++++++ 38 files changed, 997 insertions(+), 39 deletions(-) create mode 100644 src/main/java/emu/grasscutter/data/binout/HomeworldDefaultSaveData.java create mode 100644 src/main/java/emu/grasscutter/game/home/GameHome.java create mode 100644 src/main/java/emu/grasscutter/game/home/HomeBlockItem.java create mode 100644 src/main/java/emu/grasscutter/game/home/HomeFurnitureItem.java create mode 100644 src/main/java/emu/grasscutter/game/home/HomeSceneItem.java create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerGetFurnitureCurModuleArrangeCountReq.java create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerGetPlayerHomeCompInfoReq.java create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeChangeEditModeReq.java create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeGetArrangementInfoReq.java create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeGetBasicInfoReq.java create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeSceneInitFinishReq.java create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeSceneJumpReq.java create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeUnknown2Req.java create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeUpdateArrangementInfoReq.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketFurnitureCurModuleArrangeCountNotify.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketHomeBasicInfoNotify.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketHomeChangeEditModeRsp.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketHomeGetArrangementInfoRsp.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketHomeMarkPointNotify.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketHomeSceneInitFinishRsp.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketHomeSceneJumpRsp.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketHomeUnknown1Notify.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketHomeUnknown2Rsp.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketHomeUpdateArrangementInfoRsp.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketUnlockedFurnitureFormulaDataNotify.java diff --git a/build.gradle b/build.gradle index 9db721c9..900671e0 100644 --- a/build.gradle +++ b/build.gradle @@ -76,7 +76,7 @@ dependencies { implementation group: 'org.reflections', name: 'reflections', version: '0.10.2' - implementation group: 'dev.morphia.morphia', name: 'morphia-core', version: '2.2.6' + implementation group: 'dev.morphia.morphia', name: 'morphia-core', version: '2.2.7' implementation group: 'org.greenrobot', name: 'eventbus-java', version: '3.3.1' implementation group: 'org.danilopianini', name: 'java-quadtree', version: '0.1.9' diff --git a/src/main/java/emu/grasscutter/data/GameData.java b/src/main/java/emu/grasscutter/data/GameData.java index fb3d10bf..054e8734 100644 --- a/src/main/java/emu/grasscutter/data/GameData.java +++ b/src/main/java/emu/grasscutter/data/GameData.java @@ -7,12 +7,8 @@ import java.util.List; import java.util.Map; import emu.grasscutter.Grasscutter; +import emu.grasscutter.data.binout.*; import emu.grasscutter.utils.Utils; -import emu.grasscutter.data.binout.AbilityEmbryoEntry; -import emu.grasscutter.data.binout.AbilityModifierEntry; -import emu.grasscutter.data.binout.MainQuestData; -import emu.grasscutter.data.binout.OpenConfigEntry; -import emu.grasscutter.data.binout.ScenePointEntry; import emu.grasscutter.data.excels.*; import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -28,7 +24,9 @@ public class GameData { private static final Map openConfigEntries = new HashMap<>(); private static final Map scenePointEntries = new HashMap<>(); private static final Int2ObjectMap mainQuestData = new Int2ObjectOpenHashMap<>(); - + + private static final Int2ObjectMap homeworldDefaultSaveData = new Int2ObjectOpenHashMap<>(); + // ExcelConfigs private static final Int2ObjectMap playerLevelDataMap = new Int2ObjectOpenHashMap<>(); @@ -140,7 +138,9 @@ public class GameData { public static Int2ObjectMap getMainQuestDataMap() { return mainQuestData; } - + public static Int2ObjectMap getHomeworldDefaultSaveData() { + return homeworldDefaultSaveData; + } public static Int2ObjectMap getAvatarDataMap() { return avatarDataMap; } diff --git a/src/main/java/emu/grasscutter/data/ResourceLoader.java b/src/main/java/emu/grasscutter/data/ResourceLoader.java index 785ef478..14211a2b 100644 --- a/src/main/java/emu/grasscutter/data/ResourceLoader.java +++ b/src/main/java/emu/grasscutter/data/ResourceLoader.java @@ -1,13 +1,17 @@ package emu.grasscutter.data; import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.*; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.google.gson.Gson; +import emu.grasscutter.data.binout.*; import emu.grasscutter.utils.Utils; +import lombok.SneakyThrows; import org.reflections.Reflections; import com.google.gson.JsonElement; @@ -15,12 +19,6 @@ import com.google.gson.annotations.SerializedName; import com.google.gson.reflect.TypeToken; import emu.grasscutter.Grasscutter; -import emu.grasscutter.data.binout.AbilityEmbryoEntry; -import emu.grasscutter.data.binout.AbilityModifier; -import emu.grasscutter.data.binout.AbilityModifierEntry; -import emu.grasscutter.data.binout.MainQuestData; -import emu.grasscutter.data.binout.OpenConfigEntry; -import emu.grasscutter.data.binout.ScenePointEntry; import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData; import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction; import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierActionType; @@ -66,6 +64,40 @@ public class ResourceLoader { loadQuests(); // Load scene points - must be done AFTER resources are loaded loadScenePoints(); + + // Load default home layout + loadHomeworldDefaultSaveData(); + // Custom - TODO move this somewhere else + try { + GameData.getAvatarSkillDepotDataMap().get(504).setAbilities( + new AbilityEmbryoEntry( + "", + new String[] { + "Avatar_PlayerBoy_ExtraAttack_Wind", + "Avatar_Player_UziExplode_Mix", + "Avatar_Player_UziExplode", + "Avatar_Player_UziExplode_Strike_01", + "Avatar_Player_UziExplode_Strike_02", + "Avatar_Player_WindBreathe", + "Avatar_Player_WindBreathe_CameraController" + } + )); + GameData.getAvatarSkillDepotDataMap().get(704).setAbilities( + new AbilityEmbryoEntry( + "", + new String[] { + "Avatar_PlayerGirl_ExtraAttack_Wind", + "Avatar_Player_UziExplode_Mix", + "Avatar_Player_UziExplode", + "Avatar_Player_UziExplode_Strike_01", + "Avatar_Player_UziExplode_Strike_02", + "Avatar_Player_WindBreathe", + "Avatar_Player_WindBreathe_CameraController" + } + )); + } catch (Exception e) { + Grasscutter.getLogger().error("Error loading abilities", e); + } } public static void loadResources() { @@ -394,6 +426,26 @@ public class ResourceLoader { Grasscutter.getLogger().info("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas."); } + @SneakyThrows + private static void loadHomeworldDefaultSaveData(){ + var folder = Files.list(Path.of(RESOURCE("BinOutput/HomeworldDefaultSave"))).toList(); + var pattern = Pattern.compile("scene(.*)_home_config.json"); + + for(var file : folder){ + var matcher = pattern.matcher(file.getFileName().toString()); + if(!matcher.find()){ + continue; + } + var sceneId = matcher.group(1); + + var data = Grasscutter.getGsonFactory().fromJson(Files.readString(file), HomeworldDefaultSaveData.class); + + GameData.getHomeworldDefaultSaveData().put(Integer.parseInt(sceneId), data); + } + + Grasscutter.getLogger().info("Loaded " + GameData.getHomeworldDefaultSaveData().size() + " HomeworldDefaultSaveDatas."); + } + // BinOutput configs public static class AvatarConfig { diff --git a/src/main/java/emu/grasscutter/data/binout/HomeworldDefaultSaveData.java b/src/main/java/emu/grasscutter/data/binout/HomeworldDefaultSaveData.java new file mode 100644 index 00000000..04506f01 --- /dev/null +++ b/src/main/java/emu/grasscutter/data/binout/HomeworldDefaultSaveData.java @@ -0,0 +1,52 @@ +package emu.grasscutter.data.binout; + +import com.google.gson.annotations.SerializedName; +import emu.grasscutter.utils.Position; +import lombok.AccessLevel; +import lombok.Data; +import lombok.experimental.FieldDefaults; + +import java.util.List; + +@Data +@FieldDefaults(level = AccessLevel.PRIVATE) +public class HomeworldDefaultSaveData { + + @SerializedName(value = "KFHBFNPDJBE", alternate = "PKACPHDGGEI") + List homeBlockLists; + @SerializedName(value = "IJNPADKGNKE", alternate = "MINCKHBNING") + Position bornPos; + @SerializedName("IPIIGEMFLHK") + Position bornRot; + @SerializedName("HHOLBNPIHEM") + Position djinPos; + @SerializedName("KNHCJKHCOAN") + HomeFurniture mainhouse; + + @SerializedName("NIHOJFEKFPG") + List doorLists; + @SerializedName("EPGELGEFJFK") + List stairLists; + @Data + @FieldDefaults(level = AccessLevel.PRIVATE) + public static class HomeBlock{ + + @SerializedName(value = "FGIJCELCGFI", alternate = "PGDPDIDJEEL") + int blockId; + + @SerializedName(value = "BEAPOFELABD", alternate = "MLIODLGDFHJ") + List furnitures; + } + + @Data + @FieldDefaults(level = AccessLevel.PRIVATE) + public static class HomeFurniture{ + + @SerializedName(value = "ENHNGKJBJAB", alternate = "KMAAJJHPNBA") + int id; + @SerializedName(value = "NGIEEIOLPPO", alternate = "JFKAHNCPDME") + Position pos; + //@SerializedName(value = "HEOCEHKEBFM", alternate = "LKCKOOGFDBM") + Position rot; + } +} diff --git a/src/main/java/emu/grasscutter/data/excels/ItemData.java b/src/main/java/emu/grasscutter/data/excels/ItemData.java index fba8d9ec..c7496a67 100644 --- a/src/main/java/emu/grasscutter/data/excels/ItemData.java +++ b/src/main/java/emu/grasscutter/data/excels/ItemData.java @@ -2,14 +2,20 @@ package emu.grasscutter.data.excels; import java.util.List; +import com.google.gson.annotations.SerializedName; import emu.grasscutter.data.GameResource; import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.common.ItemUseData; +import emu.grasscutter.game.inventory.*; import emu.grasscutter.game.props.FightProperty; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; -@ResourceType(name = {"MaterialExcelConfigData.json", "WeaponExcelConfigData.json", "ReliquaryExcelConfigData.json"}) +@ResourceType(name = {"MaterialExcelConfigData.json", + "WeaponExcelConfigData.json", + "ReliquaryExcelConfigData.json", + "HomeWorldFurnitureExcelConfigData.json" +}) public class ItemData extends GameResource { private int id; @@ -63,12 +69,19 @@ public class ItemData extends GameResource { private long nameTextMapHash; // Post load - private transient emu.grasscutter.game.inventory.MaterialType materialEnumType; - private transient emu.grasscutter.game.inventory.ItemType itemEnumType; - private transient emu.grasscutter.game.inventory.EquipType equipEnumType; + private transient MaterialType materialEnumType; + private transient ItemType itemEnumType; + private transient EquipType equipEnumType; private IntSet addPropLevelSet; - + + // Furniture + private int comfort; + private List furnType; + private List furnitureGadgetID; + @SerializedName("JFDLJGDFIGL") + private int roomSceneId; + @Override public int getId(){ return this.id; @@ -193,41 +206,57 @@ public class ItemData extends GameResource { public int getMaxLevel() { return maxLevel; } - - public emu.grasscutter.game.inventory.ItemType getItemType() { + + public int getComfort() { + return comfort; + } + + public List getFurnType() { + return furnType; + } + + public List getFurnitureGadgetID() { + return furnitureGadgetID; + } + + public int getRoomSceneId() { + return roomSceneId; + } + + public ItemType getItemType() { return this.itemEnumType; } - public emu.grasscutter.game.inventory.MaterialType getMaterialType() { + public MaterialType getMaterialType() { return this.materialEnumType; } - public emu.grasscutter.game.inventory.EquipType getEquipType() { + public EquipType getEquipType() { return this.equipEnumType; } public boolean canAddRelicProp(int level) { - return this.addPropLevelSet != null & this.addPropLevelSet.contains(level); + return this.addPropLevelSet != null && this.addPropLevelSet.contains(level); } public boolean isEquip() { - return this.itemEnumType == emu.grasscutter.game.inventory.ItemType.ITEM_RELIQUARY || this.itemEnumType == emu.grasscutter.game.inventory.ItemType.ITEM_WEAPON; + return this.itemEnumType == ItemType.ITEM_RELIQUARY || this.itemEnumType == ItemType.ITEM_WEAPON; } @Override public void onLoad() { - this.itemEnumType = emu.grasscutter.game.inventory.ItemType.getTypeByName(getItemTypeString()); - this.materialEnumType = emu.grasscutter.game.inventory.MaterialType.getTypeByName(getMaterialTypeString()); + this.itemEnumType = ItemType.getTypeByName(getItemTypeString()); + this.materialEnumType = MaterialType.getTypeByName(getMaterialTypeString()); - if (this.itemEnumType == emu.grasscutter.game.inventory.ItemType.ITEM_RELIQUARY) { - this.equipEnumType = emu.grasscutter.game.inventory.EquipType.getTypeByName(this.equipType); + if (this.itemEnumType == ItemType.ITEM_RELIQUARY) { + this.equipEnumType = EquipType.getTypeByName(this.equipType); if (this.addPropLevels != null && this.addPropLevels.length > 0) { this.addPropLevelSet = new IntOpenHashSet(this.addPropLevels); } - } else if (this.itemEnumType == emu.grasscutter.game.inventory.ItemType.ITEM_WEAPON) { - this.equipEnumType = emu.grasscutter.game.inventory.EquipType.EQUIP_WEAPON; + } else if (this.itemEnumType == ItemType.ITEM_WEAPON) { + this.equipEnumType = EquipType.EQUIP_WEAPON; } else { - this.equipEnumType = emu.grasscutter.game.inventory.EquipType.EQUIP_NONE; + this.equipEnumType = EquipType.EQUIP_NONE; } if (this.getWeaponProperties() != null) { @@ -235,6 +264,13 @@ public class ItemData extends GameResource { weaponProperty.onLoad(); } } + + if(this.getFurnType() != null){ + this.furnType = this.furnType.stream().filter(x -> x > 0).toList(); + } + if(this.getFurnitureGadgetID() != null){ + this.furnitureGadgetID = this.furnitureGadgetID.stream().filter(x -> x > 0).toList(); + } } public static class WeaponProperty { diff --git a/src/main/java/emu/grasscutter/database/DatabaseHelper.java b/src/main/java/emu/grasscutter/database/DatabaseHelper.java index aaf6b5d0..252b7a7f 100644 --- a/src/main/java/emu/grasscutter/database/DatabaseHelper.java +++ b/src/main/java/emu/grasscutter/database/DatabaseHelper.java @@ -13,6 +13,7 @@ import emu.grasscutter.game.Account; import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.friends.Friendship; import emu.grasscutter.game.gacha.GachaRecord; +import emu.grasscutter.game.home.GameHome; import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.mail.Mail; import emu.grasscutter.game.player.Player; @@ -295,4 +296,10 @@ public final class DatabaseHelper { public static boolean deleteQuest(GameMainQuest quest) { return DatabaseManager.getGameDatastore().delete(quest).wasAcknowledged(); } + public static GameHome getHomeByUid(int id) { + return DatabaseManager.getGameDatastore().find(GameHome.class).filter(Filters.eq("ownerUid", id)).first(); + } + public static void saveHome(GameHome gameHome) { + DatabaseManager.getGameDatastore().save(gameHome); + } } diff --git a/src/main/java/emu/grasscutter/database/DatabaseManager.java b/src/main/java/emu/grasscutter/database/DatabaseManager.java index 7c1360f7..b721e860 100644 --- a/src/main/java/emu/grasscutter/database/DatabaseManager.java +++ b/src/main/java/emu/grasscutter/database/DatabaseManager.java @@ -16,6 +16,7 @@ import emu.grasscutter.game.Account; import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.friends.Friendship; import emu.grasscutter.game.gacha.GachaRecord; +import emu.grasscutter.game.home.GameHome; import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.mail.Mail; import emu.grasscutter.game.player.Player; @@ -30,7 +31,7 @@ public final class DatabaseManager { private static final Class[] mappedClasses = new Class[] { DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class, - GachaRecord.class, Mail.class, GameMainQuest.class + GachaRecord.class, Mail.class, GameMainQuest.class, GameHome.class }; public static Datastore getGameDatastore() { diff --git a/src/main/java/emu/grasscutter/game/home/GameHome.java b/src/main/java/emu/grasscutter/game/home/GameHome.java new file mode 100644 index 00000000..b2b5c1ec --- /dev/null +++ b/src/main/java/emu/grasscutter/game/home/GameHome.java @@ -0,0 +1,70 @@ +package emu.grasscutter.game.home; + +import dev.morphia.annotations.Entity; +import dev.morphia.annotations.Id; +import dev.morphia.annotations.IndexOptions; +import dev.morphia.annotations.Indexed; +import emu.grasscutter.Grasscutter; +import emu.grasscutter.data.GameData; +import emu.grasscutter.database.DatabaseHelper; +import emu.grasscutter.game.player.Player; +import emu.grasscutter.server.packet.send.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Data; +import lombok.experimental.FieldDefaults; + +import java.util.concurrent.ConcurrentHashMap; + +@Entity(value = "homes", useDiscriminator = false) +@Data +@FieldDefaults(level = AccessLevel.PRIVATE) +@Builder(builderMethodName = "of") +public class GameHome { + + @Id + String id; + + @Indexed(options = @IndexOptions(unique = true)) + long ownerUid; + + ConcurrentHashMap sceneMap; + + public void save(){ + DatabaseHelper.saveHome(this); + } + + public static GameHome getByUid(Integer uid){ + var home = DatabaseHelper.getHomeByUid(uid); + if (home == null) { + home = GameHome.create(uid); + } + return home; + } + + public static GameHome create(Integer uid){ + return GameHome.of() + .ownerUid(uid) + .sceneMap(new ConcurrentHashMap<>()) + .build(); + } + + public HomeSceneItem getHomeSceneItem(int sceneId) { + return sceneMap.computeIfAbsent(sceneId, e -> { + var defaultItem = GameData.getHomeworldDefaultSaveData().get(sceneId); + if (defaultItem != null){ + Grasscutter.getLogger().info("Set player {} home {} to initial setting", ownerUid, sceneId); + return HomeSceneItem.parseFrom(defaultItem, sceneId); + } + return null; + }); + } + + public void onOwnerLogin(Player player) { + player.getSession().send(new PacketHomeBasicInfoNotify(player, false)); + player.getSession().send(new PacketPlayerHomeCompInfoNotify(player)); + player.getSession().send(new PacketHomeComfortInfoNotify(player)); + player.getSession().send(new PacketFurnitureCurModuleArrangeCountNotify()); + player.getSession().send(new PacketUnlockedFurnitureFormulaDataNotify()); + } +} diff --git a/src/main/java/emu/grasscutter/game/home/HomeBlockItem.java b/src/main/java/emu/grasscutter/game/home/HomeBlockItem.java new file mode 100644 index 00000000..e936d026 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/home/HomeBlockItem.java @@ -0,0 +1,64 @@ +package emu.grasscutter.game.home; + +import dev.morphia.annotations.Entity; +import dev.morphia.annotations.Id; +import emu.grasscutter.data.binout.HomeworldDefaultSaveData; +import emu.grasscutter.net.proto.HomeBlockArrangementInfoOuterClass.HomeBlockArrangementInfo; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Data; +import lombok.experimental.FieldDefaults; + +import java.util.List; + +@Entity +@Data +@Builder(builderMethodName = "of") +@FieldDefaults(level = AccessLevel.PRIVATE) +public class HomeBlockItem { + + @Id + int blockId; + boolean unlocked; + + List deployFurnitureList; + + + public void update(HomeBlockArrangementInfo homeBlockArrangementInfo) { + this.blockId = homeBlockArrangementInfo.getBlockId(); + + this.deployFurnitureList = homeBlockArrangementInfo.getDeployFurniureListList().stream() + .map(HomeFurnitureItem::parseFrom) + .toList(); + } + + public int calComfort(){ + return this.deployFurnitureList.stream() + .mapToInt(HomeFurnitureItem::getComfort) + .sum(); + } + + public HomeBlockArrangementInfo toProto() { + var proto = HomeBlockArrangementInfo.newBuilder() + .setBlockId(blockId) + .setIsUnlocked(unlocked) + .setComfortValue(calComfort()); + + this.deployFurnitureList.forEach(f -> proto.addDeployFurniureList(f.toProto())); + + return proto.build(); + } + + public static HomeBlockItem parseFrom(HomeworldDefaultSaveData.HomeBlock homeBlock) { + + return HomeBlockItem.of() + .blockId(homeBlock.getBlockId()) + .unlocked(homeBlock.getFurnitures() != null) + .deployFurnitureList( + homeBlock.getFurnitures() == null ? List.of() : + homeBlock.getFurnitures().stream() + .map(HomeFurnitureItem::parseFrom) + .toList()) + .build(); + } +} diff --git a/src/main/java/emu/grasscutter/game/home/HomeFurnitureItem.java b/src/main/java/emu/grasscutter/game/home/HomeFurnitureItem.java new file mode 100644 index 00000000..0cf4fed2 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/home/HomeFurnitureItem.java @@ -0,0 +1,66 @@ +package emu.grasscutter.game.home; + +import dev.morphia.annotations.Entity; +import emu.grasscutter.data.GameData; +import emu.grasscutter.data.binout.HomeworldDefaultSaveData; +import emu.grasscutter.data.excels.ItemData; +import emu.grasscutter.net.proto.HomeFurnitureDataOuterClass; +import emu.grasscutter.utils.Position; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Data; +import lombok.experimental.FieldDefaults; + +@Entity +@Data +@FieldDefaults(level = AccessLevel.PRIVATE) +@Builder(builderMethodName = "of") +public class HomeFurnitureItem { + int furnitureId; + int guid; + int parentFurnitureIndex; + Position spawnPos; + Position spawnRot; + + public HomeFurnitureDataOuterClass.HomeFurnitureData toProto(){ + return HomeFurnitureDataOuterClass.HomeFurnitureData.newBuilder() + .setFurnitureId(furnitureId) + .setGuid(guid) + .setParentFurnitureIndex(parentFurnitureIndex) + .setSpawnPos(spawnPos.toProto()) + .setSpawnRot(spawnRot.toProto()) + .build(); + } + + public static HomeFurnitureItem parseFrom(HomeFurnitureDataOuterClass.HomeFurnitureData homeFurnitureData) { + return HomeFurnitureItem.of() + .furnitureId(homeFurnitureData.getFurnitureId()) + .guid(homeFurnitureData.getGuid()) + .parentFurnitureIndex(homeFurnitureData.getParentFurnitureIndex()) + .spawnPos(new Position(homeFurnitureData.getSpawnPos())) + .spawnRot(new Position(homeFurnitureData.getSpawnRot())) + .build(); + } + + public static HomeFurnitureItem parseFrom(HomeworldDefaultSaveData.HomeFurniture homeFurniture) { + return HomeFurnitureItem.of() + .furnitureId(homeFurniture.getId()) + .parentFurnitureIndex(1) + .spawnPos(homeFurniture.getPos() == null ? new Position() : homeFurniture.getPos()) + .spawnRot(homeFurniture.getRot() == null ? new Position() : homeFurniture.getRot()) + .build(); + } + + public ItemData getAsItem() { + return GameData.getItemDataMap().get(this.furnitureId); + } + + public int getComfort() { + var item = getAsItem(); + + if (item == null){ + return 0; + } + return item.getComfort(); + } +} diff --git a/src/main/java/emu/grasscutter/game/home/HomeSceneItem.java b/src/main/java/emu/grasscutter/game/home/HomeSceneItem.java new file mode 100644 index 00000000..5ec4ced1 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/home/HomeSceneItem.java @@ -0,0 +1,91 @@ +package emu.grasscutter.game.home; + +import dev.morphia.annotations.Entity; +import dev.morphia.annotations.Id; +import emu.grasscutter.data.binout.HomeworldDefaultSaveData; +import emu.grasscutter.net.proto.HomeBasicInfoOuterClass.HomeBasicInfo; +import emu.grasscutter.net.proto.HomeSceneArrangementInfoOuterClass.HomeSceneArrangementInfo; +import emu.grasscutter.utils.Position; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Data; +import lombok.experimental.FieldDefaults; + +import java.util.Map; +import java.util.stream.Collectors; + +@Entity +@Data +@Builder(builderMethodName = "of") +@FieldDefaults(level = AccessLevel.PRIVATE) +public class HomeSceneItem { + @Id + int sceneId; + Map blockItems; + Position bornPos; + Position bornRot; + Position djinnPos; + HomeFurnitureItem mainHouse; + + public static HomeSceneItem parseFrom(HomeworldDefaultSaveData defaultItem, int sceneId) { + return HomeSceneItem.of() + .sceneId(sceneId) + .blockItems(defaultItem.getHomeBlockLists().stream() + .map(HomeBlockItem::parseFrom) + .collect(Collectors.toMap(HomeBlockItem::getBlockId, y -> y))) + .bornPos(defaultItem.getBornPos()) + .bornRot(defaultItem.getBornRot() == null ? new Position() : defaultItem.getBornRot()) + .djinnPos(defaultItem.getDjinPos() == null ? new Position() : defaultItem.getDjinPos()) + .mainHouse(defaultItem.getMainhouse() == null ? null : + HomeFurnitureItem.parseFrom(defaultItem.getMainhouse())) + .build(); + } + + public void update(HomeSceneArrangementInfo arrangementInfo){ + for(var blockItem : arrangementInfo.getBlockArrangementInfoListList()){ + var block = this.blockItems.get(blockItem.getBlockId()); + if(block == null){ + System.out.println(111); + continue; + } + block.update(blockItem); + this.blockItems.put(blockItem.getBlockId(), block); + } + + this.bornPos = new Position(arrangementInfo.getBornPos()); + this.bornRot = new Position(arrangementInfo.getBornRot()); + this.djinnPos = new Position(arrangementInfo.getDjinnPos()); + this.mainHouse = HomeFurnitureItem.parseFrom(arrangementInfo.getMainHouse()); + } + + public int getRoomSceneId(){ + if(mainHouse == null || mainHouse.getAsItem() == null){ + return 0; + } + return mainHouse.getAsItem().getRoomSceneId(); + } + + public int calComfort(){ + return this.blockItems.values().stream() + .mapToInt(HomeBlockItem::calComfort) + .sum(); + } + + public HomeSceneArrangementInfo toProto(){ + var proto = HomeSceneArrangementInfo.newBuilder(); + blockItems.values().forEach(b -> proto.addBlockArrangementInfoList(b.toProto())); + + proto.setComfortValue(calComfort()) + .setBornPos(bornPos.toProto()) + .setBornRot(bornRot.toProto()) + .setDjinnPos(djinnPos.toProto()) + .setSceneId(sceneId) + .setTmpVersion(1); + + if(mainHouse != null){ + proto.setMainHouse(mainHouse.toProto()); + } + return proto.build(); + } + +} diff --git a/src/main/java/emu/grasscutter/game/inventory/Inventory.java b/src/main/java/emu/grasscutter/game/inventory/Inventory.java index f870ba11..b22217bd 100644 --- a/src/main/java/emu/grasscutter/game/inventory/Inventory.java +++ b/src/main/java/emu/grasscutter/game/inventory/Inventory.java @@ -267,6 +267,8 @@ public class Inventory implements Iterable { getPlayer().setMora(player.getMora() + count); case 203 -> // Genesis Crystals getPlayer().setCrystals(player.getCrystals() + count); + case 204 -> // Home Coin + getPlayer().setHomeCoin(player.getHomeCoin() + count); } } @@ -280,6 +282,8 @@ public class Inventory implements Iterable { return player.getCrystals(); case 106: // Resin return player.getProperty(PlayerProperty.PROP_PLAYER_RESIN); + case 204: // Home Coin + return player.getHomeCoin(); default: GameItem item = getInventoryTab(ItemType.ITEM_MATERIAL).getItemById(itemId); // What if we ever want to operate on weapons/relics/furniture? :S return (item == null) ? 0 : item.getCount(); @@ -320,6 +324,8 @@ public class Inventory implements Iterable { player.setCrystals(player.getCrystals() - (cost.getCount() * quantity)); case 106 -> // Resin player.getResinManager().useResin(cost.getCount() * quantity); + case 204 -> // Home Coin + player.setHomeCoin(player.getHomeCoin() - (cost.getCount() * quantity)); default -> removeItem(getInventoryTab(ItemType.ITEM_MATERIAL).getItemById(cost.getId()), cost.getCount() * quantity); } diff --git a/src/main/java/emu/grasscutter/game/player/Player.java b/src/main/java/emu/grasscutter/game/player/Player.java index 28d2f4d5..e3299971 100644 --- a/src/main/java/emu/grasscutter/game/player/Player.java +++ b/src/main/java/emu/grasscutter/game/player/Player.java @@ -14,6 +14,8 @@ import emu.grasscutter.game.avatar.AvatarProfileData; import emu.grasscutter.game.avatar.AvatarStorage; import emu.grasscutter.game.entity.EntityMonster; import emu.grasscutter.game.entity.EntityVehicle; +import emu.grasscutter.game.home.GameHome; +import emu.grasscutter.game.managers.DeforestationManager.DeforestationManager; import emu.grasscutter.game.entity.EntityGadget; import emu.grasscutter.game.entity.EntityItem; import emu.grasscutter.game.entity.GameEntity; @@ -164,6 +166,7 @@ public class Player { @Transient private ResinManager resinManager; @Transient private ForgingManager forgingManager; @Transient private DeforestationManager deforestationManager; + @Transient private GameHome home; private long springLastUsed; private HashMap mapMarks; @@ -376,7 +379,9 @@ public class Player { public void setCurrentRealmId(Integer currentRealmId) { this.currentRealmId = currentRealmId; } - + public GameHome getHome(){ + return home; + } public Position getPos() { return pos; } @@ -429,6 +434,14 @@ public class Player { this.sendPacket(new PacketPlayerPropNotify(this, PlayerProperty.PROP_PLAYER_MCOIN)); } + public int getHomeCoin() { + return this.getProperty(PlayerProperty.PROP_PLAYER_HOME_COIN); + } + + public void setHomeCoin(int coin) { + this.setProperty(PlayerProperty.PROP_PLAYER_HOME_COIN, coin); + this.sendPacket(new PacketPlayerPropNotify(this, PlayerProperty.PROP_PLAYER_HOME_COIN)); + } private int getExpRequired(int level) { PlayerLevelData levelData = GameData.getPlayerLevelDataMap().get(level); return levelData != null ? levelData.getExp() : 0; @@ -1316,14 +1329,16 @@ public class Player { session.send(new PacketCodexDataFullNotify(this)); session.send(new PacketAllWidgetDataNotify(this)); session.send(new PacketWidgetGadgetAllDataNotify()); - session.send(new PacketPlayerHomeCompInfoNotify(this)); - session.send(new PacketHomeComfortInfoNotify(this)); session.send(new PacketCombineDataNotify(this.unlockedCombines)); this.forgingManager.sendForgeDataNotify(); this.resinManager.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. + // Home + home = GameHome.getByUid(getUid()); + home.onOwnerLogin(this); + session.send(new PacketPlayerEnterSceneNotify(this)); // Enter game world session.send(new PacketPlayerLevelRewardUpdateNotify(rewardedLevels)); session.send(new PacketOpenStateUpdateNotify()); diff --git a/src/main/java/emu/grasscutter/game/world/Scene.java b/src/main/java/emu/grasscutter/game/world/Scene.java index cb724d77..4ca41002 100644 --- a/src/main/java/emu/grasscutter/game/world/Scene.java +++ b/src/main/java/emu/grasscutter/game/world/Scene.java @@ -414,6 +414,10 @@ public class Scene { } public void onTick() { + // disable script for home + if (this.getSceneType() == SceneType.SCENE_HOME_WORLD || this.getSceneType() == SceneType.SCENE_HOME_ROOM){ + return; + } if (this.getScriptManager().isInit()) { this.checkBlocks(); } else { diff --git a/src/main/java/emu/grasscutter/game/world/World.java b/src/main/java/emu/grasscutter/game/world/World.java index ac6ab4a7..46352319 100644 --- a/src/main/java/emu/grasscutter/game/world/World.java +++ b/src/main/java/emu/grasscutter/game/world/World.java @@ -270,7 +270,9 @@ public class World implements Iterable { enterType = EnterType.ENTER_TYPE_GOTO; } else if (newScene.getSceneType() == SceneType.SCENE_HOME_WORLD) { // Home + enterReason = EnterReason.EnterHome; enterType = EnterType.ENTER_TYPE_SELF_HOME; + } // Teleport packet diff --git a/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java b/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java index ec737b22..af37f7a0 100644 --- a/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java +++ b/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java @@ -777,6 +777,9 @@ public class PacketOpcodes { public static final int HomeSceneJumpRsp = 4570; public static final int HomeTransferReq = 4880; public static final int HomeTransferRsp = 4767; + public static final int HomeUnknown1Notify = 4528; + public static final int HomeUnknown2Req = 4857; + public static final int HomeUnknown2Rsp = 4670; public static final int HomeUpdateArrangementInfoReq = 4472; public static final int HomeUpdateArrangementInfoRsp = 4822; public static final int HomeUpdateFishFarmingInfoReq = 4604; diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetFurnitureCurModuleArrangeCountReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetFurnitureCurModuleArrangeCountReq.java new file mode 100644 index 00000000..9fa71a02 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetFurnitureCurModuleArrangeCountReq.java @@ -0,0 +1,17 @@ +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.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketFurnitureCurModuleArrangeCountNotify; + +@Opcodes(PacketOpcodes.GetFurnitureCurModuleArrangeCountReq) +public class HandlerGetFurnitureCurModuleArrangeCountReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + session.send(new PacketFurnitureCurModuleArrangeCountNotify()); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetPlayerHomeCompInfoReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetPlayerHomeCompInfoReq.java new file mode 100644 index 00000000..165665a7 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetPlayerHomeCompInfoReq.java @@ -0,0 +1,17 @@ +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.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketPlayerHomeCompInfoNotify; + +@Opcodes(PacketOpcodes.GetPlayerHomeCompInfoReq) +public class HandlerGetPlayerHomeCompInfoReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + session.send(new PacketPlayerHomeCompInfoNotify(session.getPlayer())); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeChangeEditModeReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeChangeEditModeReq.java new file mode 100644 index 00000000..4c0cf14f --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeChangeEditModeReq.java @@ -0,0 +1,24 @@ +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.HomeChangeEditModeReqOuterClass; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.*; + +@Opcodes(PacketOpcodes.HomeChangeEditModeReq) +public class HandlerHomeChangeEditModeReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + var req = HomeChangeEditModeReqOuterClass.HomeChangeEditModeReq.parseFrom(payload); + + session.send(new PacketHomeUnknown1Notify(req.getIsEnterEditMode())); + session.send(new PacketHomeBasicInfoNotify(session.getPlayer(), req.getIsEnterEditMode())); + session.send(new PacketHomeComfortInfoNotify(session.getPlayer())); + + session.send(new PacketHomeChangeEditModeRsp(req.getIsEnterEditMode())); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeGetArrangementInfoReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeGetArrangementInfoReq.java new file mode 100644 index 00000000..f92d3a22 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeGetArrangementInfoReq.java @@ -0,0 +1,20 @@ +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.HomeGetArrangementInfoReqOuterClass; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketHomeGetArrangementInfoRsp; + +@Opcodes(PacketOpcodes.HomeGetArrangementInfoReq) +public class HandlerHomeGetArrangementInfoReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + var req = HomeGetArrangementInfoReqOuterClass.HomeGetArrangementInfoReq.parseFrom(payload); + + session.send(new PacketHomeGetArrangementInfoRsp(session.getPlayer(), req.getSceneIdListList())); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeGetBasicInfoReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeGetBasicInfoReq.java new file mode 100644 index 00000000..9ccfee2b --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeGetBasicInfoReq.java @@ -0,0 +1,18 @@ +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.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketHomeBasicInfoNotify; + +@Opcodes(PacketOpcodes.HomeGetBasicInfoReq) +public class HandlerHomeGetBasicInfoReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + + session.send(new PacketHomeBasicInfoNotify(session.getPlayer(), false)); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeSceneInitFinishReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeSceneInitFinishReq.java new file mode 100644 index 00000000..b59cd227 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeSceneInitFinishReq.java @@ -0,0 +1,17 @@ +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.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketHomeSceneInitFinishRsp; + +@Opcodes(PacketOpcodes.HomeSceneInitFinishReq) +public class HandlerHomeSceneInitFinishReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + session.send(new PacketHomeSceneInitFinishRsp()); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeSceneJumpReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeSceneJumpReq.java new file mode 100644 index 00000000..6d816810 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeSceneJumpReq.java @@ -0,0 +1,42 @@ +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.HomeSceneJumpReqOuterClass; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketHomeSceneJumpRsp; + +@Opcodes(PacketOpcodes.HomeSceneJumpReq) +public class HandlerHomeSceneJumpReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + var req = HomeSceneJumpReqOuterClass.HomeSceneJumpReq.parseFrom(payload); + + int realmId = 2000 + session.getPlayer().getCurrentRealmId(); + + var home = session.getPlayer().getHome(); + var homeScene = home.getHomeSceneItem(realmId); + home.save(); + + if(req.getIsEnterRoomScene()){ + var roomScene = home.getHomeSceneItem(homeScene.getRoomSceneId()); + + session.getPlayer().getWorld().transferPlayerToScene( + session.getPlayer(), + homeScene.getRoomSceneId(), + roomScene.getBornPos() + ); + }else{ + session.getPlayer().getWorld().transferPlayerToScene( + session.getPlayer(), + realmId, + homeScene.getBornPos() + ); + } + + session.send(new PacketHomeSceneJumpRsp(req.getIsEnterRoomScene())); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeUnknown2Req.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeUnknown2Req.java new file mode 100644 index 00000000..8e05c08b --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeUnknown2Req.java @@ -0,0 +1,20 @@ +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.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketHomeUnknown2Rsp; + +@Opcodes(PacketOpcodes.HomeUnknown2Req) +public class HandlerHomeUnknown2Req extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + /* + * This packet is about the edit mode + */ + session.send(new PacketHomeUnknown2Rsp()); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeUpdateArrangementInfoReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeUpdateArrangementInfoReq.java new file mode 100644 index 00000000..60aea018 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerHomeUpdateArrangementInfoReq.java @@ -0,0 +1,27 @@ +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.HomeUpdateArrangementInfoReqOuterClass; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketHomeUpdateArrangementInfoRsp; + +@Opcodes(PacketOpcodes.HomeUpdateArrangementInfoReq) +public class HandlerHomeUpdateArrangementInfoReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + var req = HomeUpdateArrangementInfoReqOuterClass.HomeUpdateArrangementInfoReq.parseFrom(payload); + + var homeScene = session.getPlayer().getHome() + .getHomeSceneItem(session.getPlayer().getSceneId()); + + homeScene.update(req.getSceneArrangementInfo()); + + session.getPlayer().getHome().save(); + + session.send(new PacketHomeUpdateArrangementInfoRsp()); + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerTryEnterHomeReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerTryEnterHomeReq.java index 5df106df..2de3ffe1 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerTryEnterHomeReq.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerTryEnterHomeReq.java @@ -1,6 +1,8 @@ package emu.grasscutter.server.packet.recv; import emu.grasscutter.data.GameData; +import emu.grasscutter.database.DatabaseHelper; +import emu.grasscutter.game.home.GameHome; import emu.grasscutter.game.world.Scene; import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.PacketHandler; @@ -27,13 +29,14 @@ public class HandlerTryEnterHomeReq extends PacketHandler { int realmId = 2000 + session.getPlayer().getCurrentRealmId(); - Scene scene = session.getPlayer().getWorld().getSceneById(realmId); - Position pos = scene.getScriptManager().getConfig().born_pos; + var home = session.getPlayer().getHome(); + var homeScene = home.getHomeSceneItem(realmId); + home.save(); session.getPlayer().getWorld().transferPlayerToScene( session.getPlayer(), realmId, - pos + homeScene.getBornPos() ); diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketFurnitureCurModuleArrangeCountNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketFurnitureCurModuleArrangeCountNotify.java new file mode 100644 index 00000000..9dfe4ac0 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketFurnitureCurModuleArrangeCountNotify.java @@ -0,0 +1,57 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.FurnitureCurModuleArrangeCountNotifyOuterClass; +import emu.grasscutter.net.proto.Uint32PairOuterClass; + +public class PacketFurnitureCurModuleArrangeCountNotify extends BasePacket { + + public PacketFurnitureCurModuleArrangeCountNotify() { + super(PacketOpcodes.FurnitureCurModuleArrangeCountNotify); + + var proto = FurnitureCurModuleArrangeCountNotifyOuterClass.FurnitureCurModuleArrangeCountNotify.newBuilder(); + + proto.addFurnitureArrangeCountList(Uint32PairOuterClass.Uint32Pair.newBuilder() + .setKey(360101) + .setValue(7) + .build()); + + proto.addFurnitureArrangeCountList(Uint32PairOuterClass.Uint32Pair.newBuilder() + .setKey(360201) + .setValue(7) + .build()); + + proto.addFurnitureArrangeCountList(Uint32PairOuterClass.Uint32Pair.newBuilder() + .setKey(360301) + .setValue(7) + .build()); + + proto.addFurnitureArrangeCountList(Uint32PairOuterClass.Uint32Pair.newBuilder() + .setKey(360401) + .setValue(2) + .build()); + + proto.addFurnitureArrangeCountList(Uint32PairOuterClass.Uint32Pair.newBuilder() + .setKey(360402) + .setValue(4) + .build()); + + proto.addFurnitureArrangeCountList(Uint32PairOuterClass.Uint32Pair.newBuilder() + .setKey(364301) + .setValue(1) + .build()); + + proto.addFurnitureArrangeCountList(Uint32PairOuterClass.Uint32Pair.newBuilder() + .setKey(364401) + .setValue(1) + .build()); + + proto.addFurnitureArrangeCountList(Uint32PairOuterClass.Uint32Pair.newBuilder() + .setKey(3750102) + .setValue(1) + .build()); + + this.setData(proto); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeBasicInfoNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeBasicInfoNotify.java new file mode 100644 index 00000000..f67fed13 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeBasicInfoNotify.java @@ -0,0 +1,50 @@ +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.HomeBasicInfoNotifyOuterClass; +import emu.grasscutter.net.proto.HomeBasicInfoOuterClass; +import emu.grasscutter.net.proto.HomeLimitedShopInfoOuterClass; +import emu.grasscutter.net.proto.VectorOuterClass; + +public class PacketHomeBasicInfoNotify extends BasePacket { + + public PacketHomeBasicInfoNotify(Player player, boolean editMode) { + super(PacketOpcodes.HomeBasicInfoNotify); + + if(player.getCurrentRealmId() == null){ + return; + } + + var proto = HomeBasicInfoNotifyOuterClass.HomeBasicInfoNotify.newBuilder(); + + var sceneId = player.getCurrentRealmId() + 2000; + var homeScene = player.getHome().getHomeSceneItem(sceneId); + + proto.setBasicInfo(HomeBasicInfoOuterClass.HomeBasicInfo.newBuilder() + .setCurModuleId(player.getCurrentRealmId()) + .setCurRoomSceneId(homeScene.getRoomSceneId()) + .setIsInEditMode(editMode) + .setHomeOwnerUid(player.getUid()) + .setLevel(1) + .setOwnerNickName(player.getNickname()) + .setLimitedShopInfo(HomeLimitedShopInfoOuterClass.HomeLimitedShopInfo.newBuilder() + .setDjinnPos(VectorOuterClass.Vector.newBuilder() + .setZ(192) + .setX(792) + .setY(316.7f) + .build()) + .setDjinnRot(VectorOuterClass.Vector.newBuilder() + .setY(176) + .build()) + .setNextCloseTime(Integer.MAX_VALUE) + .setNextGuestOpenTime(0) + .setNextOpenTime(0) + .setUid(player.getUid()) + .build()) + .build()); + + this.setData(proto); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeChangeEditModeRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeChangeEditModeRsp.java new file mode 100644 index 00000000..09326aa3 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeChangeEditModeRsp.java @@ -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.HomeChangeEditModeRspOuterClass; + +public class PacketHomeChangeEditModeRsp extends BasePacket { + + public PacketHomeChangeEditModeRsp(boolean enterEditMode) { + super(PacketOpcodes.HomeChangeEditModeRsp); + + var proto = HomeChangeEditModeRspOuterClass.HomeChangeEditModeRsp.newBuilder(); + + proto.setIsEnterEditMode(enterEditMode); + + 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 index 47e46dfd..374fa415 100644 --- a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeComfortInfoNotify.java +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeComfortInfoNotify.java @@ -25,6 +25,11 @@ public class PacketHomeComfortInfoNotify extends BasePacket { comfortInfoList.add( HomeModuleComfortInfoOuterClass.HomeModuleComfortInfo.newBuilder() .setModuleId(moduleId) + .setRoomSceneComfortValue(1050) + .addWorldSceneBlockComfortValueList(750) + .addWorldSceneBlockComfortValueList(0) + .addWorldSceneBlockComfortValueList(0) + .addWorldSceneBlockComfortValueList(0) .build() ); } diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeGetArrangementInfoRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeGetArrangementInfoRsp.java new file mode 100644 index 00000000..b6c8b1d1 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeGetArrangementInfoRsp.java @@ -0,0 +1,31 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.game.home.HomeSceneItem; +import emu.grasscutter.game.player.Player; +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.HomeGetArrangementInfoRspOuterClass; + +import java.util.List; + +public class PacketHomeGetArrangementInfoRsp extends BasePacket { + + public PacketHomeGetArrangementInfoRsp(Player player, List sceneIdList) { + super(PacketOpcodes.HomeGetArrangementInfoRsp); + + var home = player.getHome(); + + var homeScenes = sceneIdList.stream() + .map(home::getHomeSceneItem) + .map(HomeSceneItem::toProto) + .toList(); + + home.save(); + + var proto = HomeGetArrangementInfoRspOuterClass.HomeGetArrangementInfoRsp.newBuilder(); + + proto.addAllSceneArrangementInfoList(homeScenes); + + this.setData(proto); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeMarkPointNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeMarkPointNotify.java new file mode 100644 index 00000000..8b74ecad --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeMarkPointNotify.java @@ -0,0 +1,19 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.game.home.GameHome; +import emu.grasscutter.game.player.Player; +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.HomeMarkPointNotifyOuterClass; + +public class PacketHomeMarkPointNotify extends BasePacket { + + public PacketHomeMarkPointNotify(Player player, GameHome home) { + super(PacketOpcodes.HomeMarkPointNotify); + + var proto = HomeMarkPointNotifyOuterClass.HomeMarkPointNotify.newBuilder(); + + + this.setData(proto); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeSceneInitFinishRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeSceneInitFinishRsp.java new file mode 100644 index 00000000..4acf4572 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeSceneInitFinishRsp.java @@ -0,0 +1,17 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.HomeSceneArrangementInfoOuterClass; + +public class PacketHomeSceneInitFinishRsp extends BasePacket { + + public PacketHomeSceneInitFinishRsp() { + super(PacketOpcodes.HomeSceneInitFinishRsp); + + var proto = HomeSceneArrangementInfoOuterClass.HomeSceneArrangementInfo.newBuilder(); + + this.setData(proto); + + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeSceneJumpRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeSceneJumpRsp.java new file mode 100644 index 00000000..01fc95f5 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeSceneJumpRsp.java @@ -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.HomeSceneJumpRspOuterClass; + +public class PacketHomeSceneJumpRsp extends BasePacket { + + public PacketHomeSceneJumpRsp(boolean enterRoomScene) { + super(PacketOpcodes.HomeSceneJumpRsp); + + var proto = HomeSceneJumpRspOuterClass.HomeSceneJumpRsp.newBuilder(); + + proto.setIsEnterRoomScene(enterRoomScene); + + this.setData(proto); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeUnknown1Notify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeUnknown1Notify.java new file mode 100644 index 00000000..ec22dce2 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeUnknown1Notify.java @@ -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.HomeUnknown1NotifyOuterClass; + +public class PacketHomeUnknown1Notify extends BasePacket { + + public PacketHomeUnknown1Notify(boolean isEnterEditMode) { + super(PacketOpcodes.HomeUnknown1Notify); + + var proto = HomeUnknown1NotifyOuterClass.HomeUnknown1Notify.newBuilder(); + + proto.setIsEnterEditMode(isEnterEditMode); + + this.setData(proto); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeUnknown2Rsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeUnknown2Rsp.java new file mode 100644 index 00000000..8766531e --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeUnknown2Rsp.java @@ -0,0 +1,12 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; + +public class PacketHomeUnknown2Rsp extends BasePacket { + + public PacketHomeUnknown2Rsp() { + super(PacketOpcodes.HomeUnknown2Rsp); + + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketHomeUpdateArrangementInfoRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeUpdateArrangementInfoRsp.java new file mode 100644 index 00000000..fac99451 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketHomeUpdateArrangementInfoRsp.java @@ -0,0 +1,12 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; + +public class PacketHomeUpdateArrangementInfoRsp extends BasePacket { + + public PacketHomeUpdateArrangementInfoRsp() { + super(PacketOpcodes.HomeUpdateArrangementInfoRsp); + + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketUnlockedFurnitureFormulaDataNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketUnlockedFurnitureFormulaDataNotify.java new file mode 100644 index 00000000..6c71be1e --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketUnlockedFurnitureFormulaDataNotify.java @@ -0,0 +1,27 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.UnlockedFurnitureFormulaDataNotifyOuterClass; + +public class PacketUnlockedFurnitureFormulaDataNotify extends BasePacket { + + public PacketUnlockedFurnitureFormulaDataNotify() { + super(PacketOpcodes.UnlockedFurnitureFormulaDataNotify); + + var proto = UnlockedFurnitureFormulaDataNotifyOuterClass.UnlockedFurnitureFormulaDataNotify.newBuilder(); + + proto.addFurnitureIdList(361207); + proto.addFurnitureIdList(362202); + proto.addFurnitureIdList(362304); + proto.addFurnitureIdList(363102); + proto.addFurnitureIdList(363103); + proto.addFurnitureIdList(363203); + proto.addFurnitureIdList(370201); + proto.addFurnitureIdList(370302); + + proto.setIsAll(true); + + this.setData(proto); + } +} -- GitLab