diff --git a/proto/ForgeGetQueueDataRsp.proto b/proto/ForgeGetQueueDataRsp.proto new file mode 100644 index 000000000..9539fc4a4 --- /dev/null +++ b/proto/ForgeGetQueueDataRsp.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +option java_package = "emu.grasscutter.net.proto"; + +import "ForgeQueueData.proto"; + +// CmdId: 628 +// EnetChannelId: 0 +// EnetIsReliable: true +message ForgeGetQueueDataRsp { + int32 retcode = 15; + uint32 max_queue_num = 13; + map forge_queue_map = 11; +} diff --git a/src/main/java/emu/grasscutter/game/managers/ForgingManager/ForgingManager.java b/src/main/java/emu/grasscutter/game/managers/ForgingManager/ForgingManager.java new file mode 100644 index 000000000..238e5acd0 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/managers/ForgingManager/ForgingManager.java @@ -0,0 +1,65 @@ +package emu.grasscutter.game.managers.ForgingManager; + +import emu.grasscutter.game.inventory.GameItem; +import emu.grasscutter.game.player.Player; +import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode; +import emu.grasscutter.server.packet.send.PacketForgeDataNotify; +import emu.grasscutter.server.packet.send.PacketForgeFormulaDataNotify; +import emu.grasscutter.server.packet.send.PacketForgeGetQueueDataRsp; + +public class ForgingManager { + private final Player player; + + public ForgingManager(Player player) { + this.player = player; + } + + /********** + Blueprint unlocking. + **********/ + public boolean unlockForgingBlueprint(GameItem blueprintItem) { + // Make sure this is actually a forging blueprint. + if (!blueprintItem.getItemData().getItemUse().get(0).getUseOp().equals("ITEM_USE_UNLOCK_FORGE")) { + return false; + } + + // Determine the forging item we should unlock. + int forgeId = Integer.parseInt(blueprintItem.getItemData().getItemUse().get(0).getUseParam().get(0)); + + // Tell the client that this blueprint is now unlocked and add the unlocked item to the player. + this.player.sendPacket(new PacketForgeFormulaDataNotify(forgeId)); + this.player.getUnlockedForgingBlueprints().add(forgeId); + + // Done. + return true; + } + + /********** + Communicate forging information to the client. + **********/ + private int determineNumberOfQueues() { + int adventureRank = player.getLevel(); + return + (adventureRank >= 15) ? 4 + : (adventureRank >= 10) ? 3 + : (adventureRank >= 5) ? 2 + : 1; + } + + public void sendForgeDataNotify() { + // Determine the number of queues and unlocked items. + int numQueues = this.determineNumberOfQueues(); + var unlockedItems = this.player.getUnlockedForgingBlueprints(); + + // Send notification. + this.player.sendPacket(new PacketForgeDataNotify(unlockedItems, numQueues)); + } + + public void handleForgeGetQueueDataReq() { + // Determine the number of queues. + int numQueues = this.determineNumberOfQueues(); + + // Reply. + this.player.sendPacket(new PacketForgeGetQueueDataRsp(Retcode.RET_SUCC, numQueues)); + } +} diff --git a/src/main/java/emu/grasscutter/game/managers/InventoryManager.java b/src/main/java/emu/grasscutter/game/managers/InventoryManager.java index 3d50873bf..d5811a316 100644 --- a/src/main/java/emu/grasscutter/game/managers/InventoryManager.java +++ b/src/main/java/emu/grasscutter/game/managers/InventoryManager.java @@ -852,15 +852,13 @@ public class InventoryManager { // Handle forging blueprints. if (useItem.getItemData().getItemUse().get(0).getUseOp().equals("ITEM_USE_UNLOCK_FORGE")) { - // Determine the forging item we should unlock. - int forgeId = Integer.parseInt(useItem.getItemData().getItemUse().get(0).getUseParam().get(0)); + // Unlock. + boolean success = player.getForgingManager().unlockForgingBlueprint(useItem); - // Tell the client that this blueprint is now unlocked and add the unlocked item to the player. - player.sendPacket(new PacketForgeFormulaDataNotify(forgeId)); - player.getUnlockedForgingBlueprints().add(forgeId); - - // Use up the blueprint item. - used = 1; + // Use up the blueprint item if successful. + if (success) { + used = 1; + } } break; case MATERIAL_CHEST: diff --git a/src/main/java/emu/grasscutter/game/player/Player.java b/src/main/java/emu/grasscutter/game/player/Player.java index ac22900dd..5a07cee6c 100644 --- a/src/main/java/emu/grasscutter/game/player/Player.java +++ b/src/main/java/emu/grasscutter/game/player/Player.java @@ -30,6 +30,7 @@ import emu.grasscutter.game.managers.InsectCaptureManager; import emu.grasscutter.game.managers.StaminaManager.StaminaManager; import emu.grasscutter.game.managers.SotSManager; import emu.grasscutter.game.managers.EnergyManager.EnergyManager; +import emu.grasscutter.game.managers.ForgingManager.ForgingManager; import emu.grasscutter.game.props.ActionReason; import emu.grasscutter.game.props.EntityType; import emu.grasscutter.game.props.PlayerProperty; @@ -153,6 +154,7 @@ public class Player { @Transient private MapMarksManager mapMarksManager; @Transient private StaminaManager staminaManager; @Transient private EnergyManager energyManager; + @Transient private ForgingManager forgingManager; @Transient private DeforestationManager deforestationManager; private long springLastUsed; @@ -209,6 +211,7 @@ public class Player { this.staminaManager = new StaminaManager(this); this.sotsManager = new SotSManager(this); this.energyManager = new EnergyManager(this); + this.forgingManager = new ForgingManager(this); } // On player creation @@ -240,6 +243,7 @@ public class Player { this.sotsManager = new SotSManager(this); this.energyManager = new EnergyManager(this); this.deforestationManager = new DeforestationManager(this); + this.forgingManager = new ForgingManager(this); } public int getUid() { @@ -1120,6 +1124,10 @@ public class Player { return this.energyManager; } + public ForgingManager getForgingManager() { + return this.forgingManager; + } + public AbilityManager getAbilityManager() { return abilityManager; } @@ -1265,7 +1273,7 @@ public class Player { session.send(new PacketWidgetGadgetAllDataNotify()); session.send(new PacketPlayerHomeCompInfoNotify(this)); session.send(new PacketHomeComfortInfoNotify(this)); - session.send(new PacketForgeDataNotify(this)); + this.forgingManager.sendForgeDataNotify(); 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/HandlerForgeGetQueueDataReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerForgeGetQueueDataReq.java new file mode 100644 index 000000000..a7ca38d2d --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerForgeGetQueueDataReq.java @@ -0,0 +1,14 @@ +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.net.packet.Opcodes; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.packet.PacketHandler; +import emu.grasscutter.server.game.GameSession; + +@Opcodes(PacketOpcodes.ForgeGetQueueDataReq) +public class HandlerForgeGetQueueDataReq extends PacketHandler { + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + session.getPlayer().getForgingManager().handleForgeGetQueueDataReq(); + } +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketForgeDataNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketForgeDataNotify.java index 48ea79ba4..bf17ab823 100644 --- a/src/main/java/emu/grasscutter/server/packet/send/PacketForgeDataNotify.java +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketForgeDataNotify.java @@ -7,18 +7,18 @@ import emu.grasscutter.net.proto.ForgeDataNotifyOuterClass.ForgeDataNotify; public class PacketForgeDataNotify extends BasePacket { - public PacketForgeDataNotify(Player player) { + public PacketForgeDataNotify(Iterable unlockedItem, int numQueues) { super(PacketOpcodes.ForgeDataNotify); - int adventureRank = player.getLevel(); + /*int adventureRank = player.getLevel(); int numQueues = (adventureRank >= 15) ? 4 : (adventureRank >= 10) ? 3 : (adventureRank >= 5) ? 2 - : 1; + : 1;*/ ForgeDataNotify proto = ForgeDataNotify.newBuilder() - .addAllForgeIdList(player.getUnlockedForgingBlueprints()) + .addAllForgeIdList(unlockedItem) .setMaxQueueNum(numQueues) .build(); diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketForgeGetQueueDataRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketForgeGetQueueDataRsp.java new file mode 100644 index 000000000..dcf080335 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketForgeGetQueueDataRsp.java @@ -0,0 +1,23 @@ +package emu.grasscutter.server.packet.send; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.ForgeGetQueueDataRspOuterClass.ForgeGetQueueDataRsp; +import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode; + +public class PacketForgeGetQueueDataRsp extends BasePacket { + + public PacketForgeGetQueueDataRsp(Retcode retcode, int numQueues) { + super(PacketOpcodes.ForgeGetQueueDataRsp); + + ForgeGetQueueDataRsp proto = ForgeGetQueueDataRsp.newBuilder() + .setRetcode(retcode.getNumber()) + .setMaxQueueNum(numQueues) + .build(); + + // ToDo: Add the information for the actual forging queues + // and ongoing forges. + + this.setData(proto); + } +}