From cb4171f1fde7d1387f9b7fe640aec78de3d3dd6b Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Sun, 14 Feb 2016 12:09:18 -0500 Subject: [PATCH] Bunch of bugfixes and final tweaking to get inventory working. --- FFXIVClassic Map Server/Database.cs | 38 ++--- FFXIVClassic Map Server/Server.cs | 132 +++++++++++++++++- .../actors/chara/player/Inventory.cs | 57 ++++++-- .../actors/chara/player/Player.cs | 6 + FFXIVClassic Map Server/dataobjects/Item.cs | 2 +- .../Actor/inventory/InventoryListX16Packet.cs | 2 +- .../Actor/inventory/InventoryListX32Packet.cs | 2 +- .../Actor/inventory/InventoryListX64Packet.cs | 2 +- .../inventory/InventoryRemoveX08Packet.cs | 4 +- .../inventory/InventoryRemoveX16Packet.cs | 4 +- .../inventory/InventoryRemoveX32Packet.cs | 4 +- .../inventory/InventoryRemoveX64Packet.cs | 4 +- 12 files changed, 215 insertions(+), 42 deletions(-) diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs index aecf28b7..fa00e80a 100644 --- a/FFXIVClassic Map Server/Database.cs +++ b/FFXIVClassic Map Server/Database.cs @@ -556,24 +556,27 @@ namespace FFXIVClassic_Lobby_Server (@itemId, @quality, @isUntradeable, @durability); "; + MySqlCommand cmd = new MySqlCommand(query, conn); + string query2 = @" INSERT INTO characters_inventory (characterId, slot, inventoryType, serverItemId, quantity) - SELECT @charId, IFNULL(MAX(SLOT)+1, 0), @inventoryType, LAST_INSERT_ID(), @quantity FROM characters_inventory WHERE characterId = @charId; + SELECT @charId, IFNULL(MAX(SLOT)+1, 0), @inventoryType, LAST_INSERT_ID(), @quantity FROM characters_inventory WHERE characterId = @charId AND inventoryType = @inventoryType; "; - query += query2; - - MySqlCommand cmd = new MySqlCommand(query, conn); - cmd.Parameters.AddWithValue("@charId", player.actorId); - cmd.Parameters.AddWithValue("@inventoryType", type); - + MySqlCommand cmd2 = new MySqlCommand(query2, conn); + cmd.Parameters.AddWithValue("@itemId", itemId); - cmd.Parameters.AddWithValue("@quantity", quantity); cmd.Parameters.AddWithValue("@quality", quality); cmd.Parameters.AddWithValue("@isUntradeable", isUntradeable); cmd.Parameters.AddWithValue("@durability", durability); + + cmd2.Parameters.AddWithValue("@charId", player.actorId); + cmd2.Parameters.AddWithValue("@inventoryType", type); + cmd2.Parameters.AddWithValue("@quantity", quantity); + cmd.ExecuteNonQuery(); + cmd2.ExecuteNonQuery(); insertedItem = new Item((uint)cmd.LastInsertedId, itemId, quantity, (ushort)player.inventories[type].getNextEmptySlot(), isUntradeable, quality, durability, 0, 0, 0, 0, 0, 0); } @@ -588,7 +591,7 @@ namespace FFXIVClassic_Lobby_Server return insertedItem; } - public static void setQuantity(Player player, uint slot, int quantity) + public static void setQuantity(Player player, uint slot, ushort type, int quantity) { using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) { @@ -599,13 +602,14 @@ namespace FFXIVClassic_Lobby_Server string query = @" UPDATE characters_inventory SET quantity = @quantity - WHERE characterId = @charId AND slot = @slot + WHERE characterId = @charId AND slot = @slot AND inventoryType = @type; "; MySqlCommand cmd = new MySqlCommand(query, conn); cmd.Parameters.AddWithValue("@charId", player.actorId); cmd.Parameters.AddWithValue("@quantity", quantity); cmd.Parameters.AddWithValue("@slot", slot); + cmd.Parameters.AddWithValue("@type", type); cmd.ExecuteNonQuery(); } @@ -619,7 +623,7 @@ namespace FFXIVClassic_Lobby_Server } - public static void removeItem(Player player, ulong serverItemId) + public static void removeItem(Player player, ulong serverItemId, ushort type) { using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}; Allow User Variables=True", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) { @@ -631,10 +635,10 @@ namespace FFXIVClassic_Lobby_Server SELECT slot INTO @slotToDelete FROM characters_inventory WHERE serverItemId = @serverItemId; UPDATE characters_inventory SET slot = slot - 1 - WHERE characterId = @charId AND slot > @slotToDelete; + WHERE characterId = @charId AND slot > @slotToDelete AND inventoryType = @type; DELETE FROM characters_inventory - WHERE serverItemId = @serverItemId; + WHERE serverItemId = @serverItemId AND inventoryType = @type; DELETE FROM server_items WHERE id = @serverItemId; @@ -643,6 +647,7 @@ namespace FFXIVClassic_Lobby_Server MySqlCommand cmd = new MySqlCommand(query, conn); cmd.Parameters.AddWithValue("@charId", player.actorId); cmd.Parameters.AddWithValue("@serverItemId", serverItemId); + cmd.Parameters.AddWithValue("@type", type); cmd.ExecuteNonQuery(); } @@ -656,7 +661,7 @@ namespace FFXIVClassic_Lobby_Server } - public static void removeItem(Player player, ushort slot) + public static void removeItem(Player player, ushort slot, ushort type) { using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}; Allow User Variables=True", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) { @@ -668,19 +673,20 @@ namespace FFXIVClassic_Lobby_Server SELECT serverItemId INTO @serverItemId FROM characters_inventory WHERE characterId = @charId AND slot = @slot; DELETE FROM characters_inventory - WHERE characterId = @charId AND slot = @slot; + WHERE characterId = @charId AND slot = @slot AND inventoryType = @type; DELETE FROM server_items WHERE id = @serverItemId; UPDATE characters_inventory SET slot = slot - 1 - WHERE characterId = @charId AND slot > @slot; + WHERE characterId = @charId AND slot > @slot AND inventoryType = @type; "; MySqlCommand cmd = new MySqlCommand(query, conn); cmd.Parameters.AddWithValue("@charId", player.actorId); cmd.Parameters.AddWithValue("@slot", slot); + cmd.Parameters.AddWithValue("@type", type); cmd.ExecuteNonQuery(); } diff --git a/FFXIVClassic Map Server/Server.cs b/FFXIVClassic Map Server/Server.cs index 8c36d0d1..34d0e9c9 100644 --- a/FFXIVClassic Map Server/Server.cs +++ b/FFXIVClassic Map Server/Server.cs @@ -412,14 +412,14 @@ namespace FFXIVClassic_Lobby_Server if (client != null) { Player p = client.getActor(); - p.inventories[Inventory.NORMAL].addItem(itemId, 0, quantity, 1); + p.inventories[Inventory.NORMAL].addItem(itemId, quantity, 1); } else { foreach (KeyValuePair entry in mConnectedPlayerList) { Player p = entry.Value.getActor(); - p.inventories[Inventory.NORMAL].addItem(itemId, 0, quantity, 1); + p.inventories[Inventory.NORMAL].addItem(itemId, quantity, 1); } } } @@ -441,6 +441,74 @@ namespace FFXIVClassic_Lobby_Server } } + private void giveCurrancy(ConnectedPlayer client, uint itemId, int quantity) + { + if (client != null) + { + Player p = client.getActor(); + p.inventories[Inventory.CURRANCY].addItem(itemId, quantity, 1); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + p.inventories[Inventory.CURRANCY].addItem(itemId, quantity, 1); + } + } + } + + private void removeCurrancy(ConnectedPlayer client, uint itemId, int quantity) + { + if (client != null) + { + Player p = client.getActor(); + p.inventories[Inventory.CURRANCY].removeItem(itemId, quantity); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + p.inventories[Inventory.CURRANCY].removeItem(itemId, quantity); + } + } + } + + private void giveKeyItem(ConnectedPlayer client, uint itemId) + { + if (client != null) + { + Player p = client.getActor(); + p.inventories[Inventory.KEYITEMS].addItem(itemId, 1, 1); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + p.inventories[Inventory.KEYITEMS].addItem(itemId, 1, 1); + } + } + } + + private void removeKeyItem(ConnectedPlayer client, uint itemId) + { + if (client != null) + { + Player p = client.getActor(); + p.inventories[Inventory.KEYITEMS].removeItem(itemId, 1); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + p.inventories[Inventory.KEYITEMS].removeItem(itemId, 1); + } + } + } + internal void doCommand(string input, ConnectedPlayer client) { input.Trim(); @@ -514,7 +582,65 @@ namespace FFXIVClassic_Lobby_Server } catch (Exception e) { - Log.error("Could not give item."); + Log.error("Could not remove item."); + } + } + else if (split[0].Equals("givekeyitem")) + { + try + { + if (split.Length == 2) + giveKeyItem(client, UInt32.Parse(split[1])); + } + catch (Exception e) + { + Log.error("Could not give keyitem."); + } + } + else if (split[0].Equals("removekeyitem")) + { + if (split.Length < 2) + return; + + try + { + if (split.Length == 2) + removeKeyItem(client, UInt32.Parse(split[1])); + } + catch (Exception e) + { + Log.error("Could not remove keyitem."); + } + } + else if (split[0].Equals("givecurrancy")) + { + try + { + if (split.Length == 2) + giveCurrancy(client, UInt32.Parse(split[1]), 1); + else if (split.Length == 3) + giveCurrancy(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); + } + catch (Exception e) + { + Log.error("Could not give currancy."); + } + } + else if (split[0].Equals("removecurrancy")) + { + if (split.Length < 2) + return; + + try + { + if (split.Length == 2) + removeCurrancy(client, UInt32.Parse(split[1]), 1); + else if (split.Length == 3) + removeCurrancy(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); + } + catch (Exception e) + { + Log.error("Could not remove currancy."); } } else if (split[0].Equals("music")) diff --git a/FFXIVClassic Map Server/actors/chara/player/Inventory.cs b/FFXIVClassic Map Server/actors/chara/player/Inventory.cs index 00879636..3dd42141 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Inventory.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Inventory.cs @@ -40,7 +40,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player list = itemsFromDB; } - public void addItem(uint itemId, ushort type, int quantity, byte quality) + public void addItem(uint itemId, int quantity, byte quality) { if (!isSpaceForAdd(itemId, quantity)) return; @@ -79,20 +79,27 @@ namespace FFXIVClassic_Map_Server.actors.chara.player //These had their quantities changed foreach (ushort slot in slotsToUpdate) { - Database.setQuantity(owner, slot, list[slot].quantity); - sendInventoryPackets(list[slot]); + Database.setQuantity(owner, slot, inventoryCode, list[slot].quantity); + + if (inventoryCode != CURRANCY && inventoryCode != KEYITEMS) + sendInventoryPackets(list[slot]); } //New item that spilled over while (quantityCount > 0) { - Item addedItem = Database.addItem(owner, itemId, Math.Min(quantityCount, 5), quality, false, 100, type); + Item addedItem = Database.addItem(owner, itemId, Math.Min(quantityCount, 5), quality, false, 100, inventoryCode); list.Add(addedItem); - sendInventoryPackets(addedItem); + + if (inventoryCode != CURRANCY && inventoryCode != KEYITEMS) + sendInventoryPackets(addedItem); quantityCount -= addedItem.maxStack; } - + + if (inventoryCode == CURRANCY || inventoryCode == KEYITEMS) + sendFullInventory(); + owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId)); owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId)); } @@ -115,10 +122,12 @@ namespace FFXIVClassic_Map_Server.actors.chara.player Item item = list[i]; if (item.itemId == itemId) { + int oldQuantity = item.quantity; //Stack nomnomed if (item.quantity - quantityCount <= 0) { itemsToRemove.Add(item); + slotsToRemove.Add(item.slot); } else { @@ -126,7 +135,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player item.quantity -= quantityCount; //Stack reduced } - quantityCount -= item.quantity; + quantityCount -= oldQuantity; lowestSlot = item.slot; if (quantityCount <= 0) @@ -136,15 +145,27 @@ namespace FFXIVClassic_Map_Server.actors.chara.player for (int i = 0; i < slotsToUpdate.Count; i++) { - Database.setQuantity(owner, slotsToUpdate[i], list[slotsToUpdate[i]].quantity); + Database.setQuantity(owner, slotsToUpdate[i], inventoryCode, list[slotsToUpdate[i]].quantity); } + int oldListSize = list.Count; for (int i = 0; i < itemsToRemove.Count; i++) { - Database.removeItem(owner, itemsToRemove[i].uniqueId); + Database.removeItem(owner, itemsToRemove[i].uniqueId, inventoryCode); list.Remove(itemsToRemove[i]); } + //Realign slots + for (int i = lowestSlot; i < list.Count; i++) + list[i].slot = (ushort)i; + + //Added tail end items that need to be cleared for slot realignment + for (int i = oldListSize-1; i >= oldListSize - itemsToRemove.Count; i--) + { + if (!slotsToRemove.Contains((ushort)i)) + slotsToRemove.Add((ushort)i); + } + owner.queuePacket(InventoryBeginChangePacket.buildPacket(owner.actorId)); owner.queuePacket(InventorySetBeginPacket.buildPacket(owner.actorId, inventoryCapacity, inventoryCode)); @@ -172,14 +193,21 @@ namespace FFXIVClassic_Map_Server.actors.chara.player if (toDelete == null) return; + int oldListSize = list.Count; list.RemoveAt(slot); - Database.removeItem(owner, itemDBId); + Database.removeItem(owner, itemDBId, inventoryCode); + //Realign slots + for (int i = slot; i < list.Count; i++) + list[i].slot = (ushort)i; + owner.queuePacket(InventoryBeginChangePacket.buildPacket(owner.actorId)); owner.queuePacket(InventorySetBeginPacket.buildPacket(owner.actorId, inventoryCapacity, inventoryCode)); sendInventoryPackets(slot); sendInventoryRemovePackets(slot); + if (slot != oldListSize - 1) + sendInventoryRemovePackets((ushort)(oldListSize - 1)); owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId)); owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId)); @@ -191,14 +219,21 @@ namespace FFXIVClassic_Map_Server.actors.chara.player if (slot >= list.Count) return; + int oldListSize = list.Count; list.RemoveAt((int)slot); - Database.removeItem(owner, slot); + Database.removeItem(owner, slot, inventoryCode); + + //Realign slots + for (int i = slot; i < list.Count; i++) + list[i].slot = (ushort)i; owner.queuePacket(InventoryBeginChangePacket.buildPacket(owner.actorId)); owner.queuePacket(InventorySetBeginPacket.buildPacket(owner.actorId, inventoryCapacity, inventoryCode)); sendInventoryPackets(slot); sendInventoryRemovePackets(slot); + if (slot != oldListSize - 1) + sendInventoryRemovePackets((ushort)(oldListSize - 1)); owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId)); owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId)); diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 5828ec44..5f3f8308 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -432,6 +432,7 @@ namespace FFXIVClassic_Map_Server.Actors queuePacket(InventoryBeginChangePacket.buildPacket(actorId)); inventories[Inventory.NORMAL].sendFullInventory(); inventories[Inventory.CURRANCY].sendFullInventory(); + inventories[Inventory.KEYITEMS].sendFullInventory(); #region equipsetup // EquipmentListX08Packet initialEqupmentPacket = new EquipmentListX08Packet(); // initialEqupmentPacket.setItem(EquipmentListX08Packet.SLOT_BODY, 5); @@ -634,6 +635,11 @@ namespace FFXIVClassic_Map_Server.Actors //zone.broadcastPacketAroundActor(this, worldMasterMessage); } + public Inventory getInventory(ushort type) + { + return inventories[type]; + } + public void runEventFunction(string functionName, params object[] parameters) { List lParams = LuaUtils.createLuaParamList(parameters); diff --git a/FFXIVClassic Map Server/dataobjects/Item.cs b/FFXIVClassic Map Server/dataobjects/Item.cs index 08e878e8..20f39b98 100644 --- a/FFXIVClassic Map Server/dataobjects/Item.cs +++ b/FFXIVClassic Map Server/dataobjects/Item.cs @@ -14,7 +14,7 @@ namespace FFXIVClassic_Map_Server.dataobjects public int quantity = 1; public ushort slot; - public int maxStack = 5; + public int maxStack = 99999; public bool isUntradeable = false; public byte quality = 1; diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX16Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX16Packet.cs index e6bf12d0..f0c118fa 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX16Packet.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX16Packet.cs @@ -30,7 +30,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.inventory for (int i = 0; i < max; i++) { - binWriter.Write(items[i].toPacketBytes()); + binWriter.Write(items[listOffset].toPacketBytes()); listOffset++; } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX32Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX32Packet.cs index 5f376b97..a830610a 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX32Packet.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX32Packet.cs @@ -30,7 +30,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.inventory for (int i = 0; i < max; i++) { - binWriter.Write(items[i].toPacketBytes()); + binWriter.Write(items[listOffset].toPacketBytes()); listOffset++; } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX64Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX64Packet.cs index ba705072..8e4827e1 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX64Packet.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryListX64Packet.cs @@ -30,7 +30,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.inventory for (int i = 0; i < max; i++) { - binWriter.Write(items[i].toPacketBytes()); + binWriter.Write(items[listOffset].toPacketBytes()); listOffset++; } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX08Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX08Packet.cs index 79f805c5..26c4f27c 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX08Packet.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX08Packet.cs @@ -27,9 +27,9 @@ namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory else max = 8; - for (int i = listOffset; i < max; i++) + for (int i = 0; i < max; i++) { - binWriter.Write((UInt16)slots[i]); + binWriter.Write((UInt16)slots[listOffset]); listOffset++; } diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX16Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX16Packet.cs index 30ed3d08..7d7ad104 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX16Packet.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX16Packet.cs @@ -27,9 +27,9 @@ namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory else max = 16; - for (int i = listOffset; i < 16; i++) + for (int i = 0; i < max; i++) { - binWriter.Write((UInt16)slots[i]); + binWriter.Write((UInt16)slots[listOffset]); listOffset++; } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX32Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX32Packet.cs index c7b8b59d..4b05d273 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX32Packet.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX32Packet.cs @@ -27,9 +27,9 @@ namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory else max = 32; - for (int i = listOffset; i < max; i++) + for (int i = 0; i < max; i++) { - binWriter.Write((UInt16)slots[i]); + binWriter.Write((UInt16)slots[listOffset]); listOffset++; } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX64Packet.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX64Packet.cs index 632b2e36..8359d2b4 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX64Packet.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryRemoveX64Packet.cs @@ -27,9 +27,9 @@ namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory else max = 64; - for (int i = listOffset; i < max; i++) + for (int i = 0; i < max; i++) { - binWriter.Write((UInt16)slots[i]); + binWriter.Write((UInt16)slots[listOffset]); listOffset++; } }