From f243c10157802a26ab9b305f4848a2a8d79d6004 Mon Sep 17 00:00:00 2001
From: ImmuState <kyoko12@gmx.at>
Date: Thu, 2 Jun 2022 14:51:01 -0700
Subject: [PATCH] Unlock forging blueprints.

---
 .../grasscutter/data/common/ItemUseData.java  | 24 ++++++++++++++
 .../emu/grasscutter/data/excels/ItemData.java | 11 ++++++-
 .../game/managers/InventoryManager.java       | 21 +++++++++++++
 .../emu/grasscutter/game/player/Player.java   |  1 +
 .../packet/send/PacketForgeDataNotify.java    | 31 +++++++++++++++++++
 .../send/PacketForgeFormulaDataNotify.java    | 19 ++++++++++++
 6 files changed, 106 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/emu/grasscutter/data/common/ItemUseData.java
 create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketForgeDataNotify.java
 create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketForgeFormulaDataNotify.java

diff --git a/src/main/java/emu/grasscutter/data/common/ItemUseData.java b/src/main/java/emu/grasscutter/data/common/ItemUseData.java
new file mode 100644
index 00000000..7f905c20
--- /dev/null
+++ b/src/main/java/emu/grasscutter/data/common/ItemUseData.java
@@ -0,0 +1,24 @@
+package emu.grasscutter.data.common;
+
+import java.util.List;
+
+public class ItemUseData {
+	private String useOp;
+	private List<String> useParam;
+
+	public String getUseOp() {
+		return useOp;
+	}
+
+	public void setUseOp(String useOp) {
+		this.useOp = useOp;
+	}
+
+	public List<String> getUseParam() {
+		return useParam;
+	}
+	
+	public void setUseParam(List<String> useParam) {
+		this.useParam = useParam;
+	}
+}
diff --git a/src/main/java/emu/grasscutter/data/excels/ItemData.java b/src/main/java/emu/grasscutter/data/excels/ItemData.java
index adeec435..fba8d9ec 100644
--- a/src/main/java/emu/grasscutter/data/excels/ItemData.java
+++ b/src/main/java/emu/grasscutter/data/excels/ItemData.java
@@ -1,7 +1,10 @@
 package emu.grasscutter.data.excels;
 
+import java.util.List;
+
 import emu.grasscutter.data.GameResource;
 import emu.grasscutter.data.ResourceType;
+import emu.grasscutter.data.common.ItemUseData;
 import emu.grasscutter.game.props.FightProperty;
 import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
 import it.unimi.dsi.fastutil.ints.IntSet;
