1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-23 05:07:47 +00:00

Implemented remove though will need to test more. Finished tweaking addItem(itemId, quantity).

This commit is contained in:
Filip Maj 2016-02-13 21:14:49 -05:00
parent 73732ac542
commit 110a112328
4 changed files with 302 additions and 55 deletions

View file

@ -589,7 +589,7 @@ namespace FFXIVClassic_Lobby_Server
return insertedItem; return insertedItem;
} }
public static void addQuantity(Player player, uint slot, int quantity) public static void setQuantity(Player player, uint slot, 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))) 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)))
{ {
@ -597,9 +597,9 @@ namespace FFXIVClassic_Lobby_Server
{ {
conn.Open(); conn.Open();
string query = @" string query = @"
UPDATE characters_inventory UPDATE characters_inventory
SET quantity = quantity + @quantity SET quantity = @quantity
WHERE serverItemId = (SELECT id FROM server_items WHERE characterId = @charId AND slot = @slot LIMIT 1) WHERE serverItemId = (SELECT id FROM server_items WHERE characterId = @charId AND slot = @slot LIMIT 1)
"; ";
@ -620,7 +620,41 @@ namespace FFXIVClassic_Lobby_Server
} }
public static void removeItem(Player player, uint uniqueItemId) public static void removeItem(Player player, ulong serverItemId)
{
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)))
{
try
{
conn.Open();
//Load Last 5 Completed
string query = @"
SELECT slot INTO @slotToDelete FROM characters_inventory WHERE serverItemId = @serverItemId;
UPDATE characters_inventory
SET slot = slot - 1
WHERE characterId = 108 AND slot > @slotToDelete;
DELETE FROM characters_inventory
WHERE serverItemId = @serverItemId;
";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
cmd.Parameters.AddWithValue("@serverItemId", serverItemId);
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
}
public static void removeItem(Player player, ushort slot)
{ {
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))) 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)))
{ {
@ -631,7 +665,7 @@ namespace FFXIVClassic_Lobby_Server
//Load Last 5 Completed //Load Last 5 Completed
string query = @" string query = @"
DELETE FROM server_items DELETE FROM server_items
WHERE id = @uniqueItemId; WHERE slot = @slot;
"; ";
string query2 = @" string query2 = @"
@ -639,13 +673,14 @@ namespace FFXIVClassic_Lobby_Server
WHERE uniqueServerId = @uniqueItemId; WHERE uniqueServerId = @uniqueItemId;
UPDATE character_inventory UPDATE character_inventory
SET slot = slot - 1 SET slot = slot - 1
WHERE characterId = @charId AND slot > X WHERE characterId = @charId AND slot > @slot
"; ";
query += query2; query += query2;
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId); cmd.Parameters.AddWithValue("@charId", player.actorId);
cmd.Parameters.AddWithValue("@slot", slot);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }

View file