@@ -21,6 +24,8 @@ public class ItemData extends GameResource {
     
     private int[] destroyReturnMaterial;
     private int[] destroyReturnMaterialCount;
+
+    private List<ItemUseData> itemUse;
     
     // Food
     private String foodQuality;
@@ -112,7 +117,11 @@ public class ItemData extends GameResource {
     public int[] getDestroyReturnMaterialCount(){
         return this.destroyReturnMaterialCount;
     }
-    
+
+    public List<ItemUseData> getItemUse() {
+        return itemUse;
+    }
+
     public long getNameTextMapHash(){
         return this.nameTextMapHash;
     }
diff --git a/src/main/java/emu/grasscutter/game/managers/InventoryManager.java b/src/main/java/emu/grasscutter/game/managers/InventoryManager.java
index f32299ee..054d350d 100644
--- a/src/main/java/emu/grasscutter/game/managers/InventoryManager.java
+++ b/src/main/java/emu/grasscutter/game/managers/InventoryManager.java
@@ -6,6 +6,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import emu.grasscutter.Grasscutter;
 import emu.grasscutter.data.GameData;
 import emu.grasscutter.data.binout.OpenConfigEntry;
 import emu.grasscutter.data.binout.OpenConfigEntry.SkillPointModifier;
@@ -28,6 +29,7 @@ import emu.grasscutter.game.shop.ShopChestBatchUseTable;
 import emu.grasscutter.game.shop.ShopChestTable;
 import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
 import emu.grasscutter.net.proto.MaterialInfoOuterClass.MaterialInfo;
+import emu.grasscutter.server.packet.send.PacketForgeFormulaDataNotify;
 import emu.grasscutter.server.game.GameServer;
 import emu.grasscutter.server.packet.send.*;
 import emu.grasscutter.utils.Utils;
@@ -822,6 +824,7 @@ public class InventoryManager {
 		int used = 0;
 		
 		// Use
+		Grasscutter.getLogger().info("Item: {}", useItem.getItemData().getId());
 		switch (useItem.getItemData().getMaterialType()) {
 			case MATERIAL_FOOD:
 				if (useItem.getItemData().getUseTarget().equals("ITEM_USE_TARGET_SPECIFY_DEAD_AVATAR")) {
@@ -842,6 +845,24 @@ public class InventoryManager {
 					used = player.getTeamManager().healAvatar(target, SatiationParams[0], SatiationParams[1]) ? 1 : 0;
 				}
 				break;
+			case MATERIAL_CONSUME:
+				// Make sure we have usage data for this material.
+				if (useItem.getItemData().getItemUse() == null) {
+					break;
+				}
+
+				// 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));
+
+					// Tell the client that this blueprint is now unlocked.
+					player.sendPacket(new PacketForgeFormulaDataNotify(forgeId));
+
+					// Use up the blueprint item.
+					used = 1;
+				}
+				break;
 			case MATERIAL_CHEST:
 				List<ShopChestTable> shopChestTableList = player.getServer().getShopManager().getShopChestData();
 				List<GameItem> rewardItemList = new ArrayList<>();
diff --git a/src/main/java/emu/grasscutter/game/player/Player.java b/src/main/java/emu/grasscutter/game/player/Player.java
index d2d86546..b5ab55e3 100644
--- a/src/main/java/emu/grasscutter/game/player/Player.java
+++ b/src/main/java/emu/grasscutter/game/player/Player.java
@@ -1264,6 +1264,7 @@ public class Player {
 		session.send(new PacketWidgetGadgetAllDataNotify());
 		session.send(new PacketPlayerHomeCompInfoNotify(this));
 		session.send(new PacketHomeComfortInfoNotify(this));
+		session.send(new PacketForgeDataNotify(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/send/PacketForgeDataNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketForgeDataNotify.java
new file mode 100644
index 00000000..3f22e62a
--- /dev/null
+++ b/src/main/java/emu/grasscutter/server/packet/send/PacketForgeDataNotify.java
@@ -0,0 +1,31 @@
+package emu.grasscutter.server.packet.send;
+
+import java.util.List;
+
+import dev.morphia.AdvancedDatastore;
+import emu.grasscutter.game.player.Player;
+import emu.grasscutter.net.packet.BasePacket;
+import emu.grasscutter.net.packet.PacketOpcodes;
+import emu.grasscutter.net.proto.ForgeDataNotifyOuterClass.ForgeDataNotify;
+import emu.grasscutter.net.proto.ForgeQueueDataOuterClass.ForgeQueueData;
+
+public class PacketForgeDataNotify extends BasePacket {
+	
+	public PacketForgeDataNotify(Player player) {
+		super(PacketOpcodes.ForgeDataNotify);
+		
+		int adventureRank = player.getLevel();
+		int numQueues = 
+			(adventureRank >= 15) ? 4 
+			: (adventureRank >= 10) ? 3 
+			: (adventureRank >= 5) ? 2 
+			: 1;
+
+		ForgeDataNotify proto = ForgeDataNotify.newBuilder()
+			.addAllForgeIdList(List.of(14017, 14009, 14008))
+			.setMaxQueueNum(numQueues)
+			.build();
+
+		this.setData(proto);
+	}
+}
diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketForgeFormulaDataNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketForgeFormulaDataNotify.java
new file mode 100644
index 00000000..46f18028
--- /dev/null
+++ b/src/main/java/emu/grasscutter/server/packet/send/PacketForgeFormulaDataNotify.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.ForgeFormulaDataNotifyOuterClass.ForgeFormulaDataNotify;
+
+public class PacketForgeFormulaDataNotify extends BasePacket {
+	
+	public PacketForgeFormulaDataNotify(int itemId) {
+		super(PacketOpcodes.ForgeFormulaDataNotify);
+
+		ForgeFormulaDataNotify proto = ForgeFormulaDataNotify.newBuilder()
+				.setForgeId(itemId)
+				.setIsLocked(false)
+				.build();
+		
+		this.setData(proto);
+	}
+}
-- 
GitLab