@ -407,19 +407,36 @@ namespace FFXIVClassic_Lobby_Server
} }
} }
private void giveItem(ConnectedPlayer client, uint itemId) private void giveItem(ConnectedPlayer client, uint itemId, int quantity)
{ {
if (client != null) if (client != null)
{ {
Player p = client.getActor(); Player p = client.getActor();
p.inventories[Inventory.NORMAL].addItem(itemId, 0, 1, 1); p.inventories[Inventory.NORMAL].addItem(itemId, 0, quantity, 1);
} }
else else
{ {
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList) foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{ {
Player p = entry.Value.getActor(); Player p = entry.Value.getActor();
p.inventories[Inventory.NORMAL].addItem(itemId, 0, 1, 1); p.inventories[Inventory.NORMAL].addItem(itemId, 0, quantity, 1);
}
}
}
private void removeItem(ConnectedPlayer client, ushort slot)
{
if (client != null)
{
Player p = client.getActor();
p.inventories[Inventory.NORMAL].removeItem(slot);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
p.inventories[Inventory.NORMAL].removeItem(slot);
} }
} }
} }
@ -455,11 +472,11 @@ namespace FFXIVClassic_Lobby_Server
} }
mWorldManager.reloadZone(client.getActor().zoneId); mWorldManager.reloadZone(client.getActor().zoneId);
} }
} else if (split[0].Equals("sendpacket"))
if (split.Length >= 2)
{
if (split[0].Equals("sendpacket"))
{ {
if (split.Length < 2)
return;
try try
{ {
sendPacket(client, "./packets/" + split[1]); sendPacket(client, "./packets/" + split[1]);
@ -470,10 +487,27 @@ namespace FFXIVClassic_Lobby_Server
} }
} }
else if (split[0].Equals("giveitem")) else if (split[0].Equals("giveitem"))
{ {
try try
{ {
giveItem(client, UInt32.Parse(split[1])); if (split.Length == 2)
giveItem(client, UInt32.Parse(split[1]), 1);
else if (split.Length == 3)
giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]));
}
catch (Exception e)
{
Log.error("Could not give item.");
}
}
else if (split[0].Equals("removeitem"))
{
if (split.Length < 2)
return;
try
{
removeItem(client, UInt16.Parse(split[1]));
} }
catch (Exception e) catch (Exception e)
{ {
@ -482,6 +516,9 @@ namespace FFXIVClassic_Lobby_Server
} }
else if (split[0].Equals("music")) else if (split[0].Equals("music"))
{ {
if (split.Length < 2)
return;
try try
{ {
doMusic(client, split[1]); doMusic(client, split[1]);
@ -493,20 +530,17 @@ namespace FFXIVClassic_Lobby_Server
} }
else if (split[0].Equals("warp")) else if (split[0].Equals("warp"))
{ {
doWarp(client, split[1]); if (split.Length == 2)
} doWarp(client, split[1]);
} else if (split.Length == 5)
if (split.Length >= 5) doWarp(client, split[1], split[2], split[3], split[4]);
{
if (split[0].Equals("warp"))
{
doWarp(client, split[1], split[2], split[3], split[4]);
} }
else if (split[0].Equals("property")) else if (split[0].Equals("property"))
{ {
testCodePacket(Utils.MurmurHash2(split[1], 0), Convert.ToUInt32(split[2], 16), split[3]); if (split.Length == 5)
testCodePacket(Utils.MurmurHash2(split[1], 0), Convert.ToUInt32(split[2], 16), split[3]);
} }
} }
} }
} }

View file

@ -13,7 +13,7 @@ using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.chara.player namespace FFXIVClassic_Map_Server.actors.chara.player
{ {
class Inventory class Inventory
{ {
public const ushort NORMAL = 0x0000; //Max 0xC8 public const ushort NORMAL = 0x0000; //Max 0xC8
public const ushort LOOT = 0x0004; //Max 0xA public const ushort LOOT = 0x0004; //Max 0xA
public const ushort MELDREQUEST = 0x0005; //Max 0x04 public const ushort MELDREQUEST = 0x0005; //Max 0x04
@ -42,49 +42,154 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public void addItem(uint itemId, ushort type, int quantity, byte quality) public void addItem(uint itemId, ushort type, int quantity, byte quality)
{ {
if (!isSpaceForAdd(itemId, quantity))
return;
List<ushort> slotsToUpdate = new List<ushort>();
List<SubPacket> addItemPackets = new List<SubPacket>(); List<SubPacket> addItemPackets = new List<SubPacket>();
Item storedItem = null;
//Check if item id exists //Check if item id exists
foreach (Item item in list) int quantityCount = quantity;
for (int i = 0; i < list.Count; i++)
{ {
if (item.itemId == itemId && item.quantity < 99) Item item = list[i];
if (item.itemId == itemId && item.quantity < item.maxStack)
{ {
storedItem = item; slotsToUpdate.Add(item.slot);
break; int oldQuantity = item.quantity;
item.quantity = Math.Min(item.quantity + quantityCount, item.maxStack);
quantityCount -= (item.maxStack - oldQuantity);
if (quantityCount <= 0)
break;
} }
} }
//If it's unique, abort //If it's unique, abort
// if (storedItem != null && storedItem.isUnique) //if (quantityCount > 0 && storedItem.isUnique)
// return ITEMERROR_UNIQUE; // return ITEMERROR_UNIQUE;
//If Inventory is full //If Inventory is full
// if (storedItem == null && isInventoryFull()) //if (quantityCount > 0 && isInventoryFull())
// return ITEMERROR_FULL; // return ITEMERROR_FULL;
//Update lists and db //Update lists and db
owner.queuePacket(InventoryBeginChangePacket.buildPacket(owner.actorId)); owner.queuePacket(InventoryBeginChangePacket.buildPacket(owner.actorId));
owner.queuePacket(InventorySetBeginPacket.buildPacket(owner.actorId, inventoryCapacity, inventoryCode)); owner.queuePacket(InventorySetBeginPacket.buildPacket(owner.actorId, inventoryCapacity, inventoryCode));
if (storedItem == null)
//These had their quantities changed
foreach (ushort slot in slotsToUpdate)
{ {
Item addedItem = Database.addItem(owner, itemId, quantity, quality, false, 100, type); Database.setQuantity(owner, slot, list[slot].quantity);
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);
list.Add(addedItem); list.Add(addedItem);
sendInventoryPackets(addedItem); sendInventoryPackets(addedItem);
quantityCount -= addedItem.maxStack;
} }
else
{
Database.addQuantity(owner, storedItem.slot, quantity);
storedItem.quantity += quantity;
sendInventoryPackets(storedItem);
}
owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId)); owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId));
owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId)); owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId));
} }
public void removeItem(uint itemId, uint quantity) public void removeItem(uint itemId, int quantity)
{ {
if (!hasItem(itemId))
return;
List<ushort> slotsToRemove = new List<ushort>();
List<SubPacket> addItemPackets = new List<SubPacket>();
//Remove as we go along
int quantityCount = quantity;
ushort lowestSlot = 0;
for (int i = list.Count - 1; i >= 0; i--)
{
Item item = list[i];
if (item.itemId == itemId)
{
//Stack nomnomed
if (item.quantity - quantityCount <= 0)
slotsToRemove.Add(item.slot);
else
item.quantity -= quantityCount; //Stack reduced
quantityCount -= item.quantity;
lowestSlot = item.slot;
if (quantityCount <= 0)
break;
}
}
list.Sort();
int numSlotsRemoved = 0;
for (int i = 0; i < slotsToRemove.Count; i++)
{
Database.removeItem(owner, (ushort)(slotsToRemove[i] - numSlotsRemoved));
list.RemoveAt(slotsToRemove[i] - numSlotsRemoved);
numSlotsRemoved++;
}
owner.queuePacket(InventoryBeginChangePacket.buildPacket(owner.actorId));
owner.queuePacket(InventorySetBeginPacket.buildPacket(owner.actorId, inventoryCapacity, inventoryCode));
sendInventoryPackets(lowestSlot);
sendInventoryRemovePackets(slotsToRemove);
owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId));
owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId));
}
public void removeItem(uint itemDBId)
{
ushort slot = 0;
Item toDelete = null;
foreach (Item item in list)
{
if (item.uniqueId == itemDBId)
{
toDelete = item;
break;
}
slot++;
}
if (toDelete == null)
return;
list.RemoveAt(slot);
Database.removeItem(owner, itemDBId);
owner.queuePacket(InventoryBeginChangePacket.buildPacket(owner.actorId));
owner.queuePacket(InventorySetBeginPacket.buildPacket(owner.actorId, inventoryCapacity, inventoryCode));
sendInventoryPackets(slot);
sendInventoryRemovePackets(slot);
owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId));
owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId));
}
public void removeItem(ushort slot)
{
list.RemoveAt((int)slot);
Database.removeItem(owner, slot);
owner.queuePacket(InventoryBeginChangePacket.buildPacket(owner.actorId));
owner.queuePacket(InventorySetBeginPacket.buildPacket(owner.actorId, inventoryCapacity, inventoryCode));
sendInventoryPackets(slot);
sendInventoryRemovePackets(slot);
owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId));
owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId));
} }
public void changeDurability(uint slot, uint durabilityChange) public void changeDurability(uint slot, uint durabilityChange)
@ -107,7 +212,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public void sendFullInventory() public void sendFullInventory()
{ {
owner.queuePacket(InventorySetBeginPacket.buildPacket(owner.actorId, inventoryCapacity, inventoryCode)); owner.queuePacket(InventorySetBeginPacket.buildPacket(owner.actorId, inventoryCapacity, inventoryCode));
sendInventoryPackets(list); sendInventoryPackets(0);
owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId)); owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId));
} }
@ -116,23 +221,23 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
owner.queuePacket(InventoryListX01Packet.buildPacket(owner.actorId, item)); owner.queuePacket(InventoryListX01Packet.buildPacket(owner.actorId, item));
} }
private void sendInventoryPackets(List<Item> items) private void sendInventoryPackets(int startOffset)
{ {
int currentIndex = 0; int currentIndex = startOffset;
while (true) while (true)
{ {
if (items.Count - currentIndex >= 64) if (list.Count - currentIndex >= 64)
owner.queuePacket(InventoryListX64Packet.buildPacket(owner.actorId, items, ref currentIndex)); owner.queuePacket(InventoryListX64Packet.buildPacket(owner.actorId, list, ref currentIndex));
else if (items.Count - currentIndex >= 32) else if (list.Count - currentIndex >= 32)
owner.queuePacket(InventoryListX32Packet.buildPacket(owner.actorId, items, ref currentIndex)); owner.queuePacket(InventoryListX32Packet.buildPacket(owner.actorId, list, ref currentIndex));
else if (items.Count - currentIndex >= 16) else if (list.Count - currentIndex >= 16)
owner.queuePacket(InventoryListX16Packet.buildPacket(owner.actorId, items, ref currentIndex)); owner.queuePacket(InventoryListX16Packet.buildPacket(owner.actorId, list, ref currentIndex));
else if (items.Count - currentIndex > 1) else if (list.Count - currentIndex > 1)
owner.queuePacket(InventoryListX08Packet.buildPacket(owner.actorId, items, ref currentIndex)); owner.queuePacket(InventoryListX08Packet.buildPacket(owner.actorId, list, ref currentIndex));
else if (items.Count - currentIndex == 1) else if (list.Count - currentIndex == 1)
{ {
owner.queuePacket(InventoryListX01Packet.buildPacket(owner.actorId, items[currentIndex])); owner.queuePacket(InventoryListX01Packet.buildPacket(owner.actorId, list[currentIndex]));
currentIndex++; currentIndex++;
} }
else else
@ -140,6 +245,37 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
} }
} }
private void sendInventoryRemovePackets(ushort index)
{
owner.queuePacket(InventoryRemoveX01Packet.buildPacket(owner.actorId, index));
}
private void sendInventoryRemovePackets(List<ushort> indexes)
{
int currentIndex = 0;
while (true)
{
if (indexes.Count - currentIndex >= 64)
owner.queuePacket(InventoryRemoveX64Packet.buildPacket(owner.actorId, indexes, ref currentIndex));
else if (indexes.Count - currentIndex >= 32)
owner.queuePacket(InventoryRemoveX32Packet.buildPacket(owner.actorId, indexes, ref currentIndex));
else if (indexes.Count - currentIndex >= 16)
owner.queuePacket(InventoryRemoveX16Packet.buildPacket(owner.actorId, indexes, ref currentIndex));
else if (indexes.Count - currentIndex > 1)
owner.queuePacket(InventoryRemoveX08Packet.buildPacket(owner.actorId, indexes, ref currentIndex));
else if (indexes.Count - currentIndex == 1)
{
owner.queuePacket(InventoryRemoveX01Packet.buildPacket(owner.actorId, indexes[currentIndex]));
currentIndex++;
}
else
break;
}
}
#endregion #endregion
#region Inventory Utils #region Inventory Utils
@ -148,6 +284,46 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
{ {
return list.Count >= inventoryCapacity; return list.Count >= inventoryCapacity;
} }
public bool isSpaceForAdd(uint itemId, int quantity)
{
int quantityCount = quantity;
for (int i = 0; i < list.Count; i++)
{
Item item = list[i];
if (item.itemId == itemId && item.quantity < item.maxStack)
{
int oldQuantity = item.quantity;
item.quantity = Math.Min(item.quantity + quantityCount, item.maxStack);
quantityCount -= (item.maxStack - oldQuantity);
if (quantityCount <= 0)
break;
}
}
return quantityCount <= 0 || (quantityCount > 0 && !isFull());
}
public bool hasItem(uint itemId)
{
return hasItem(itemId, 1);
}
public bool hasItem(uint itemId, int minQuantity)
{
int count = 0;
foreach (Item item in list)
{
if (item.itemId == itemId)
count += item.quantity;
if (count >= minQuantity)
return true;
}
return false;
}
public int getNextEmptySlot() public int getNextEmptySlot()
{ {

View file

@ -14,6 +14,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
public int quantity = 1; public int quantity = 1;
public ushort slot; public ushort slot;
public int maxStack = 5;
public bool isUntradeable = false; public bool isUntradeable = false;
public byte quality = 1; public byte quality = 1;