1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-20 11:47:48 +00:00
Fix Excruciate removign status from enemy rather than caster
This commit is contained in:
Yogurt 2019-06-05 19:28:02 -07:00
commit f2e34174c4
272 changed files with 8223 additions and 2425 deletions

View file

@ -1,5 +1,4 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following

View file

@ -1,12 +1,4 @@
using System; using NLog;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using NLog;
using System.Data;
using System.Data.Common;
namespace FFXIVClassic.Common namespace FFXIVClassic.Common
{ {

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using FFXIVClassic.Common;
using NLog; using NLog;
using NLog.Targets; using NLog.Targets;

View file

@ -145,6 +145,12 @@ namespace FFXIVClassic.Common
return input; return input;
} }
public static ushort SwapEndian(ushort input)
{
return (ushort)(((input << 8) & 0xff00) |
((input >> 8) & 0x00ff));
}
public static uint MurmurHash2(string key, uint seed) public static uint MurmurHash2(string key, uint seed)
{ {
// 'm' and 'r' are mixing constants generated offline. // 'm' and 'r' are mixing constants generated offline.

View file

@ -2,9 +2,7 @@
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using FFXIVClassic_Lobby_Server.utils; using FFXIVClassic_Lobby_Server.utils;
using FFXIVClassic.Common;
namespace FFXIVClassic_Lobby_Server namespace FFXIVClassic_Lobby_Server
{ {

View file

@ -2,8 +2,6 @@
using System.Diagnostics; using System.Diagnostics;
using System.Threading; using System.Threading;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using System.Reflection;
using FFXIVClassic.Common;
using NLog; using NLog;
namespace FFXIVClassic_Lobby_Server namespace FFXIVClassic_Lobby_Server
{ {

View file

@ -5,7 +5,6 @@ using System.Net.Sockets;
using System.Threading; using System.Threading;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using NLog;
namespace FFXIVClassic_Lobby_Server namespace FFXIVClassic_Lobby_Server
{ {

View file

@ -1,11 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using System.IO; using System.IO;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send; using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;

View file

@ -1,9 +1,6 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net.Sockets;
using MoonSharp.Interpreter.Interop;
using System.Linq; using System.Linq;
using System.Net; using System.Net;

View file

@ -12,7 +12,6 @@ using FFXIVClassic_Map_Server.packets.receive.supportdesk;
using FFXIVClassic_Map_Server.actors.chara.npc; using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.actors.chara.ai; using FFXIVClassic_Map_Server.actors.chara.ai;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.actors.chara;
namespace FFXIVClassic_Map_Server namespace FFXIVClassic_Map_Server
{ {
@ -1111,14 +1110,14 @@ namespace FFXIVClassic_Map_Server
} }
} }
player.GetInventory(Inventory.NORMAL).InitList(GetInventory(player, 0, Inventory.NORMAL)); player.GetItemPackage(ItemPackage.NORMAL).InitList(GetItemPackage(player, 0, ItemPackage.NORMAL));
player.GetInventory(Inventory.KEYITEMS).InitList(GetInventory(player, 0, Inventory.KEYITEMS)); player.GetItemPackage(ItemPackage.KEYITEMS).InitList(GetItemPackage(player, 0, ItemPackage.KEYITEMS));
player.GetInventory(Inventory.CURRENCY_CRYSTALS).InitList(GetInventory(player, 0, Inventory.CURRENCY_CRYSTALS)); player.GetItemPackage(ItemPackage.CURRENCY_CRYSTALS).InitList(GetItemPackage(player, 0, ItemPackage.CURRENCY_CRYSTALS));
player.GetInventory(Inventory.BAZAAR).InitList(GetInventory(player, 0, Inventory.BAZAAR)); player.GetItemPackage(ItemPackage.BAZAAR).InitList(GetBazaar(player));
player.GetInventory(Inventory.MELDREQUEST).InitList(GetInventory(player, 0, Inventory.MELDREQUEST)); player.GetItemPackage(ItemPackage.MELDREQUEST).InitList(GetItemPackage(player, 0, ItemPackage.MELDREQUEST));
player.GetInventory(Inventory.LOOT).InitList(GetInventory(player, 0, Inventory.LOOT)); player.GetItemPackage(ItemPackage.LOOT).InitList(GetItemPackage(player, 0, ItemPackage.LOOT));
player.GetEquipment().SetEquipment(GetEquipment(player, player.charaWork.parameterSave.state_mainSkill[0])); player.GetEquipment().SetList(GetEquipment(player, player.charaWork.parameterSave.state_mainSkill[0]));
} }
catch (MySqlException e) catch (MySqlException e)
{ {
@ -1159,7 +1158,7 @@ namespace FFXIVClassic_Map_Server
{ {
ushort equipSlot = reader.GetUInt16(0); ushort equipSlot = reader.GetUInt16(0);
ulong uniqueItemId = reader.GetUInt16(1); ulong uniqueItemId = reader.GetUInt16(1);
InventoryItem item = player.GetInventory(Inventory.NORMAL).GetItemByUniqueId(uniqueItemId); InventoryItem item = player.GetItemPackage(ItemPackage.NORMAL).GetItemByUniqueId(uniqueItemId);
equipment[equipSlot] = item; equipment[equipSlot] = item;
} }
} }
@ -1196,7 +1195,7 @@ namespace FFXIVClassic_Map_Server
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@characterId", player.actorId); cmd.Parameters.AddWithValue("@characterId", player.actorId);
cmd.Parameters.AddWithValue("@classId", (equipSlot == Equipment.SLOT_UNDERSHIRT || equipSlot == Equipment.SLOT_UNDERGARMENT) ? 0 : player.charaWork.parameterSave.state_mainSkill[0]); cmd.Parameters.AddWithValue("@classId", (equipSlot == Player.SLOT_UNDERSHIRT || equipSlot == Player.SLOT_UNDERGARMENT) ? 0 : player.charaWork.parameterSave.state_mainSkill[0]);
cmd.Parameters.AddWithValue("@equipSlot", equipSlot); cmd.Parameters.AddWithValue("@equipSlot", equipSlot);
cmd.Parameters.AddWithValue("@uniqueItemId", uniqueItemId); cmd.Parameters.AddWithValue("@uniqueItemId", uniqueItemId);
@ -1435,7 +1434,8 @@ namespace FFXIVClassic_Map_Server
} }
return slot; return slot;
} }
public static List<InventoryItem> GetInventory(Player player, uint slotOffset, uint type)
public static List<InventoryItem> GetItemPackage(Player player, uint slotOffset, uint type)
{ {
List<InventoryItem> items = new List<InventoryItem>(); List<InventoryItem> items = new List<InventoryItem>();
@ -1449,19 +1449,29 @@ namespace FFXIVClassic_Map_Server
SELECT SELECT
serverItemId, serverItemId,
itemId, itemId,
server_items_modifiers.id AS modifierId,
quantity, quantity,
itemType,
quality, quality,
durability, durability,
spiritBind, mainQuality,
subQuality1,
subQuality2,
subQuality3,
param1,
param2,
param3,
spiritbind,
materia1, materia1,
materia2, materia2,
materia3, materia3,
materia4, materia4,
materia5 materia5
FROM characters_inventory FROM characters_inventory
INNER JOIN server_items ON serverItemId = server_items.id INNER JOIN server_items ON serverItemId = server_items.id
WHERE characterId = @charId AND inventoryType = @type"; LEFT JOIN server_items_modifiers ON server_items.id = server_items_modifiers.id
WHERE characterId = @charId AND itemPackage = @type";
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId); cmd.Parameters.AddWithValue("@charId", player.actorId);
@ -1476,21 +1486,15 @@ namespace FFXIVClassic_Map_Server
uint itemId = reader.GetUInt32("itemId"); uint itemId = reader.GetUInt32("itemId");
int quantity = reader.GetInt32("quantity"); int quantity = reader.GetInt32("quantity");
byte itemType = reader.GetByte("itemType");
byte qualityNumber = reader.GetByte("quality"); byte qualityNumber = reader.GetByte("quality");
int durability = reader.GetInt32("durability"); bool hasModifier = !reader.IsDBNull(reader.GetOrdinal("modifierId"));
ushort spiritBind = reader.GetUInt16("spiritBind"); InventoryItem.ItemModifier modifier = null;
byte materia1 = reader.GetByte("materia1"); if (hasModifier)
byte materia2 = reader.GetByte("materia2"); modifier = new InventoryItem.ItemModifier(reader);
byte materia3 = reader.GetByte("materia3");
byte materia4 = reader.GetByte("materia4");
byte materia5 = reader.GetByte("materia5");
InventoryItem item = new InventoryItem(uniqueId, itemId, quantity, itemType, qualityNumber, durability, spiritBind, materia1, materia2, materia3, materia4, materia5); InventoryItem item = new InventoryItem(uniqueId, Server.GetItemGamedata(itemId), quantity, qualityNumber, modifier);
item.slot = slot;
slot++;
items.Add(item); items.Add(item);
} }
} }
@ -1508,6 +1512,247 @@ namespace FFXIVClassic_Map_Server
return items; return items;
} }
public static bool CreateBazaarEntry(Player owner, InventoryItem reward, InventoryItem seek, int rewardAmount, int seekAmount, byte bazaarMode, int sellPrice = 0)
{
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();
string query = @"
INSERT INTO characters_inventory_bazaar
(characterId, rewardId, seekId, rewardAmount, seekAmount, bazaarMode, sellPrice)
VALUES
(@characterId, @rewardId, @seekId, @rewardAmount, @seekAmount, @bazaarMode, @sellPrice);
";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@characterId", owner.actorId);
cmd.Parameters.AddWithValue("@rewardId", reward.uniqueId);
cmd.Parameters.AddWithValue("@seekId", seek.uniqueId);
cmd.Parameters.AddWithValue("@rewardAmount", rewardAmount);
cmd.Parameters.AddWithValue("@seekAmount", seekAmount);
cmd.Parameters.AddWithValue("@bazaarMode", bazaarMode);
cmd.Parameters.AddWithValue("@sellPrice", sellPrice);
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
return false;
}
finally
{
conn.Dispose();
}
}
return true;
}
public static void ClearBazaarEntry(Player owner, InventoryItem reward)
{
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)))
{
try
{
conn.Open();
string query = @"
DELETE FROM characters_inventory_bazaar
WHERE characterId = @charId and rewardId = @rewardId;
";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", owner.actorId);
cmd.Parameters.AddWithValue("@rewardId", reward.uniqueId);
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
}
public static List<InventoryItem> GetBazaar(Player player)
{
List<InventoryItem> rewardItems = new List<InventoryItem>();
Dictionary<ulong, InventoryItem> seekItems = new Dictionary<ulong, InventoryItem>();
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();
string query = @"
SELECT
rewardId,
seekId,
rewardAmount,
bazaarMode,
sellPrice,
itemId,
server_items_modifiers.id AS modifierId,
quantity,
quality,
durability,
mainQuality,
subQuality1,
subQuality2,
subQuality3,
param1,
param2,
param3,
spiritbind,
materia1,
materia2,
materia3,
materia4,
materia5
FROM characters_inventory_bazaar
INNER JOIN server_items ON rewardId = server_items.id
LEFT JOIN server_items_modifiers ON server_items.id = server_items_modifiers.id
WHERE characterId = @charaId";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charaId", player.actorId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
uint uniqueId = reader.GetUInt32("rewardId");
uint itemId = reader.GetUInt32("itemId");
int quantity = reader.GetInt32("quantity");
byte qualityNumber = reader.GetByte("quality");
bool hasModifier = !reader.IsDBNull(reader.GetOrdinal("modifierId"));
InventoryItem.ItemModifier modifier = null;
if (hasModifier)
modifier = new InventoryItem.ItemModifier(reader);
InventoryItem item = new InventoryItem(uniqueId, Server.GetItemGamedata(itemId), quantity, qualityNumber, modifier);
byte bazaarMode = reader.GetByte("bazaarMode");
if (bazaarMode == InventoryItem.TYPE_SINGLE || bazaarMode == InventoryItem.TYPE_MULTI || bazaarMode == InventoryItem.TYPE_STACK)
{
uint price = (uint)reader.GetInt32("sellPrice");
item.SetDealing(bazaarMode, (int)price);
}
else
{
uint seekId = reader.GetUInt32("seekId");
item.SetDealingAttached(bazaarMode, seekId);
}
rewardItems.Add(item);
}
}
string query2 = @"
SELECT
seekId,
seekAmount,
sellPrice,
itemId,
server_items_modifiers.id AS modifierId,
quantity,
quality,
durability,
mainQuality,
subQuality1,
subQuality2,
subQuality3,
param1,
param2,
param3,
spiritbind,
materia1,
materia2,
materia3,
materia4,
materia5
FROM characters_inventory_bazaar
INNER JOIN server_items ON seekId = server_items.id
LEFT JOIN server_items_modifiers ON server_items.id = server_items_modifiers.id
WHERE characterId = @charaId and bazaarMode != 11 and bazaarMode != 12 and bazaarMode != 13";
MySqlCommand cmd2 = new MySqlCommand(query2, conn);
cmd2.Parameters.AddWithValue("@charaId", player.actorId);
using (MySqlDataReader reader = cmd2.ExecuteReader())
{
while (reader.Read())
{
uint uniqueId = reader.GetUInt32("seekId");
uint itemId = reader.GetUInt32("itemId");
int quantity = reader.GetInt32("quantity");
byte qualityNumber = reader.GetByte("quality");
bool hasModifier = !reader.IsDBNull(reader.GetOrdinal("modifierId"));
InventoryItem.ItemModifier modifier = null;
if (hasModifier)
modifier = new InventoryItem.ItemModifier(reader);
InventoryItem item = new InventoryItem(uniqueId, Server.GetItemGamedata(itemId), quantity, qualityNumber, modifier);
item.SetHasAttached(true);
seekItems.Add(uniqueId, item);
}
}
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
List<InventoryItem> items = new List<InventoryItem>();
ushort slot = 0;
foreach (InventoryItem reward in rewardItems)
{
if (reward.dealingMode == InventoryItem.DEALINGMODE_PRICED)
{
reward.slot = slot++;
items.Add(reward);
}
else
{
if (seekItems.ContainsKey(reward.GetAttached()))
{
reward.slot = slot++;
items.Add(reward);
InventoryItem seek = seekItems[reward.GetAttached()];
seek.slot = slot++;
items.Add(seek);
reward.SetAttachedIndex(7, seek.slot);
}
}
}
return items;
}
public static List<InventoryItem> GetInventory(Retainer retainer, uint type) public static List<InventoryItem> GetInventory(Retainer retainer, uint type)
{ {
List<InventoryItem> items = new List<InventoryItem>(); List<InventoryItem> items = new List<InventoryItem>();
@ -1522,22 +1767,32 @@ namespace FFXIVClassic_Map_Server
SELECT SELECT
serverItemId, serverItemId,
itemId, itemId,
server_items_modifiers.id AS modifierId,
quantity, quantity,
itemType,
quality, quality,
durability, durability,
spiritBind, mainQuality,
subQuality1,
subQuality2,
subQuality3,
param1,
param2,
param3,
spiritbind,
materia1, materia1,
materia2, materia2,
materia3, materia3,
materia4, materia4,
materia5 materia5
FROM retainers_inventory FROM retainers_inventory
INNER JOIN server_items ON serverItemId = server_items.id INNER JOIN server_items ON serverItemId = server_items.id
WHERE retainerId = @retainerId AND inventoryType = @type"; LEFT JOIN server_items_modifiers ON server_items.id = server_items_modifiers.id
WHERE retainerId = @retainerId AND itemPackage = @type";
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@retainerId", retainer.getRetainerId()); cmd.Parameters.AddWithValue("@retainerId", retainer.GetRetainerId());
cmd.Parameters.AddWithValue("@type", type); cmd.Parameters.AddWithValue("@type", type);
ushort slot = 0; ushort slot = 0;
@ -1549,21 +1804,15 @@ namespace FFXIVClassic_Map_Server
uint itemId = reader.GetUInt32("itemId"); uint itemId = reader.GetUInt32("itemId");
int quantity = reader.GetInt32("quantity"); int quantity = reader.GetInt32("quantity");
byte itemType = reader.GetByte("itemType");
byte qualityNumber = reader.GetByte("quality"); byte qualityNumber = reader.GetByte("quality");
int durability = reader.GetInt32("durability"); bool hasModifier = !reader.IsDBNull(reader.GetOrdinal("modifierId"));
ushort spiritBind = reader.GetUInt16("spiritBind"); InventoryItem.ItemModifier modifier = null;
byte materia1 = reader.GetByte("materia1"); if (hasModifier)
byte materia2 = reader.GetByte("materia2"); modifier = new InventoryItem.ItemModifier(reader);
byte materia3 = reader.GetByte("materia3");
byte materia4 = reader.GetByte("materia4");
byte materia5 = reader.GetByte("materia5");
InventoryItem item = new InventoryItem(uniqueId, itemId, quantity, itemType, qualityNumber, durability, spiritBind, materia1, materia2, materia3, materia4, materia5); InventoryItem item = new InventoryItem(uniqueId, Server.GetItemGamedata(itemId), quantity, qualityNumber, modifier);
item.slot = slot;
slot++;
items.Add(item); items.Add(item);
} }
} }
@ -1581,7 +1830,7 @@ namespace FFXIVClassic_Map_Server
return items; return items;
} }
public static InventoryItem CreateItem(uint itemId, int quantity, byte quality, byte itemType, int durability) public static InventoryItem CreateItem(uint itemId, int quantity, byte quality, InventoryItem.ItemModifier modifiers = null)
{ {
InventoryItem insertedItem = null; InventoryItem insertedItem = null;
@ -1595,21 +1844,33 @@ namespace FFXIVClassic_Map_Server
string query = @" string query = @"
INSERT INTO server_items INSERT INTO server_items
(itemId, quality, itemType, durability) (itemId, quantity, quality)
VALUES VALUES
(@itemId, @quality, @itemType, @durability); (@itemId, @quantity, @quality);
";
string query2 = @"
INSERT INTO server_items_modifiers
(id, durability)
VALUES
(@id, @durability);
"; ";
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@itemId", itemId); cmd.Parameters.AddWithValue("@itemId", itemId);
cmd.Parameters.AddWithValue("@quantity", quantity);
cmd.Parameters.AddWithValue("@quality", quality); cmd.Parameters.AddWithValue("@quality", quality);
cmd.Parameters.AddWithValue("@itemType", itemType);
cmd.Parameters.AddWithValue("@durability", durability);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
insertedItem = new InventoryItem((uint)cmd.LastInsertedId, itemId, quantity, itemType, quality, durability, 0, 0, 0, 0, 0, 0); insertedItem = new InventoryItem((uint)cmd.LastInsertedId, Server.GetItemGamedata(itemId), quantity, quality, modifiers);
if (modifiers != null)
{
MySqlCommand cmd2 = new MySqlCommand(query2, conn);
cmd2.Parameters.AddWithValue("@id", insertedItem.uniqueId);
cmd2.Parameters.AddWithValue("@durability", modifiers.durability);
cmd2.ExecuteNonQuery();
}
} }
catch (MySqlException e) catch (MySqlException e)
{ {
@ -1634,17 +1895,16 @@ namespace FFXIVClassic_Map_Server
string query = @" string query = @"
INSERT INTO characters_inventory INSERT INTO characters_inventory
(characterId, inventoryType, serverItemId, quantity) (characterId, itemPackage, serverItemId)
VALUES VALUES
(@charId, @inventoryType, @serverItemId, @quantity) (@charId, @itemPackage, @serverItemId)
"; ";
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@serverItemId", addedItem.uniqueId); cmd.Parameters.AddWithValue("@serverItemId", addedItem.uniqueId);
cmd.Parameters.AddWithValue("@charId", player.actorId); cmd.Parameters.AddWithValue("@charId", player.actorId);
cmd.Parameters.AddWithValue("@inventoryType", type); cmd.Parameters.AddWithValue("@itemPackage", type);
cmd.Parameters.AddWithValue("@quantity", addedItem.quantity);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
@ -1659,7 +1919,9 @@ namespace FFXIVClassic_Map_Server
} }
} }
public static void SetQuantity(Player player, ulong serverItemId, int quantity)
public static void SetQuantity(ulong serverItemId, 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)))
{ {
@ -1668,13 +1930,12 @@ namespace FFXIVClassic_Map_Server
conn.Open(); conn.Open();
string query = @" string query = @"
UPDATE characters_inventory UPDATE server_items
SET quantity = @quantity SET quantity = @quantity
WHERE characterId = @charId and serverItemId = @serverItemId; WHERE id = @serverItemId;
"; ";
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
cmd.Parameters.AddWithValue("@serverItemId", serverItemId); cmd.Parameters.AddWithValue("@serverItemId", serverItemId);
cmd.Parameters.AddWithValue("@quantity", quantity); cmd.Parameters.AddWithValue("@quantity", quantity);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
@ -1720,7 +1981,6 @@ namespace FFXIVClassic_Map_Server
conn.Dispose(); conn.Dispose();
} }
} }
} }
public static void AddItem(Retainer retainer, InventoryItem addedItem, uint type) public static void AddItem(Retainer retainer, InventoryItem addedItem, uint type)
@ -1733,17 +1993,16 @@ namespace FFXIVClassic_Map_Server
string query = @" string query = @"
INSERT INTO retainers_inventory INSERT INTO retainers_inventory
(retainerId, inventoryType, serverItemId, quantity) (retainerId, itemPackage, serverItemId)
VALUES VALUES
(@retainerId, @inventoryType, @serverItemId, @quantity) (@retainerId, @itemPackage, @serverItemId)
"; ";
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@serverItemId", addedItem.uniqueId); cmd.Parameters.AddWithValue("@serverItemId", addedItem.uniqueId);
cmd.Parameters.AddWithValue("@retainerId", retainer.getRetainerId()); cmd.Parameters.AddWithValue("@retainerId", retainer.GetRetainerId());
cmd.Parameters.AddWithValue("@inventoryType", type); cmd.Parameters.AddWithValue("@itemPackage", type);
cmd.Parameters.AddWithValue("@quantity", addedItem.quantity);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
@ -1758,39 +2017,6 @@ namespace FFXIVClassic_Map_Server
} }
} }
public static void SetQuantity(Retainer retainer, ulong serverItemId, 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)))
{
try
{
conn.Open();
string query = @"
UPDATE retainers_inventory
SET quantity = @quantity
WHERE retainerId = @retainerId and serverItemId = @serverItemId;
";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@retainerId", retainer.getRetainerId());
cmd.Parameters.AddWithValue("@serverItemId", serverItemId);
cmd.Parameters.AddWithValue("@quantity", quantity);
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
}
public static void RemoveItem(Retainer retainer, ulong serverItemId) public static void RemoveItem(Retainer retainer, ulong serverItemId)
{ {
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))) 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)))
@ -1805,7 +2031,7 @@ namespace FFXIVClassic_Map_Server
"; ";
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@retainerId", retainer.getRetainerId()); cmd.Parameters.AddWithValue("@retainerId", retainer.GetRetainerId());
cmd.Parameters.AddWithValue("@serverItemId", serverItemId); cmd.Parameters.AddWithValue("@serverItemId", serverItemId);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
@ -1908,6 +2134,45 @@ namespace FFXIVClassic_Map_Server
return cheevosPacket.BuildPacket(player.actorId); return cheevosPacket.BuildPacket(player.actorId);
} }
public static SubPacket GetAchievementProgress(Player player, uint achievementId)
{
uint progress = 0, progressFlags = 0;
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();
string query = @"
SELECT progress, progressFlags
FROM characters_achievements
WHERE characterId = @charId AND achievementId = @achievementId";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charId", player.actorId);
cmd.Parameters.AddWithValue("@achievementId", achievementId);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
progress = reader.GetUInt32(0);
progressFlags = reader.GetUInt32(1);
}
}
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
return SendAchievementRatePacket.BuildPacket(player.actorId, achievementId, progress, progressFlags);
}
public static bool CreateLinkshell(Player player, string lsName, ushort lsCrest) public static bool CreateLinkshell(Player player, string lsName, ushort lsCrest)
{ {
bool success = false; bool success = false;
@ -2645,7 +2910,7 @@ namespace FFXIVClassic_Map_Server
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charaId", player.actorId); cmd.Parameters.AddWithValue("@charaId", player.actorId);
cmd.Parameters.AddWithValue("@retainerIndex", retainerIndex-1); cmd.Parameters.AddWithValue("@retainerIndex", retainerIndex - 1);
using (MySqlDataReader reader = cmd.ExecuteReader()) using (MySqlDataReader reader = cmd.ExecuteReader())
{ {
@ -2677,5 +2942,85 @@ namespace FFXIVClassic_Map_Server
} }
} }
public static void PlayerCharacterUpdateClassLevel(Player player, byte classId, short level)
{
string query;
MySqlCommand cmd;
string[] classNames = {
"",
"",
"pug",
"gla",
"mrd",
"",
"",
"arc",
"lnc",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"thm",
"cnj",
"",
"",
"",
"",
"",
"crp",
"bsm",
"arm",
"gsm",
"ltw",
"wvr",
"alc",
"cul",
"",
"",
"min",
"btn",
"fsh"
};
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();
query = String.Format(@"
UPDATE characters_class_levels
SET
{0}=@level
WHERE
characterId = @characterId", classNames[classId]);
cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@level", level);
cmd.Parameters.AddWithValue("@characterId", player.actorId);
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
}
}
} }
} }

View file

@ -139,8 +139,8 @@
<Compile Include="actors\chara\AetheryteWork.cs" /> <Compile Include="actors\chara\AetheryteWork.cs" />
<Compile Include="actors\chara\npc\Retainer.cs" /> <Compile Include="actors\chara\npc\Retainer.cs" />
<Compile Include="actors\chara\npc\Pet.cs" /> <Compile Include="actors\chara\npc\Pet.cs" />
<Compile Include="actors\chara\player\Equipment.cs" /> <Compile Include="actors\chara\ItemPackage.cs" />
<Compile Include="actors\chara\player\Inventory.cs" /> <Compile Include="actors\chara\ReferencedItemPackage.cs" />
<Compile Include="actors\chara\SubState.cs" /> <Compile Include="actors\chara\SubState.cs" />
<Compile Include="actors\chara\Work.cs" /> <Compile Include="actors\chara\Work.cs" />
<Compile Include="actors\debug\Debug.cs" /> <Compile Include="actors\debug\Debug.cs" />
@ -150,23 +150,25 @@
<Compile Include="actors\EventList.cs" /> <Compile Include="actors\EventList.cs" />
<Compile Include="actors\group\GLContentGroup.cs" /> <Compile Include="actors\group\GLContentGroup.cs" />
<Compile Include="actors\group\ContentGroup.cs" /> <Compile Include="actors\group\ContentGroup.cs" />
<Compile Include="actors\group\TradeGroup.cs" />
<Compile Include="actors\group\RetainerMeetingRelationGroup.cs" /> <Compile Include="actors\group\RetainerMeetingRelationGroup.cs" />
<Compile Include="actors\group\Work\ContentGroupWork.cs" /> <Compile Include="actors\group\Work\ContentGroupWork.cs" />
<Compile Include="actors\group\Work\GlobalTemp.cs" /> <Compile Include="actors\group\Work\GlobalTemp.cs" />
<Compile Include="actors\group\Group.cs" /> <Compile Include="actors\group\Group.cs" />
<Compile Include="actors\group\MonsterParty.cs" /> <Compile Include="actors\group\MonsterParty.cs" />
<Compile Include="actors\group\Party.cs" /> <Compile Include="actors\group\Party.cs" />
<Compile Include="actors\group\Relation.cs" /> <Compile Include="actors\group\RelationGroup.cs" />
<Compile Include="actors\group\work\GroupGlobalSave.cs" /> <Compile Include="actors\group\Work\GroupGlobalSave.cs" />
<Compile Include="actors\group\work\GroupGlobalTemp.cs" /> <Compile Include="actors\group\Work\GroupGlobalTemp.cs" />
<Compile Include="actors\group\work\GroupMemberSave.cs" /> <Compile Include="actors\group\Work\GroupMemberSave.cs" />
<Compile Include="actors\group\work\PartyWork.cs" /> <Compile Include="actors\group\Work\PartyWork.cs" />
<Compile Include="actors\group\work\RelationWork.cs" /> <Compile Include="actors\group\Work\RelationWork.cs" />
<Compile Include="actors\judge\Judge.cs" /> <Compile Include="actors\judge\Judge.cs" />
<Compile Include="actors\quest\Quest.cs" /> <Compile Include="actors\quest\Quest.cs" />
<Compile Include="actors\StaticActors.cs" /> <Compile Include="actors\StaticActors.cs" />
<Compile Include="actors\world\WorldMaster.cs" /> <Compile Include="actors\world\WorldMaster.cs" />
<Compile Include="dataobjects\GuildleveData.cs" /> <Compile Include="dataobjects\GuildleveData.cs" />
<Compile Include="dataobjects\TradeTransaction.cs" />
<Compile Include="dataobjects\ZoneConnection.cs" /> <Compile Include="dataobjects\ZoneConnection.cs" />
<Compile Include="CommandProcessor.cs" /> <Compile Include="CommandProcessor.cs" />
<Compile Include="ConfigConstants.cs" /> <Compile Include="ConfigConstants.cs" />
@ -195,6 +197,7 @@
<Compile Include="lua\LuaScript.cs" /> <Compile Include="lua\LuaScript.cs" />
<Compile Include="lua\LuaUtils.cs" /> <Compile Include="lua\LuaUtils.cs" />
<Compile Include="PacketProcessor.cs" /> <Compile Include="PacketProcessor.cs" />
<Compile Include="packets\receive\AchievementProgressRequestPacket.cs" />
<Compile Include="packets\receive\ChatMessagePacket.cs" /> <Compile Include="packets\receive\ChatMessagePacket.cs" />
<Compile Include="packets\receive\events\EventUpdatePacket.cs" /> <Compile Include="packets\receive\events\EventUpdatePacket.cs" />
<Compile Include="packets\receive\events\EventStartPacket.cs" /> <Compile Include="packets\receive\events\EventStartPacket.cs" />
@ -202,6 +205,7 @@
<Compile Include="packets\receive\HandshakePacket.cs" /> <Compile Include="packets\receive\HandshakePacket.cs" />
<Compile Include="packets\receive\CountdownRequestPacket.cs" /> <Compile Include="packets\receive\CountdownRequestPacket.cs" />
<Compile Include="packets\receive\LangaugeCodePacket.cs" /> <Compile Include="packets\receive\LangaugeCodePacket.cs" />
<Compile Include="packets\receive\UpdateItemPackagePacket.cs" />
<Compile Include="packets\receive\ParameterDataRequestPacket.cs" /> <Compile Include="packets\receive\ParameterDataRequestPacket.cs" />
<Compile Include="packets\receive\recruitment\RecruitmentDetailsRequestPacket.cs" /> <Compile Include="packets\receive\recruitment\RecruitmentDetailsRequestPacket.cs" />
<Compile Include="packets\receive\recruitment\RecruitmentSearchRequestPacket.cs" /> <Compile Include="packets\receive\recruitment\RecruitmentSearchRequestPacket.cs" />
@ -237,9 +241,6 @@
<Compile Include="packets\send\actor\inventory\InventoryRemoveX16Packet.cs" /> <Compile Include="packets\send\actor\inventory\InventoryRemoveX16Packet.cs" />
<Compile Include="packets\send\actor\inventory\InventoryRemoveX32Packet.cs" /> <Compile Include="packets\send\actor\inventory\InventoryRemoveX32Packet.cs" />
<Compile Include="packets\send\actor\inventory\InventoryRemoveX64Packet.cs" /> <Compile Include="packets\send\actor\inventory\InventoryRemoveX64Packet.cs" />
<Compile Include="packets\send\actor\inventory\EquipmentListX64Packet.cs" />
<Compile Include="packets\send\actor\inventory\EquipmentListX32Packet.cs" />
<Compile Include="packets\send\actor\inventory\EquipmentListX16Packet.cs" />
<Compile Include="packets\send\actor\inventory\InventoryListX01Packet.cs" /> <Compile Include="packets\send\actor\inventory\InventoryListX01Packet.cs" />
<Compile Include="packets\send\actor\inventory\InventoryListX08Packet.cs" /> <Compile Include="packets\send\actor\inventory\InventoryListX08Packet.cs" />
<Compile Include="packets\send\actor\inventory\InventoryListX16Packet.cs" /> <Compile Include="packets\send\actor\inventory\InventoryListX16Packet.cs" />
@ -251,14 +252,17 @@
<Compile Include="packets\send\actor\_0x132Packet.cs" /> <Compile Include="packets\send\actor\_0x132Packet.cs" />
<Compile Include="packets\send\actor\SetActorIsZoningPacket.cs" /> <Compile Include="packets\send\actor\SetActorIsZoningPacket.cs" />
<Compile Include="packets\send\actor\battle\CommandResultX01Packet.cs" /> <Compile Include="packets\send\actor\battle\CommandResultX01Packet.cs" />
<Compile Include="packets\send\actor\inventory\EquipmentListX01Packet.cs" /> <Compile Include="packets\send\actor\inventory\LinkedItemListX01Packet.cs" />
<Compile Include="packets\send\actor\inventory\LinkedItemListX08Packet.cs" />
<Compile Include="packets\send\actor\inventory\LinkedItemListX16Packet.cs" />
<Compile Include="packets\send\actor\inventory\LinkedItemListX32Packet.cs" />
<Compile Include="packets\send\actor\inventory\LinkedItemListX64Packet.cs" />
<Compile Include="packets\send\actor\inventory\InventoryBeginChangePacket.cs" /> <Compile Include="packets\send\actor\inventory\InventoryBeginChangePacket.cs" />
<Compile Include="packets\send\actor\inventory\InventoryEndChangePacket.cs" /> <Compile Include="packets\send\actor\inventory\InventoryEndChangePacket.cs" />
<Compile Include="packets\send\actor\inventory\InventoryItemEndPacket.cs" /> <Compile Include="packets\send\actor\inventory\InventoryItemEndPacket.cs" />
<Compile Include="packets\send\actor\inventory\InventoryItemPacket.cs" /> <Compile Include="packets\send\actor\inventory\InventoryItemPacket.cs" />
<Compile Include="packets\send\actor\inventory\InventorySetBeginPacket.cs" /> <Compile Include="packets\send\actor\inventory\InventorySetBeginPacket.cs" />
<Compile Include="packets\send\actor\inventory\InventorySetEndPacket.cs" /> <Compile Include="packets\send\actor\inventory\InventorySetEndPacket.cs" />
<Compile Include="packets\send\actor\inventory\EquipmentListX08Packet.cs" />
<Compile Include="packets\send\actor\RemoveActorPacket.cs" /> <Compile Include="packets\send\actor\RemoveActorPacket.cs" />
<Compile Include="packets\send\actor\SetActorIconPacket.cs" /> <Compile Include="packets\send\actor\SetActorIconPacket.cs" />
<Compile Include="packets\send\actor\SetActorSubStatePacket.cs" /> <Compile Include="packets\send\actor\SetActorSubStatePacket.cs" />
@ -361,6 +365,7 @@
<Compile Include="packets\receive\UpdatePlayerPositionPacket.cs" /> <Compile Include="packets\receive\UpdatePlayerPositionPacket.cs" />
<Compile Include="packets\WorldPackets\Receive\ErrorPacket.cs" /> <Compile Include="packets\WorldPackets\Receive\ErrorPacket.cs" />
<Compile Include="packets\WorldPackets\Receive\PartySyncPacket.cs" /> <Compile Include="packets\WorldPackets\Receive\PartySyncPacket.cs" />
<Compile Include="packets\WorldPackets\Receive\LinkshellResultPacket.cs" />
<Compile Include="packets\WorldPackets\Receive\SessionEndPacket.cs" /> <Compile Include="packets\WorldPackets\Receive\SessionEndPacket.cs" />
<Compile Include="packets\WorldPackets\Receive\SessionBeginPacket.cs" /> <Compile Include="packets\WorldPackets\Receive\SessionBeginPacket.cs" />
<Compile Include="packets\WorldPackets\Send\Group\CreateLinkshellPacket.cs" /> <Compile Include="packets\WorldPackets\Send\Group\CreateLinkshellPacket.cs" />

View file

@ -1,9 +1,6 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using System; using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.receive; using FFXIVClassic_Map_Server.packets.receive;
using FFXIVClassic_Map_Server.packets.send; using FFXIVClassic_Map_Server.packets.send;
@ -88,6 +85,11 @@ namespace FFXIVClassic_Map_Server
PartySyncPacket partySyncPacket = new PartySyncPacket(subpacket.data); PartySyncPacket partySyncPacket = new PartySyncPacket(subpacket.data);
Server.GetWorldManager().PartyMemberListRecieved(partySyncPacket); Server.GetWorldManager().PartyMemberListRecieved(partySyncPacket);
break; break;
//World Server - Linkshell Creation Result
case 0x1025:
LinkshellResultPacket lsResult = new LinkshellResultPacket(subpacket.data);
LuaEngine.GetInstance().OnSignal("ls_result", lsResult.resultCode);
break;
//Ping //Ping
case 0x0001: case 0x0001:
//subpacket.DebugPrintSubPacket(); //subpacket.DebugPrintSubPacket();
@ -176,11 +178,6 @@ namespace FFXIVClassic_Map_Server
Actor ownerActor = Server.GetStaticActors(eventStart.scriptOwnerActorID); Actor ownerActor = Server.GetStaticActors(eventStart.scriptOwnerActorID);
session.GetActor().currentEventOwner = eventStart.scriptOwnerActorID;
session.GetActor().currentEventName = eventStart.triggerName;
if (ownerActor == null) if (ownerActor == null)
{ {
//Is it your retainer? //Is it your retainer?
@ -188,7 +185,7 @@ namespace FFXIVClassic_Map_Server
ownerActor = session.GetActor().currentSpawnedRetainer; ownerActor = session.GetActor().currentSpawnedRetainer;
//Is it a instance actor? //Is it a instance actor?
if (ownerActor == null) if (ownerActor == null)
ownerActor = session.GetActor().zone.FindActorInArea(session.GetActor().currentEventOwner); ownerActor = session.GetActor().zone.FindActorInArea(eventStart.scriptOwnerActorID);
if (ownerActor == null) if (ownerActor == null)
{ {
//Is it a Director? //Is it a Director?
@ -246,11 +243,27 @@ namespace FFXIVClassic_Map_Server
if (paramRequest.paramName.Equals("charaWork/exp")) if (paramRequest.paramName.Equals("charaWork/exp"))
session.GetActor().SendCharaExpInfo(); session.GetActor().SendCharaExpInfo();
break; break;
//Item Package Request
case 0x0131:
UpdateItemPackagePacket packageRequest = new UpdateItemPackagePacket(subpacket.data);
if (Server.GetWorldManager().GetActorInWorld(packageRequest.actorID) != null)
{
((Character)Server.GetWorldManager().GetActorInWorld(packageRequest.actorID)).SendItemPackage(session.GetActor(), packageRequest.packageId);
break;
}
if (session.GetActor().GetSpawnedRetainer() != null && session.GetActor().GetSpawnedRetainer().actorId == packageRequest.actorID)
session.GetActor().GetSpawnedRetainer().SendItemPackage(session.GetActor(), packageRequest.packageId);
break;
//Group Created Confirm //Group Created Confirm
case 0x0133: case 0x0133:
GroupCreatedPacket groupCreated = new GroupCreatedPacket(subpacket.data); GroupCreatedPacket groupCreated = new GroupCreatedPacket(subpacket.data);
Server.GetWorldManager().SendGroupInit(session, groupCreated.groupId); Server.GetWorldManager().SendGroupInit(session, groupCreated.groupId);
break; break;
//Achievement Progress Request
case 0x0135:
AchievementProgressRequestPacket progressRequest = new AchievementProgressRequestPacket(subpacket.data);
session.QueuePacket(Database.GetAchievementProgress(session.GetActor(), progressRequest.achievementId));
break;
/* RECRUITMENT */ /* RECRUITMENT */
//Start Recruiting //Start Recruiting
case 0x01C3: case 0x01C3:

View file

@ -1,15 +1,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Threading;
using System.Text;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using System.Reflection;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic.Common;
using NLog; using NLog;
using NLog.Targets;
using NLog.Targets.Wrappers;
using NLog.Config;
namespace FFXIVClassic_Map_Server namespace FFXIVClassic_Map_Server
{ {

View file

@ -6,7 +6,6 @@ using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
namespace FFXIVClassic_Map_Server namespace FFXIVClassic_Map_Server
{ {

View file

@ -1,30 +1,23 @@
using FFXIVClassic_Map_Server; using FFXIVClassic.Common;
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.area; using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.actors.chara.npc; using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send; using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.login;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.actors.group; using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.WorldPackets.Receive; using FFXIVClassic_Map_Server.packets.WorldPackets.Receive;
using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group; using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group;
using System.Threading; using System.Threading;
using System.Diagnostics;
using FFXIVClassic_Map_Server.actors.director; using FFXIVClassic_Map_Server.actors.director;
using FFXIVClassic_Map_Server.actors.chara.ai; using FFXIVClassic_Map_Server.actors.chara.ai;
using FFXIVClassic_Map_Server.actors.chara; using FFXIVClassic_Map_Server.actors.chara;
using FFXIVClassic_Map_Server.Actors.Chara; using FFXIVClassic_Map_Server.actors.chara.player;
namespace FFXIVClassic_Map_Server namespace FFXIVClassic_Map_Server
{ {
@ -51,9 +44,12 @@ namespace FFXIVClassic_Map_Server
private const int MILIS_LOOPTIME = 333; private const int MILIS_LOOPTIME = 333;
private Timer mZoneTimer; private Timer mZoneTimer;
//Content Groups //Zone Server Groups
public Dictionary<ulong, Group> mContentGroups = new Dictionary<ulong, Group>(); public Dictionary<ulong, Group> mContentGroups = new Dictionary<ulong, Group>();
public Dictionary<ulong, RelationGroup> mRelationGroups = new Dictionary<ulong, RelationGroup>();
public Dictionary<ulong, TradeGroup> mTradeGroups = new Dictionary<ulong, TradeGroup>();
private Object groupLock = new Object(); private Object groupLock = new Object();
private Object tradeLock = new Object();
public ulong groupIndexId = 1; public ulong groupIndexId = 1;
public WorldManager(Server server) public WorldManager(Server server)
@ -1033,8 +1029,6 @@ namespace FFXIVClassic_Map_Server
player.playerSession.LockUpdates(false); player.playerSession.LockUpdates(false);
LuaEngine.GetInstance().CallLuaFunction(player, contentArea, "onZoneIn", true); LuaEngine.GetInstance().CallLuaFunction(player, contentArea, "onZoneIn", true);
} }
@ -1185,6 +1179,484 @@ namespace FFXIVClassic_Map_Server
} }
} }
public RelationGroup CreateRelationGroup(Actor inviter, Actor invitee, ulong groupType)
{
lock (groupLock)
{
groupIndexId = groupIndexId | 0x0000000000000000;
RelationGroup group = new RelationGroup(groupIndexId, inviter.actorId, invitee.actorId, 0, groupType);
mRelationGroups.Add(groupIndexId, group);
groupIndexId++;
group.SendGroupPacketsAll(inviter.actorId, invitee.actorId);
return group;
}
}
public RelationGroup GetRelationGroup(uint actorId)
{
lock (groupLock)
{
foreach (RelationGroup relation in mRelationGroups.Values)
{
if (relation.GetHost() == actorId || relation.GetOther() == actorId)
return relation;
}
return null;
}
}
public void DeleteRelationGroup(ulong groupid)
{
lock (groupLock)
{
if (mRelationGroups.ContainsKey(groupid))
mRelationGroups.Remove(groupid);
}
}
public TradeGroup CreateTradeGroup(Player inviter, Player invitee)
{
//Sanity Checks
if (inviter.Equals(invitee))
{
inviter.SendGameMessage(GetActor(), 25043, 0x20, (object)invitee); //You cannot trade with yourself.
return null;
}
else if (GetTradeGroup(inviter.actorId) != null)
{
inviter.SendGameMessage(GetActor(), 25045, 0x20, (object)invitee); //You may only trade with one person at a time.
return null;
}
else if (GetTradeGroup(invitee.actorId) != null)
{
inviter.SendGameMessage(GetActor(), 25044, 0x20, (object)invitee); //Your target is unable to trade.
return null;
}
//Create a trade group between these two players
lock (groupLock)
{
groupIndexId = groupIndexId | 0x0000000000000000;
TradeGroup group = new TradeGroup(groupIndexId, inviter.actorId, invitee.actorId);
mTradeGroups.Add(groupIndexId, group);
groupIndexId++;
group.SendGroupPacketsAll(inviter.actorId, invitee.actorId);
inviter.SendGameMessage(GetActor(), 25101, 0x20, (object)invitee); //You request to trade with X
invitee.SendGameMessage(GetActor(), 25037, 0x20, (object)inviter); //X wishes to trade with you
return group;
}
}
public TradeGroup GetTradeGroup(uint actorId)
{
lock (groupLock)
{
foreach (TradeGroup group in mTradeGroups.Values)
{
if (group.GetHost() == actorId || group.GetOther() == actorId)
return (TradeGroup)group;
}
return null;
}
}
public void DeleteTradeGroup(ulong groupid)
{
lock (groupLock)
{
if (mTradeGroups.ContainsKey(groupid))
{
TradeGroup group = mTradeGroups[groupid];
group.SendDeletePackets(group.GetHost(), group.GetOther());
mTradeGroups.Remove(groupid);
}
}
}
public void TradeTEST(Player player)
{
player.KickEventSpecial(Server.GetStaticActors("TradeExecuteCommand"), 0, "commandContent", null, null, null, 16, null, null, null, null, null);
}
public void AcceptTrade(Player invitee)
{
TradeGroup group = GetTradeGroup(invitee.actorId);
if (group == null)
{
invitee.SendMessage(0x20, "", "MASSIVE ERROR: No tradegroup found!!!");
return;
}
Player inviter = (Player)invitee.GetZone().FindActorInArea(group.GetHost());
//DeleteTradeGroup(group.groupIndex);
inviter.StartTradeTransaction(invitee);
invitee.StartTradeTransaction(inviter);
inviter.KickEventSpecial(Server.GetStaticActors("TradeExecuteCommand"), 0, "commandContent", null, null, null, 16, null, null, null, null, null);
invitee.KickEventSpecial(Server.GetStaticActors("TradeExecuteCommand"), 0, "commandContent", null, null, null, 16, null, null, null, null, null);
}
public void CancelTradeTooFar(Player inviter)
{
TradeGroup group = GetTradeGroup(inviter.actorId);
if (group == null)
{
inviter.SendMessage(0x20, "", "MASSIVE ERROR: No tradegroup found!!!");
return;
}
Player invitee = (Player)inviter.GetZone().FindActorInArea(group.GetOther());
inviter.SendGameMessage(GetActor(), 25042, 0x20); //You cancel the trade.
if (invitee != null)
invitee.SendGameMessage(GetActor(), 25042, 0x20); //The trade has been canceled.
DeleteTradeGroup(group.groupIndex);
}
public void CancelTrade(Player inviter)
{
TradeGroup group = GetTradeGroup(inviter.actorId);
if (group == null)
{
inviter.SendMessage(0x20, "", "MASSIVE ERROR: No tradegroup found!!!");
return;
}
Player invitee = (Player)inviter.GetZone().FindActorInArea(group.GetOther());
inviter.SendGameMessage(GetActor(), 25041, 0x20); //You cancel the trade.
if (invitee != null)
invitee.SendGameMessage(GetActor(), 25040, 0x20); //The trade has been canceled.
DeleteTradeGroup(group.groupIndex);
}
public void RefuseTrade(Player invitee)
{
TradeGroup group = GetTradeGroup(invitee.actorId);
if (group == null)
{
invitee.SendMessage(0x20, "", "MASSIVE ERROR: No tradegroup found!!!");
return;
}
Player inviter = (Player)invitee.GetZone().FindActorInArea(group.GetHost());
if (inviter != null)
inviter.SendGameMessage(GetActor(), 25038, 0x20); //Your trade request fails
DeleteTradeGroup(group.groupIndex);
}
public void CompleteTrade(Player p1, Player p2)
{
if (!p1.IsTradeAccepted() || !p2.IsTradeAccepted())
return;
TradeGroup group = GetTradeGroup(p1.actorId);
if (group == null)
{
p1.SendMessage(0x20, "", "MASSIVE ERROR: No tradegroup found!!!");
return;
}
ReferencedItemPackage p1Offer = p1.GetTradeOfferings();
ReferencedItemPackage p2Offer = p2.GetTradeOfferings();
int failCode = 0;
Player failurePlayerOffer = null;
Player failureCauser = null;
//TODO Add full inventory check
//Check items. If there is a failcode abort and set.
for (ushort i = 0; i < p1Offer.GetCapacity(); i++)
{
InventoryItem p1ItemToP2 = p1Offer.GetItemAtSlot(i);
InventoryItem p2ItemToP1 = p2Offer.GetItemAtSlot(i);
int failCodeP1 = CheckIfCanTrade(p1, p2, p1ItemToP2); //P2's inv caused a failcode for P1
int failCodeP2 = CheckIfCanTrade(p2, p1, p2ItemToP1); //P1's inv caused a failcode for P2
if (failCodeP1 != 0)
{
failCode = failCodeP1;
failurePlayerOffer = p1;
failureCauser = p2;
break;
}
if (failCodeP2 != 0)
{
failCode = failCodeP2;
failurePlayerOffer = p2;
failureCauser = p1;
break;
}
}
//Do we have a failcode?
switch (failCode)
{
case 1:
failurePlayerOffer.SendGameMessage(GetActor(), 25100, 0x20, (object)failureCauser); //Transaction failed. X inventory is either full or X can only hold one of the selected items.
failureCauser.SendGameMessage(GetActor(), 25100, 0x20, (object)failureCauser); //Transaction failed. X inventory is either full or X can only hold one of the selected items.
break;
case 2:
failurePlayerOffer.SendGameMessage(GetActor(), 25100, 0x20, (object)failureCauser); //Transaction failed. X inventory is either full or X can only hold one of the selected items.
failureCauser.SendGameMessage(GetActor(), 25103, 0x20); //Unable to complete transaction. You can only hold one of the selected items.
break;
case 3:
failurePlayerOffer.SendGameMessage(GetActor(), 25099, 0x20); //Unable to complete transaction.
failureCauser.SendGameMessage(GetActor(), 25104, 0x20); //Unable to complete transaction. You cannot receive the incoming payment.
break;
}
//If all good, perform the swap.
if (failCode == 0)
{
lock (tradeLock)
{
for (ushort i = 0; i < p1Offer.GetCapacity(); i++)
{
InventoryItem p1ItemToP2 = p1Offer.GetItemAtSlot(i);
InventoryItem p2ItemToP1 = p2Offer.GetItemAtSlot(i);
//Transfer P1 -> P2
if (p1ItemToP2 != null)
{
/*
if (p1ItemToP2.GetItemData().maxStack > 1)
{
p1.GetItemPackage(p1ItemToP2.itemPackage).RemoveItem(p1ItemToP2.itemId, p1ItemToP2.GetTradeQuantity(), p1ItemToP2.quality);
p2.GetItemPackage(p1ItemToP2.itemPackage).AddItem(p1ItemToP2.itemId, p1ItemToP2.GetTradeQuantity(), p1ItemToP2.quality);
}
else
{
p1.GetItemPackage(p1ItemToP2.itemPackage).RemoveItem(p1ItemToP2);
p2.GetItemPackage(p1ItemToP2.itemPackage).AddItem(p1ItemToP2);
}
*/
}
//Transfer P2 -> P1
if (p2ItemToP1 != null)
{
/*
if (p2ItemToP1.GetItemData().maxStack > 1)
{
p2.GetItemPackage(p2ItemToP1.itemPackage).RemoveItem(p2ItemToP1.itemId, p2ItemToP1.GetTradeQuantity(), p2ItemToP1.quality);
p1.GetItemPackage(p2ItemToP1.itemPackage).AddItem(p2ItemToP1.itemId, p2ItemToP1.GetTradeQuantity(), p2ItemToP1.quality);
}
else
{
p2.GetItemPackage(p2ItemToP1.itemPackage).RemoveItem(p2ItemToP1);
p1.GetItemPackage(p2ItemToP1.itemPackage).AddItem(p2ItemToP1);
}
*/
}
}
}
p1.SendGameMessage(GetActor(), 25039, 0x20); //The trade is complete.
p2.SendGameMessage(GetActor(), 25039, 0x20); //The trade is complete.
}
//Cleanup the trade and delete the tradegroup.
p1.FinishTradeTransaction();
p2.FinishTradeTransaction();
DeleteTradeGroup(group.groupIndex);
}
private int CheckIfCanTrade(Player itemOwner, Player itemReceiver, InventoryItem item)
{
if (item == null)
return 0;
//Check if their inventory can't hold all these things
if (false)
{
return 1;
}
//Check if they already have a unique
else if (item.GetItemData().isRare && itemReceiver.HasItem(item.itemId))
{
return 2;
}
//Check if gil is max
else if (item.itemId == 100001 && item.dealingAttached3 + itemReceiver.GetCurrentGil() > item.GetItemData().maxStack)
{
return 3;
}
return 0;
}
public InventoryItem CreateItem(uint itemId, int amount, byte quality = 1, InventoryItem.ItemModifier modifiers = null)
{
return Database.CreateItem(itemId, amount, quality, modifiers);
}
public bool BazaarBuyOperation(Player bazaar, Player buyer, InventoryItem itemToBuy, int quantity, int cost)
{
if (bazaar == null || buyer == null || itemToBuy == null)
return false;
if (quantity <= 0)
return false;
if (cost < 0)
return false;
if (itemToBuy.GetBazaarMode() == InventoryItem.TYPE_SINGLE || itemToBuy.GetBazaarMode() == InventoryItem.TYPE_MULTI || itemToBuy.GetBazaarMode() == InventoryItem.TYPE_STACK)
{
itemToBuy.ChangeQuantity(-quantity);
buyer.AddItem(itemToBuy.itemId, quantity, itemToBuy.quality);
buyer.GetItemPackage(ItemPackage.CURRENCY_CRYSTALS).RemoveItem(1000001, cost);
}
if (itemToBuy.quantity == 0)
Database.ClearBazaarEntry(bazaar, itemToBuy);
bazaar.CheckBazaarFlags();
return true;
}
public bool BazaarSellOperation(Player bazaar, Player buyer, InventoryItem reward, int rewardQuantity, InventoryItem seek, int seekQuantity)
{
if (bazaar == null || buyer == null || reward == null || seek == null)
return false;
if (rewardQuantity <= 0 || seekQuantity <= 0)
return false;
if (reward.GetBazaarMode() == InventoryItem.TYPE_SEEK_ITEM)
{
InventoryItem seekBazaar = bazaar.GetItemPackage(ItemPackage.BAZAAR).GetItemAttachedTo(reward);
bazaar.RemoveItem(reward, rewardQuantity);
bazaar.RemoveItem(seekBazaar, seekQuantity);
bazaar.AddItem(seekBazaar);
bazaar.AddItem(seek.itemId, seekQuantity, seek.quality);
buyer.RemoveItem(seek, seekQuantity);
buyer.AddItem(reward);
}
Database.ClearBazaarEntry(bazaar, reward);
bazaar.CheckBazaarFlags();
return true;
}
public void AddToBazaar(Player player, InventoryItem reward, InventoryItem seek, int rewardAmount, int seekAmount, byte bazaarMode)
{
bool succ = false;
if (bazaarMode == InventoryItem.TYPE_SINGLE || bazaarMode == InventoryItem.TYPE_MULTI || bazaarMode == InventoryItem.TYPE_STACK)
succ = Database.CreateBazaarEntry(player, reward, seek, rewardAmount, 0, bazaarMode, seekAmount);
else
succ = Database.CreateBazaarEntry(player, reward, seek, rewardAmount, seekAmount, bazaarMode);
if (succ)
{
if (bazaarMode != InventoryItem.TYPE_SINGLE && bazaarMode != InventoryItem.TYPE_MULTI && bazaarMode != InventoryItem.TYPE_STACK)
{
reward.SetDealingAttached(bazaarMode, seek.uniqueId);
seek.SetHasAttached(true);
player.GetItemPackage(ItemPackage.BAZAAR).StartSendUpdate();
player.GetItemPackage(ItemPackage.BAZAAR).AddItem(reward);
player.GetItemPackage(ItemPackage.BAZAAR).AddItem(seek);
reward.SetAttachedIndex(ItemPackage.BAZAAR, seek.slot);
player.GetItemPackage(ItemPackage.BAZAAR).DoneSendUpdate();
}
else
{
reward.SetDealing(bazaarMode, seekAmount);
player.GetItemPackage(ItemPackage.BAZAAR).StartSendUpdate();
player.GetItemPackage(ItemPackage.BAZAAR).AddItem(reward);
player.GetItemPackage(ItemPackage.BAZAAR).DoneSendUpdate();
}
}
player.CheckBazaarFlags();
}
public void RemoveFromBazaar(Player player, InventoryItem rewardRef)
{
ushort attachedItemPackage = (ushort)((rewardRef.dealingAttached1 >> 16) & 0xFF);
ushort attachedSlot = (ushort) (rewardRef.dealingAttached1 & 0xFF);
InventoryItem seekRef = rewardRef.IsSelling() ? null : player.GetItemPackage(attachedItemPackage).GetItemAtSlot(attachedSlot);
Database.ClearBazaarEntry(player, rewardRef);
player.GetItemPackage(ItemPackage.BAZAAR).RemoveItem(rewardRef);
bool isSelling = rewardRef.IsSelling();
rewardRef.SetNormal();
if (seekRef != null)
player.GetItemPackage(ItemPackage.BAZAAR).RemoveItem(seekRef);
player.AddItem(rewardRef);
if (!isSelling)
{
seekRef.SetNormal();
player.AddItem(seekRef);
}
player.CheckBazaarFlags();
}
/*
public void TransactionBazaar(Player owner, Player other, InventoryItem reward, InventoryItem seek, int rewardAmount, int seekAmount)
{
Database.ClearBazaarEntry(owner, reward, seek);
//Remove Bazaar Items from owner
owner.GetInventory(Inventory.BAZAAR).RemoveItem(reward);
owner.GetInventory(Inventory.BAZAAR).RemoveItem(seek);
//Remove Seek item from other
if (seek.GetItemData().IsMoney())
other.GetInventory(Inventory.CURRENCY_CRYSTALS).RemoveItem(seek.itemId, seekAmount);
else
other.GetInventory(Inventory.NORMAL).RemoveItem(seek.itemId, seekAmount);
//Add reward to other, seek to owner
if (reward.GetItemData().IsMoney())
other.GetInventory(Inventory.CURRENCY_CRYSTALS).AddItem(reward.itemId, rewardAmount);
else
other.GetInventory(Inventory.NORMAL).AddItem(reward);
if (seek.GetItemData().IsMoney())
owner.GetInventory(Inventory.CURRENCY_CRYSTALS).AddItem(seek.itemId, seekAmount);
else
other.GetInventory(Inventory.NORMAL).AddItem(seek);
}*/
public bool SendGroupInit(Session session, ulong groupId) public bool SendGroupInit(Session session, ulong groupId)
{ {
if (mContentGroups.ContainsKey(groupId)) if (mContentGroups.ContainsKey(groupId))
@ -1192,6 +1664,11 @@ namespace FFXIVClassic_Map_Server
mContentGroups[groupId].SendInitWorkValues(session); mContentGroups[groupId].SendInitWorkValues(session);
return true; return true;
} }
else if (mTradeGroups.ContainsKey(groupId))
{
mTradeGroups[groupId].SendInitWorkValues(session);
return true;
}
return false; return false;
} }

View file

@ -9,8 +9,6 @@ using System.Collections.Generic;
using FFXIVClassic_Map_Server.actors.area; using FFXIVClassic_Map_Server.actors.area;
using System.Reflection; using System.Reflection;
using System.ComponentModel; using System.ComponentModel;
using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.actors.chara; using FFXIVClassic_Map_Server.actors.chara;
namespace FFXIVClassic_Map_Server.Actors namespace FFXIVClassic_Map_Server.Actors

View file

@ -1,5 +1,4 @@
using FFXIVClassic_Map_Server; using FFXIVClassic.Common;
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.area; using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.actors.chara.npc; using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;

View file

@ -3,11 +3,7 @@ using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.area namespace FFXIVClassic_Map_Server.actors.area
{ {

View file

@ -1,12 +1,7 @@
using FFXIVClassic_Map_Server.actors.director; using FFXIVClassic_Map_Server.actors.director;
using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.area namespace FFXIVClassic_Map_Server.actors.area
{ {

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.area
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.area
{ {
class SpawnLocation class SpawnLocation
{ {

View file

@ -1,17 +1,9 @@
using FFXIVClassic_Map_Server; using FFXIVClassic.Common;
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using FFXIVClassic_Map_Server.actors.director; using FFXIVClassic_Map_Server.actors.director;
namespace FFXIVClassic_Map_Server.actors.area namespace FFXIVClassic_Map_Server.actors.area

View file

@ -1,16 +1,17 @@
 
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.area; using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.actors.group; using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.Actors.Chara; using FFXIVClassic_Map_Server.Actors.Chara;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using FFXIVClassic_Map_Server.utils; using FFXIVClassic_Map_Server.utils;
using FFXIVClassic_Map_Server.actors.chara.ai; using FFXIVClassic_Map_Server.actors.chara.ai;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using FFXIVClassic_Map_Server.actors.chara; using FFXIVClassic_Map_Server.actors.chara;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.actors.chara.ai.state; using FFXIVClassic_Map_Server.actors.chara.ai.state;
using FFXIVClassic_Map_Server.actors.chara.ai.utils; using FFXIVClassic_Map_Server.actors.chara.ai.utils;
using FFXIVClassic_Map_Server.actors.chara.npc; using FFXIVClassic_Map_Server.actors.chara.npc;
@ -132,7 +133,12 @@ namespace FFXIVClassic_Map_Server.Actors
protected Dictionary<string, UInt64> tempVars = new Dictionary<string, UInt64>(); protected Dictionary<string, UInt64> tempVars = new Dictionary<string, UInt64>();
public Character(uint actorID) : base(actorID) //Inventory
protected Dictionary<ushort, ItemPackage> itemPackages = new Dictionary<ushort, ItemPackage>();
protected ReferencedItemPackage equipment;
public Character(uint actorID)
: base(actorID)
{ {
//Init timer array to "notimer" //Init timer array to "notimer"
for (int i = 0; i < charaWork.statusShownTime.Length; i++) for (int i = 0; i < charaWork.statusShownTime.Length; i++)
@ -1154,5 +1160,180 @@ namespace FFXIVClassic_Map_Server.Actors
targetFind.FindWithinArea(this, ValidTarget.Party, TargetFindAOETarget.Self); targetFind.FindWithinArea(this, ValidTarget.Party, TargetFindAOETarget.Self);
return targetFind.GetTargets(); return targetFind.GetTargets();
} }
#region Inventory
public void SendItemPackage(Player player, uint id)
{
if (!itemPackages.ContainsKey((ushort)id))
return;
player.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
itemPackages[(ushort)id].SendUpdate(player);
player.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
}
public void AddItem(uint catalogID)
{
AddItem(catalogID, 1);
}
public void AddItem(uint catalogID, int quantity)
{
AddItem(catalogID, quantity, 1);
}
public void AddItem(uint catalogID, int quantity, byte quality)
{
ushort itemPackage = GetPackageForItem(catalogID);
if (itemPackages.ContainsKey(itemPackage))
{
itemPackages[itemPackage].AddItem(catalogID, quantity, quality);
}
}
public void AddItem(InventoryItem item)
{
ushort itemPackage = GetPackageForItem(item.GetItemData().catalogID);
if (itemPackages.ContainsKey(itemPackage))
{
itemPackages[itemPackage].AddItem(item);
}
}
public void SetItem(InventoryItem item, ushort itemPackage, ushort slot)
{
if (itemPackages.ContainsKey(itemPackage))
{
itemPackages[itemPackage].SetItem(slot, item);
}
}
public void MoveItem(InventoryItem item, ushort destinationPackage)
{
ushort sourcePackage = item.itemPackage;
if (!itemPackages.ContainsKey(sourcePackage) && !itemPackages.ContainsKey(destinationPackage))
return;
itemPackages[sourcePackage].RemoveItem(item);
itemPackages[destinationPackage].AddItem(item);
}
public void RemoveItem(uint catalogID)
{
RemoveItem(catalogID, 1);
}
public void RemoveItem(uint catalogID, int quantity)
{
RemoveItem(catalogID, quantity, 1);
}
public void RemoveItem(uint catalogID, int quantity, byte quality)
{
ushort itemPackage = GetPackageForItem(catalogID);
if (itemPackages.ContainsKey(itemPackage))
{
itemPackages[itemPackage].RemoveItem(catalogID, quantity, quality);
}
}
public void RemoveItemAtSlot(ushort itemPackage, ushort slot)
{
if (itemPackages.ContainsKey(itemPackage))
{
itemPackages[itemPackage].RemoveItemAtSlot(slot);
}
}
public void RemoveItem(InventoryItem item)
{
RemoveItem(item, 1);
}
public void RemoveItem(InventoryItem item, int quantity)
{
if (itemPackages.ContainsKey(item.itemPackage))
{
itemPackages[item.itemPackage].RemoveItem(item, quantity);
}
}
public bool HasItem(uint catalogID)
{
return HasItem(catalogID, 1);
}
public bool HasItem(uint catalogID, int minQuantity)
{
return HasItem(catalogID, minQuantity, 1);
}
public bool HasItem(uint catalogID, int minQuantity, byte quality)
{
ushort itemPackage = GetPackageForItem(catalogID);
if (itemPackages.ContainsKey(itemPackage))
{
return itemPackages[itemPackage].HasItem(catalogID, minQuantity, quality);
}
return false;
}
public bool HasItem(InventoryItem item)
{
ushort itemPackage = GetPackageForItem(item.GetItemData().catalogID);
if (itemPackages.ContainsKey(itemPackage))
{
//return itemPackages[itemPackage].HasItem(item);
return false; //TODO FIX
}
else
return false;
}
public InventoryItem GetItem(LuaUtils.ItemRefParam reference)
{
if (reference.actorId != actorId)
return null;
if (itemPackages.ContainsKey(reference.itemPackage))
{
return itemPackages[reference.itemPackage].GetItemAtSlot(reference.slot);
}
return null;
}
public ItemPackage GetItemPackage(ushort package)
{
if (itemPackages.ContainsKey(package))
return itemPackages[package];
else
return null;
}
public ushort GetPackageForItem(uint catalogID)
{
ItemData data = Server.GetItemGamedata(catalogID);
if (data == null)
return ItemPackage.NORMAL;
else
{
if (data.IsMoney())
return ItemPackage.CURRENCY_CRYSTALS;
else if (data.IsImportant())
return ItemPackage.KEYITEMS;
else
return ItemPackage.NORMAL;
}
}
//public void removeItem(byUniqueId)
//public void removeItem(byUniqueId, quantity)
//public void removeItem(slot)
//public void removeItem(slot, quantity)
#endregion
} }
} }

View file

@ -6,43 +6,52 @@ using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
namespace FFXIVClassic_Map_Server.actors.chara.player namespace FFXIVClassic_Map_Server.actors.chara.player
{ {
class Inventory class ItemPackage
{ {
public const ushort NORMAL = 0; //Max 0xC8 public const ushort NORMAL = 0; //Max 0xC8
public const ushort TRADE = 1; //Max 0x96 public const ushort UNKNOWN = 1; //Max 0x96
public const ushort LOOT = 4; //Max 0xA public const ushort LOOT = 4; //Max 0xA
public const ushort MELDREQUEST = 5; //Max 0x04 public const ushort MELDREQUEST = 5; //Max 0x04
public const ushort BAZAAR = 7; //Max 0x0A public const ushort BAZAAR = 7; //Max 0x0A
public const ushort CURRENCY_CRYSTALS = 99; //Max 0x140 public const ushort CURRENCY_CRYSTALS = 99; //Max 0x140
public const ushort KEYITEMS = 100; //Max 0x500 public const ushort KEYITEMS = 100; //Max 0x500
public const ushort EQUIPMENT = 0x00FE; //Max 0x23 public const ushort EQUIPMENT = 0x00FE; //Max 0x23
public const ushort TRADE = 0x00FD; //Max 0x04
public const ushort EQUIPMENT_OTHERPLAYER = 0x00F9; //Max 0x23 public const ushort EQUIPMENT_OTHERPLAYER = 0x00F9; //Max 0x23
public enum INV_ERROR { public const ushort MAXSIZE_NORMAL = 200;
SUCCESS = 0, public const ushort MAXSIZE_CURRANCY = 320;
INVENTORY_FULL, public const ushort MAXSIZE_KEYITEMS = 500;
ALREADY_HAS_UNIQUE, public const ushort MAXSIZE_LOOT = 10;
SYSTEM_ERROR public const ushort MAXSIZE_TRADE = 4;
}; public const ushort MAXSIZE_MELDREQUEST = 4;
public const ushort MAXSIZE_BAZAAR = 10;
public const ushort MAXSIZE_EQUIPMENT = 35;
public const ushort MAXSIZE_EQUIPMENT_OTHERPLAYER = 0x23;
public const int ERROR_SUCCESS = 0;
public const int ERROR_FULL = 1;
public const int ERROR_HAS_UNIQUE = 2;
public const int ERROR_SYSTEM = 3;
private Character owner; private Character owner;
private ushort inventoryCapacity; private ushort itemPackageCapacity;
private ushort inventoryCode; private ushort itemPackageCode;
private bool isTemporary; private bool isTemporary;
private InventoryItem[] list; private InventoryItem[] list;
private bool[] isDirty; private bool[] isDirty;
private bool holdingUpdates = false;
private int endOfListIndex = 0; private int endOfListIndex = 0;
public Inventory(Character ownerPlayer, ushort capacity, ushort code, bool temporary = false) public ItemPackage(Character ownerPlayer, ushort capacity, ushort code, bool temporary = false)
{ {
owner = ownerPlayer; owner = ownerPlayer;
inventoryCapacity = capacity; itemPackageCapacity = capacity;
inventoryCode = code; itemPackageCode = code;
isTemporary = temporary; isTemporary = temporary;
list = new InventoryItem[capacity]; list = new InventoryItem[capacity];
isDirty = new bool[capacity]; isDirty = new bool[capacity];
@ -53,7 +62,10 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
{ {
int i = 0; int i = 0;
foreach (InventoryItem item in itemsFromDB) foreach (InventoryItem item in itemsFromDB)
{
item.RefreshPositioning(owner, itemPackageCode, (ushort) i);
list[i++] = item; list[i++] = item;
}
endOfListIndex = i; endOfListIndex = i;
} }
@ -93,56 +105,193 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
return null; return null;
} }
public InventoryItem GetItemAttachedTo(InventoryItem attachedTo)
public int GetItemQuantity(uint itemId)
{ {
return GetItemQuantity(itemId, 1); for (int i = 0; i < endOfListIndex; i++)
}
public int GetItemQuantity(uint itemId, uint quality)
{
int count = 0;
for (int i = endOfListIndex - 1; i >= 0; i--)
{ {
InventoryItem item = list[i]; InventoryItem item = list[i];
if (item.itemId == itemId && item.quality == quality) Debug.Assert(item != null, "Item slot was null!!!");
count += item.quantity;
if (attachedTo.GetAttached() == item.uniqueId)
return item;
} }
return null;
return count;
} }
public int AddItem(uint itemId) public int AddItem(uint itemId)
{ {
return AddItem(itemId, 1, 1); return AddItem(itemId, 1, 1);
} }
public void AddItem(uint[] itemId)
{
for (int i = 0; i < itemId.Length; i++)
AddItem(itemId[i]);
}
public int AddItem(uint itemId, int quantity) public int AddItem(uint itemId, int quantity)
{ {
return AddItem(itemId, quantity, 1); return AddItem(itemId, quantity, 1);
} }
public int AddItems(uint[] itemIds, uint[] quantity = null, byte[] quality = null)
{
//Check if has space
if (!CanAdd(itemIds, quantity, quality))
return ERROR_FULL;
for (int i = 0; i < itemIds.Length; i++)
{
ItemData gItem = Server.GetItemGamedata(itemIds[i]);
//If it's unique, abort
if (HasItem(itemIds[i]) && gItem.isExclusive)
return ERROR_HAS_UNIQUE;
if (gItem == null)
{
Program.Log.Error("Inventory.AddItem: unable to find item %u", itemIds[i]);
return ERROR_SYSTEM;
}
//Check if item id exists
uint setQuantity = quantity != null ? quantity[i] : 1;
int quantityCount = (int)setQuantity;
for (int j = 0; j < endOfListIndex; j++)
{
InventoryItem item = list[j];
Debug.Assert(item != null, "Item slot was null!!!");
byte setQuality = quality != null ? quality[i] : (byte)1;
if (item.itemId == itemIds[i] && item.quality == setQuality && item.quantity < gItem.maxStack)
{
int oldQuantity = item.quantity;
item.quantity = Math.Min(item.quantity + quantityCount, gItem.maxStack);
isDirty[j] = true;
quantityCount -= (gItem.maxStack - oldQuantity);
DoDatabaseQuantity(item.uniqueId, item.quantity);
if (quantityCount <= 0)
break;
}
}
//New item that spilled over
while (quantityCount > 0)
{
InventoryItem.ItemModifier modifiers = null;
if (gItem.durability != 0)
{
modifiers = new InventoryItem.ItemModifier();
modifiers.durability = (uint)gItem.durability;
}
byte setQuality = quality != null ? quality[i] : (byte)1;
InventoryItem addedItem = Database.CreateItem(itemIds[i], Math.Min(quantityCount, gItem.maxStack), setQuality, modifiers);
addedItem.RefreshPositioning(owner, itemPackageCode, (ushort)endOfListIndex);
isDirty[endOfListIndex] = true;
list[endOfListIndex++] = addedItem;
quantityCount -= gItem.maxStack;
DoDatabaseAdd(addedItem);
}
}
if (owner is Player)
{
(owner as Player).QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendUpdate();
(owner as Player).QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
return ERROR_SUCCESS;
}
public bool CanAdd(uint[] itemIds, uint[] quantity, byte[] quality)
{
int tempInvSize = GetCount();
for (int i = 0; i < itemIds.Length; i++)
{
ItemData gItem = Server.GetItemGamedata(itemIds[i]);
//Check if item id exists and fill up til maxstack
int quantityCount = (int) (quantity != null ? quantity[i] : 1);
for (int j = 0; j < endOfListIndex; j++)
{
InventoryItem item = list[j];
Debug.Assert(item != null, "Item slot was null!!!");
if (item.itemId == itemIds[i] && item.quality == (quality != null ? quality[i] : 1) && item.quantity < gItem.maxStack)
{
quantityCount -= (gItem.maxStack - item.quantity);
if (quantityCount <= 0)
break;
}
}
//New items that spilled over creating new stacks
while (quantityCount > 0)
{
quantityCount -= gItem.maxStack;
tempInvSize++;
}
//If the new stacks push us over capacity, can't add these items
if (tempInvSize > itemPackageCapacity)
return false;
}
return true;
}
public int AddItem(InventoryItem itemRef)
{
//If it isn't a single item (ie: armor) just add like normal (not valid for BAZAAR)
if (itemPackageCode != BAZAAR && itemRef.GetItemData().maxStack > 1)
return AddItem(itemRef.itemId, itemRef.quantity, itemRef.quality);
if (!IsSpaceForAdd(itemRef.itemId, itemRef.quantity, itemRef.quality))
return ERROR_FULL;
ItemData gItem = Server.GetItemGamedata(itemRef.itemId);
if (gItem == null)
{
Program.Log.Error("Inventory.AddItem: unable to find item %u", itemRef.itemId);
return ERROR_SYSTEM;
}
itemRef.RefreshPositioning(owner, itemPackageCode, (ushort)endOfListIndex);
isDirty[endOfListIndex] = true;
list[endOfListIndex++] = itemRef;
DoDatabaseAdd(itemRef);
if (owner is Player)
{
(owner as Player).QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendUpdate();
(owner as Player).QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
return ERROR_SUCCESS;
}
public int AddItem(uint itemId, int quantity, byte quality) public int AddItem(uint itemId, int quantity, byte quality)
{ {
if (!IsSpaceForAdd(itemId, quantity, quality)) if (!IsSpaceForAdd(itemId, quantity, quality))
return (int)INV_ERROR.INVENTORY_FULL; return ERROR_FULL;
ItemData gItem = Server.GetItemGamedata(itemId); ItemData gItem = Server.GetItemGamedata(itemId);
//If it's unique, abort
if (HasItem(itemId) && gItem.isExclusive)
return ERROR_HAS_UNIQUE;
if (gItem == null) if (gItem == null)
{ {
Program.Log.Error("Inventory.AddItem: unable to find item %u", itemId); Program.Log.Error("Inventory.AddItem: unable to find item %u", itemId);
return (int)INV_ERROR.SYSTEM_ERROR; return ERROR_SYSTEM;
} }
//Check if item id exists //Check if item id exists
@ -167,15 +316,18 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
} }
} }
//If it's unique, abort
if (HasItem(itemId) && gItem.isRare)
return (int)INV_ERROR.ALREADY_HAS_UNIQUE;
//New item that spilled over //New item that spilled over
while (quantityCount > 0) while (quantityCount > 0)
{ {
InventoryItem addedItem = Database.CreateItem(itemId, Math.Min(quantityCount, gItem.maxStack), quality, gItem.isExclusive ? (byte)0x3 : (byte)0x0, gItem.durability); InventoryItem.ItemModifier modifiers = null;
addedItem.slot = (ushort)endOfListIndex; if (gItem.durability != 0)
{
modifiers = new InventoryItem.ItemModifier();
modifiers.durability = (uint)gItem.durability;
}
InventoryItem addedItem = Database.CreateItem(itemId, Math.Min(quantityCount, gItem.maxStack), quality, modifiers);
addedItem.RefreshPositioning(owner, itemPackageCode, (ushort)endOfListIndex);
isDirty[endOfListIndex] = true; isDirty[endOfListIndex] = true;
list[endOfListIndex++] = addedItem; list[endOfListIndex++] = addedItem;
quantityCount -= gItem.maxStack; quantityCount -= gItem.maxStack;
@ -183,9 +335,26 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
DoDatabaseAdd(addedItem); DoDatabaseAdd(addedItem);
} }
SendUpdatePackets(); if (owner is Player)
{
(owner as Player).QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendUpdate();
(owner as Player).QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
return (int)INV_ERROR.SUCCESS; return ERROR_SUCCESS;
}
public void SetItem(ushort slot, InventoryItem item)
{
list[slot] = item;
if (owner is Player)
{
(owner as Player).QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendUpdate();
(owner as Player).QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
item.RefreshPositioning(owner, itemPackageCode, slot);
} }
public void RemoveItem(uint itemId) public void RemoveItem(uint itemId)
@ -230,8 +399,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
else else
{ {
item.quantity -= quantityCount; item.quantity -= quantityCount;
DoDatabaseQuantity(list[i].uniqueId, list[i].quantity); DoDatabaseQuantity(list[i].uniqueId, list[i].quantity);}
}
isDirty[i] = true; isDirty[i] = true;
@ -244,14 +412,30 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
} }
DoRealign(); DoRealign();
SendUpdatePackets();
if (owner is Player)
{
(owner as Player).QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendUpdate();
(owner as Player).QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
} }
public void RemoveItemByUniqueId(ulong itemDBId) public void RemoveItem(InventoryItem item)
{
RemoveItemByUniqueId(item.uniqueId, item.quantity);
}
public void RemoveItem(InventoryItem item, int quantity)
{
RemoveItemByUniqueId(item.uniqueId, quantity);
}
public void RemoveItemByUniqueId(ulong itemDBId, int quantity)
{ {
ushort slot = 0; ushort slot = 0;
InventoryItem toDelete = null; InventoryItem toDelete = null;
for (int i = endOfListIndex - 1; i >= 0; i--) for (int i = 0; i < endOfListIndex; i++)
{ {
InventoryItem item = list[i]; InventoryItem item = list[i];
@ -268,13 +452,28 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
if (toDelete == null) if (toDelete == null)
return; return;
DoDatabaseRemove(toDelete.uniqueId); if (quantity >= toDelete.quantity)
{
DoDatabaseRemove(toDelete.uniqueId);
list[slot].RefreshPositioning(null, 0xFFFF, 0xFFFF);
list[slot] = null;
}
else
{
list[slot].quantity -= quantity;
DoDatabaseQuantity(list[slot].uniqueId, list[slot].quantity);
}
list[slot] = null;
isDirty[slot] = true; isDirty[slot] = true;
DoRealign(); DoRealign();
SendUpdatePackets();
if (owner is Player)
{
(owner as Player).QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendUpdate();
(owner as Player).QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
} }
public void RemoveItemAtSlot(ushort slot) public void RemoveItemAtSlot(ushort slot)
@ -284,11 +483,18 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
DoDatabaseRemove(list[slot].uniqueId); DoDatabaseRemove(list[slot].uniqueId);
list[slot].RefreshPositioning(null, 0xFFFF, 0xFFFF);
list[slot] = null; list[slot] = null;
isDirty[slot] = true; isDirty[slot] = true;
DoRealign(); DoRealign();
SendUpdatePackets();
if (owner is Player)
{
(owner as Player).QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendUpdate();
(owner as Player).QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
} }
public void RemoveItemAtSlot(ushort slot, int quantity) public void RemoveItemAtSlot(ushort slot, int quantity)
@ -304,6 +510,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
{ {
DoDatabaseRemove(list[slot].uniqueId); DoDatabaseRemove(list[slot].uniqueId);
list[slot].RefreshPositioning(null, 0xFFFF, 0xFFFF);
list[slot] = null; list[slot] = null;
DoRealign(); DoRealign();
} }
@ -311,10 +518,52 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
DoDatabaseQuantity(list[slot].uniqueId, list[slot].quantity); DoDatabaseQuantity(list[slot].uniqueId, list[slot].quantity);
isDirty[slot] = true; isDirty[slot] = true;
SendUpdatePackets();
if (owner is Player)
{
(owner as Player).QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendUpdate();
(owner as Player).QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
} }
} }
public void Clear()
{
for (int i = 0; i < endOfListIndex; i++)
{
list[i].RefreshPositioning(null, 0xFFFF, 0xFFFF);
list[i] = null;
isDirty[i] = true;
}
endOfListIndex = 0;
if (owner is Player)
{
(owner as Player).QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendUpdate();
(owner as Player).QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
}
public void MarkDirty(InventoryItem item)
{
if (item.itemPackage != itemPackageCode || list[item.slot] == null)
return;
isDirty[item.slot] = true;
}
public void MarkDirty(ushort slot)
{
isDirty[slot] = true;
}
public InventoryItem[] GetRawList()
{
return list;
}
public void ChangeDurability(uint slot, uint durabilityChange) public void ChangeDurability(uint slot, uint durabilityChange)
{ {
isDirty[slot] = true; isDirty[slot] = true;
@ -332,19 +581,61 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
#endregion #endregion
#region Packet Functions #region Packet Functions
public void SendFullInventory(Player player) public void SendFullPackage(Player player)
{ {
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode)); player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
SendInventoryPackets(player, 0); SendItemPackets(player, 0);
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
} }
private void SendInventoryPackets(Player player, InventoryItem item) public void SendUpdate()
{ {
player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, item)); if (owner is Player && !holdingUpdates)
{
SendUpdate((Player)owner);
}
} }
private void SendInventoryPackets(Player player, List<InventoryItem> items) public void SendUpdate(Player player)
{
List<InventoryItem> items = new List<InventoryItem>();
List<ushort> slotsToRemove = new List<ushort>();
for (int i = 0; i < list.Length; i++)
{
if (i == endOfListIndex)
break;
if (isDirty[i])
items.Add(list[i]);
}
for (int i = endOfListIndex; i < list.Length; i++)
{
if (isDirty[i])
slotsToRemove.Add((ushort)i);
}
if (!holdingUpdates)
Array.Clear(isDirty, 0, isDirty.Length);
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
//Send Updated Slots
SendItemPackets(player, items);
//Send Remove packets for tail end
SendItemPackets(player, slotsToRemove);
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
//If player is updating their normal inventory, we need to send
//an equip update as well to resync the slots.
if (player.Equals(owner) && itemPackageCode == NORMAL)
player.GetEquipment().SendUpdate();
}
private void SendItemPackets(Player player, InventoryItem item)
{
player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, item));
}
private void SendItemPackets(Player player, List<InventoryItem> items)
{ {
int currentIndex = 0; int currentIndex = 0;
@ -366,10 +657,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
else else
break; break;
} }
} }
private void SendInventoryPackets(Player player, int startOffset) private void SendItemPackets(Player player, int startOffset)
{ {
int currentIndex = startOffset; int currentIndex = startOffset;
@ -395,15 +685,14 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
else else
break; break;
} }
} }
private void SendInventoryRemovePackets(Player player, ushort index) private void SendItemPackets(Player player, ushort index)
{ {
player.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, index)); player.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, index));
} }
private void SendInventoryRemovePackets(Player player, List<ushort> indexes) private void SendItemPackets(Player player, List<ushort> indexes)
{ {
int currentIndex = 0; int currentIndex = 0;
@ -425,30 +714,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
else else
break; break;
} }
} }
public void RefreshItem(Player player, InventoryItem item)
{
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendInventoryPackets(player, item);
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void RefreshItem(Player player, params InventoryItem[] items)
{
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendInventoryPackets(player, items.ToList());
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void RefreshItem(Player player, List<InventoryItem> items)
{
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendInventoryPackets(player, items);
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
#endregion #endregion
#region Automatic Client and DB Updating #region Automatic Client and DB Updating
@ -458,10 +724,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
if (isTemporary) if (isTemporary)
return; return;
if (itemPackageCode == BAZAAR)
return;
if (owner is Player) if (owner is Player)
Database.AddItem((Player)owner, addedItem, inventoryCode); Database.AddItem((Player)owner, addedItem, itemPackageCode);
else if (owner is Retainer) else if (owner is Retainer)
Database.AddItem((Retainer)owner, addedItem, inventoryCode); Database.AddItem((Retainer)owner, addedItem, itemPackageCode);
} }
private void DoDatabaseQuantity(ulong itemDBId, int quantity) private void DoDatabaseQuantity(ulong itemDBId, int quantity)
@ -469,10 +738,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
if (isTemporary) if (isTemporary)
return; return;
if (owner is Player)
Database.SetQuantity((Player)owner, itemDBId, inventoryCode); if (itemPackageCode == BAZAAR)
else if (owner is Retainer) return;
Database.SetQuantity((Retainer)owner, itemDBId, inventoryCode);
Database.SetQuantity(itemDBId, quantity);
} }
private void DoDatabaseRemove(ulong itemDBId) private void DoDatabaseRemove(ulong itemDBId)
@ -480,54 +750,24 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
if (isTemporary) if (isTemporary)
return; return;
if (itemPackageCode == BAZAAR)
return;
if (owner is Player) if (owner is Player)
Database.RemoveItem((Player)owner, itemDBId); Database.RemoveItem((Player)owner, itemDBId);
else if (owner is Retainer) else if (owner is Retainer)
Database.RemoveItem((Retainer)owner, itemDBId); Database.RemoveItem((Retainer)owner, itemDBId);
} }
private void SendUpdatePackets() public void StartSendUpdate()
{ {
if (owner is Player) holdingUpdates = true;
{
SendUpdatePackets((Player)owner, true);
}
}
public void SendUpdatePackets(Player player, bool doneImmediate = false)
{
List<InventoryItem> items = new List<InventoryItem>();
List<ushort> slotsToRemove = new List<ushort>();
for (int i = 0; i < list.Length; i++)
{
if (i == endOfListIndex)
break;
if (isDirty[i])
items.Add(list[i]);
}
for (int i = endOfListIndex; i < list.Length; i++)
{
if (isDirty[i])
slotsToRemove.Add((ushort)i);
}
if (doneImmediate)
DoneSendUpdate();
player.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
//Send Updated Slots
SendInventoryPackets(player, items);
//Send Remove packets for tail end
SendInventoryRemovePackets(player, slotsToRemove);
player.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
player.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
} }
public void DoneSendUpdate() public void DoneSendUpdate()
{ {
holdingUpdates = false;
SendUpdate();
Array.Clear(isDirty, 0, isDirty.Length); Array.Clear(isDirty, 0, isDirty.Length);
} }
@ -537,7 +777,12 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
public bool IsFull() public bool IsFull()
{ {
return endOfListIndex >= inventoryCapacity; return endOfListIndex >= itemPackageCapacity;
}
public int GetFreeSlots()
{
return itemPackageCapacity - endOfListIndex;
} }
public bool IsSpaceForAdd(uint itemId, int quantity, int quality) public bool IsSpaceForAdd(uint itemId, int quantity, int quality)
@ -621,5 +866,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
#endregion #endregion
public int GetCount()
{
return endOfListIndex;
}
} }
} }

View file

@ -1,8 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.chara namespace FFXIVClassic_Map_Server.actors.chara
{ {

View file

@ -1,9 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.actors.chara.npc;
namespace FFXIVClassic_Map_Server.actors.chara namespace FFXIVClassic_Map_Server.actors.chara
{ {

View file

@ -0,0 +1,295 @@
using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using System.Collections.Generic;
using System.Diagnostics;
namespace FFXIVClassic_Map_Server.actors.chara
{
class ReferencedItemPackage
{
const uint EMPTY = 0xFFFFFFFF;
private readonly Player owner;
private readonly InventoryItem[] referenceList;
private readonly ushort itemPackageCode;
private readonly ushort itemPackageCapacity;
private bool writeToDB = false;
public ReferencedItemPackage(Player owner, ushort capacity, ushort code)
{
this.owner = owner;
itemPackageCode = code;
itemPackageCapacity = capacity;
referenceList = new InventoryItem[capacity];
if (code == ItemPackage.EQUIPMENT)
writeToDB = true;
}
public void ToggleDBWrite(bool flag)
{
writeToDB = flag;
}
#region Package Management
public void SetList(InventoryItem[] toSet)
{
Debug.Assert(referenceList.Length == itemPackageCapacity);
toSet.CopyTo(referenceList, 0);
}
public void Set(ushort[] positions, ushort[] itemSlots, ushort itemPackage)
{
Debug.Assert(positions.Length == itemSlots.Length);
for (int i = 0; i < positions.Length; i++)
{
InventoryItem item = owner.GetItemPackage(itemPackage)?.GetItemAtSlot(itemSlots[i]);
if (item == null)
continue;
Database.EquipItem(owner, positions[i], item.uniqueId);
referenceList[positions[i]] = item;
}
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendUpdate();
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
public void Set(ushort position, ushort itemPackagePosition, ushort itemPackageCode)
{
InventoryItem item = owner.GetItemPackage(itemPackageCode).GetItemAtSlot(itemPackagePosition);
if (item == null)
return;
Set(position, item);
}
public void Set(ushort position, InventoryItem item)
{
if (position >= referenceList.Length)
return;
if (writeToDB)
Database.EquipItem(owner, position, item.uniqueId);
ItemPackage newPackage = owner.GetItemPackage(item.itemPackage);
ItemPackage oldPackage = null;
if (referenceList[position] != null)
{
oldPackage = owner.GetItemPackage(referenceList[position].itemPackage);
InventoryItem oldItem = referenceList[position];
oldPackage.MarkDirty(oldItem);
}
newPackage.MarkDirty(item);
referenceList[position] = item;
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
if (oldPackage != null)
oldPackage.SendUpdate();
newPackage.SendUpdate();
SendSingleUpdate(position);
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
public void Clear(ushort position)
{
if (position >= referenceList.Length)
return;
if (writeToDB)
Database.UnequipItem(owner, position);
ItemPackage oldItemPackage = owner.GetItemPackage(referenceList[position].itemPackage);
oldItemPackage.MarkDirty(referenceList[position]);
referenceList[position] = null;
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
oldItemPackage.SendUpdate();
SendSingleUpdate(position);
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
public void ClearAll()
{
List<ItemPackage> packagesToRefresh = new List<ItemPackage>();
for (int i = 0; i < referenceList.Length; i++)
{
if (referenceList[i] == null)
continue;
if (writeToDB)
Database.UnequipItem(owner, (ushort)i);
ItemPackage package = owner.GetItemPackage(referenceList[i].itemPackage);
package.MarkDirty(referenceList[i]);
packagesToRefresh.Add(package);
referenceList[i] = null;
}
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
for (int i = 0; i < packagesToRefresh.Count; i++)
packagesToRefresh[i].SendUpdate();
SendUpdate();
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
#endregion
#region Send Update Functions
public void SendSingleUpdate(ushort position)
{
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
SendSingleLinkedItemPacket(owner, position);
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void SendUpdate()
{
SendUpdate(owner);
}
public void SendUpdate(Player targetPlayer)
{
List<ushort> slotsToUpdate = new List<ushort>();
for (ushort i = 0; i < referenceList.Length; i++)
{
if (referenceList[i] != null)
slotsToUpdate.Add(i);
}
targetPlayer.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode));
SendLinkedItemPackets(targetPlayer, slotsToUpdate);
targetPlayer.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void SendUpdateAsItemPackage(Player targetPlayer)
{
SendUpdateAsItemPackage(targetPlayer, itemPackageCapacity, itemPackageCode);
}
public void SendUpdateAsItemPackage(Player targetPlayer, ushort destinationCapacity, ushort destinationCode)
{
List<InventoryItem> items = new List<InventoryItem>();
for (ushort i = 0; i < referenceList.Length; i++)
{
if (referenceList[i] == null)
continue;
InventoryItem item = referenceList[i];
item.linkSlot = i; //We have to set the linkSlot as this is the position in the Referenced IP, not the original IP it's linked from.
items.Add(referenceList[i]);
}
targetPlayer.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, destinationCapacity, destinationCode));
SendItemPackets(targetPlayer, items);
targetPlayer.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
//Clean Up linkSlots
for (ushort i = 0; i < referenceList.Length; i++)
{
if (referenceList[i] == null)
continue;
InventoryItem item = referenceList[i];
item.linkSlot = 0xFFFF;
}
}
#endregion
#region Packet Functions (Private)
private void SendSingleLinkedItemPacket(Player targetPlayer, ushort position)
{
if (referenceList[position] == null)
targetPlayer.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, position));
else
targetPlayer.QueuePacket(LinkedItemListX01Packet.BuildPacket(owner.actorId, position, referenceList[position]));
}
private void SendLinkedItemPackets(Player targetPlayer, List<ushort> slotsToUpdate)
{
int currentIndex = 0;
while (true)
{
if (slotsToUpdate.Count - currentIndex >= 64)
targetPlayer.QueuePacket(LinkedItemListX64Packet.BuildPacket(owner.actorId, referenceList, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex >= 32)
targetPlayer.QueuePacket(LinkedItemListX32Packet.BuildPacket(owner.actorId, referenceList, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex >= 16)
targetPlayer.QueuePacket(LinkedItemListX16Packet.BuildPacket(owner.actorId, referenceList, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex > 1)
targetPlayer.QueuePacket(LinkedItemListX08Packet.BuildPacket(owner.actorId, referenceList, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex == 1)
{
targetPlayer.QueuePacket(LinkedItemListX01Packet.BuildPacket(owner.actorId, slotsToUpdate[currentIndex], referenceList[slotsToUpdate[currentIndex]]));
currentIndex++;
}
else
break;
}
}
private void SendItemPackets(Player player, List<InventoryItem> items)
{
int currentIndex = 0;
while (true)
{
if (items.Count - currentIndex >= 64)
player.QueuePacket(InventoryListX64Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex >= 32)
player.QueuePacket(InventoryListX32Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex >= 16)
player.QueuePacket(InventoryListX16Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex > 1)
player.QueuePacket(InventoryListX08Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex == 1)
{
player.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, items[currentIndex]));
currentIndex++;
}
else
break;
}
}
#endregion
#region Getters/Setters
public ushort GetCode()
{
return itemPackageCode;
}
public int GetCapacity()
{
return itemPackageCapacity;
}
public Player GetOwner()
{
return owner;
}
public InventoryItem GetItemAtSlot(ushort position)
{
if (position < referenceList.Length)
return referenceList[position];
else
return null;
}
#endregion
}
}

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.chara
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.chara
{ {
class SubState class SubState
{ {

View file

@ -1,8 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.actors.chara.ai.state; using FFXIVClassic_Map_Server.actors.chara.ai.state;
using FFXIVClassic_Map_Server.actors.chara.ai.controllers; using FFXIVClassic_Map_Server.actors.chara.ai.controllers;

View file

@ -1,11 +1,6 @@
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.actors.chara.ai.utils; using FFXIVClassic_Map_Server.actors.chara.ai.utils;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.chara.ai
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.chara.ai
{ {
class BattleTrait class BattleTrait
{ {

View file

@ -1,8 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
namespace FFXIVClassic_Map_Server.actors.chara.ai namespace FFXIVClassic_Map_Server.actors.chara.ai

View file

@ -1,12 +1,7 @@
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
using FFXIVClassic.Common; using FFXIVClassic.Common;

View file

@ -1,16 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
using System.Collections.ObjectModel;
using FFXIVClassic_Map_Server.utils; using FFXIVClassic_Map_Server.utils;
namespace FFXIVClassic_Map_Server.actors.chara.ai namespace FFXIVClassic_Map_Server.actors.chara.ai

View file

@ -1,11 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.actors.chara.npc; using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic.Common;
namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
{ {

View file

@ -1,8 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers

View file

@ -1,8 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers

View file

@ -1,11 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic.Common;
namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
{ {

View file

@ -1,11 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using MoonSharp;
using MoonSharp.Interpreter;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;
namespace FFXIVClassic_Map_Server.actors.chara.ai namespace FFXIVClassic_Map_Server.actors.chara.ai

View file

@ -1,14 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server;
using FFXIVClassic_Map_Server.utils; using FFXIVClassic_Map_Server.utils;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.area; using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.packets.send.actor;
// port of https://github.com/DarkstarProject/darkstar/blob/master/src/map/ai/helpers/pathfind.h // port of https://github.com/DarkstarProject/darkstar/blob/master/src/map/ai/helpers/pathfind.h

View file

@ -1,14 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.chara.ai;
using FFXIVClassic_Map_Server.actors.chara.ai.controllers; using FFXIVClassic_Map_Server.actors.chara.ai.controllers;
using FFXIVClassic_Map_Server.actors.group; using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.packets.send.actor;
// port of dsp's ai code https://github.com/DarkstarProject/darkstar/blob/master/src/map/ai/ // port of dsp's ai code https://github.com/DarkstarProject/darkstar/blob/master/src/map/ai/

View file

@ -1,13 +1,7 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.packets.send;
namespace FFXIVClassic_Map_Server.actors.chara.ai.state namespace FFXIVClassic_Map_Server.actors.chara.ai.state
{ {

View file

@ -1,8 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;

View file

@ -1,8 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;

View file

@ -1,8 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;

View file

@ -1,8 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
namespace FFXIVClassic_Map_Server.actors.chara.ai.state namespace FFXIVClassic_Map_Server.actors.chara.ai.state

View file

@ -1,10 +1,4 @@
using System; using FFXIVClassic_Map_Server.Actors;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
namespace FFXIVClassic_Map_Server.actors.chara.ai.state namespace FFXIVClassic_Map_Server.actors.chara.ai.state

View file

@ -1,14 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.utils;
namespace FFXIVClassic_Map_Server.actors.chara.ai.state namespace FFXIVClassic_Map_Server.actors.chara.ai.state
{ {

View file

@ -1,10 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
namespace FFXIVClassic_Map_Server.actors.chara.ai.state namespace FFXIVClassic_Map_Server.actors.chara.ai.state

View file

@ -1,13 +1,7 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.packets.send;
namespace FFXIVClassic_Map_Server.actors.chara.ai.state namespace FFXIVClassic_Map_Server.actors.chara.ai.state
{ {

View file

@ -1,9 +1,4 @@
using System; using FFXIVClassic_Map_Server.Actors;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors;
namespace FFXIVClassic_Map_Server.actors.chara.ai.utils namespace FFXIVClassic_Map_Server.actors.chara.ai.utils
{ {
static class AttackUtils static class AttackUtils

View file

@ -1,15 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.actors.chara.npc; using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic.Common; using FFXIVClassic.Common;
namespace FFXIVClassic_Map_Server.actors.chara.ai.utils namespace FFXIVClassic_Map_Server.actors.chara.ai.utils

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.chara.npc
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.chara.npc
{ {
class ActorClass class ActorClass
{ {

View file

@ -1,9 +1,4 @@
using System; using FFXIVClassic_Map_Server.Actors;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.actors.chara.ai; using FFXIVClassic_Map_Server.actors.chara.ai;
using FFXIVClassic_Map_Server.actors.chara.ai.controllers; using FFXIVClassic_Map_Server.actors.chara.ai.controllers;

View file

@ -1,22 +1,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.actors.chara.npc; using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.actors;
using FFXIVClassic_Map_Server.actors.chara; using FFXIVClassic_Map_Server.actors.chara;
using FFXIVClassic_Map_Server.actors.chara.ai; using FFXIVClassic_Map_Server.actors.chara.ai;
using FFXIVClassic_Map_Server.actors.chara.ai.controllers; using FFXIVClassic_Map_Server.actors.chara.ai.controllers;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.actors.chara.ai.state; using FFXIVClassic_Map_Server.actors.chara.ai.state;
using FFXIVClassic_Map_Server.utils; using FFXIVClassic_Map_Server.utils;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.actors.chara.ai.utils; using FFXIVClassic_Map_Server.actors.chara.ai.utils;
using FFXIVClassic_Map_Server.actors.group; using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.Actors.Chara; using FFXIVClassic_Map_Server.Actors.Chara;
namespace FFXIVClassic_Map_Server.Actors namespace FFXIVClassic_Map_Server.Actors

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.chara.npc
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.chara.npc
{ {
enum MobModifier enum MobModifier
{ {

View file

@ -1,22 +1,14 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors; using FFXIVClassic_Map_Server.actors;
using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.actors.chara.npc; using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.Actors.Chara; using FFXIVClassic_Map_Server.Actors.Chara;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.receive.events;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.utils; using FFXIVClassic_Map_Server.utils;
using MoonSharp.Interpreter;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.actors.chara.ai; using FFXIVClassic_Map_Server.actors.chara.ai;
namespace FFXIVClassic_Map_Server.Actors namespace FFXIVClassic_Map_Server.Actors

View file

@ -1,13 +1,7 @@
using System; 
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.actors.chara.ai; using FFXIVClassic_Map_Server.actors.chara.ai;
using FFXIVClassic_Map_Server.actors.chara.ai.controllers; using FFXIVClassic_Map_Server.actors.chara.ai.controllers;
using FFXIVClassic_Map_Server.actors.chara.npc; using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.packets.send.actor;
namespace FFXIVClassic_Map_Server.Actors namespace FFXIVClassic_Map_Server.Actors
{ {

View file

@ -1,12 +1,6 @@
using FFXIVClassic.Common; using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.chara.npc namespace FFXIVClassic_Map_Server.actors.chara.npc
{ {
@ -18,7 +12,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.npc
private uint retainerId; private uint retainerId;
private Player ownerPlayer; private Player ownerPlayer;
private Dictionary<ushort, Inventory> inventories = new Dictionary<ushort, Inventory>();
public Retainer(uint retainerId, ActorClass actorClass, Player player, float posX, float posY, float posZ, float rot) public Retainer(uint retainerId, ActorClass actorClass, Player player, float posX, float posY, float posZ, float rot)
: base(0, actorClass, "myretainer", player.GetZone(), posX, posY, posZ, rot, 0, 0, null) : base(0, actorClass, "myretainer", player.GetZone(), posX, posY, posZ, rot, 0, 0, null)
@ -27,33 +20,16 @@ namespace FFXIVClassic_Map_Server.actors.chara.npc
this.ownerPlayer = player; this.ownerPlayer = player;
this.actorName = String.Format("_rtnre{0:x7}", actorId); this.actorName = String.Format("_rtnre{0:x7}", actorId);
inventories[Inventory.NORMAL] = new Inventory(this, MAXSIZE_INVENTORY_NORMAL, Inventory.NORMAL); itemPackages[ItemPackage.NORMAL] = new ItemPackage(this, MAXSIZE_INVENTORY_NORMAL, ItemPackage.NORMAL);
inventories[Inventory.CURRENCY_CRYSTALS] = new Inventory(this, MAXSIZE_INVENTORY_CURRANCY, Inventory.CURRENCY_CRYSTALS); itemPackages[ItemPackage.CURRENCY_CRYSTALS] = new ItemPackage(this, MAXSIZE_INVENTORY_CURRANCY, ItemPackage.CURRENCY_CRYSTALS);
inventories[Inventory.BAZAAR] = new Inventory(this, MAXSIZE_INVENTORY_BAZAAR, Inventory.BAZAAR); itemPackages[ItemPackage.BAZAAR] = new ItemPackage(this, MAXSIZE_INVENTORY_BAZAAR, ItemPackage.BAZAAR);
inventories[Inventory.NORMAL].InitList(Database.GetInventory(this, Inventory.NORMAL)); itemPackages[ItemPackage.NORMAL].InitList(Database.GetInventory(this, ItemPackage.NORMAL));
inventories[Inventory.CURRENCY_CRYSTALS].InitList(Database.GetInventory(this, Inventory.CURRENCY_CRYSTALS)); itemPackages[ItemPackage.CURRENCY_CRYSTALS].InitList(Database.GetInventory(this, ItemPackage.CURRENCY_CRYSTALS));
inventories[Inventory.BAZAAR].InitList(Database.GetInventory(this, Inventory.BAZAAR)); itemPackages[ItemPackage.BAZAAR].InitList(Database.GetInventory(this, ItemPackage.BAZAAR));
} }
public Inventory GetInventory(ushort type) public uint GetRetainerId()
{
if (inventories.ContainsKey(type))
return inventories[type];
else
return null;
}
public void SendFullRetainerInventory(Player player)
{
player.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId));
inventories[Inventory.NORMAL].SendFullInventory(player);
inventories[Inventory.CURRENCY_CRYSTALS].SendFullInventory(player);
inventories[Inventory.BAZAAR].SendFullInventory(player);
player.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
}
public uint getRetainerId()
{ {
return retainerId; return retainerId;
} }

View file

@ -1,236 +0,0 @@
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using System.Collections.Generic;
namespace FFXIVClassic_Map_Server.actors.chara.player
{
class Equipment
{
public const int SLOT_MAINHAND = 0;
public const int SLOT_OFFHAND = 1;
public const int SLOT_THROWINGWEAPON = 4;
public const int SLOT_PACK = 5;
public const int SLOT_POUCH = 6;
public const int SLOT_HEAD = 8;
public const int SLOT_UNDERSHIRT = 9;
public const int SLOT_BODY = 10;
public const int SLOT_UNDERGARMENT = 11;
public const int SLOT_LEGS = 12;
public const int SLOT_HANDS = 13;
public const int SLOT_BOOTS = 14;
public const int SLOT_WAIST = 15;
public const int SLOT_NECK = 16;
public const int SLOT_EARS = 17;
public const int SLOT_WRISTS = 19;
public const int SLOT_RIGHTFINGER = 21;
public const int SLOT_LEFTFINGER = 22;
private Player owner;
private ushort inventoryCapacity;
private ushort inventoryCode;
private InventoryItem[] list;
private Inventory normalInventory;
private bool writeToDB = true;
public Equipment(Player ownerPlayer, Inventory normalInventory, ushort capacity, ushort code)
{
owner = ownerPlayer;
inventoryCapacity = capacity;
inventoryCode = code;
list = new InventoryItem[inventoryCapacity];
this.normalInventory = normalInventory;
}
public InventoryItem GetItemAtSlot(ushort slot)
{
if (slot < list.Length)
return list[slot];
else
return null;
}
public void SendCheckEquipmentToPlayer(Player toPlayer)
{
List<InventoryItem> items = new List<InventoryItem>();
for (ushort i = 0; i < list.Length; i++)
{
if (list[i] != null)
{
InventoryItem equipItem = new InventoryItem(list[i], i);
items.Add(equipItem);
}
}
toPlayer.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, 0x23, Inventory.EQUIPMENT_OTHERPLAYER));
int currentIndex = 0;
while (true)
{
if (items.Count - currentIndex >= 16)
toPlayer.QueuePacket(InventoryListX16Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex > 1)
toPlayer.QueuePacket(InventoryListX08Packet.BuildPacket(owner.actorId, items, ref currentIndex));
else if (items.Count - currentIndex == 1)
{
toPlayer.QueuePacket(InventoryListX01Packet.BuildPacket(owner.actorId, items[currentIndex]));
currentIndex++;
}
else
break;
}
toPlayer.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void SendFullEquipment(bool DoClear)
{
List<ushort> slotsToUpdate = new List<ushort>();
for (ushort i = 0; i < list.Length; i++)
{
if (list[i] == null && DoClear)
slotsToUpdate.Add(0);
else if (list[i] != null)
slotsToUpdate.Add(i);
}
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendEquipmentPackets(slotsToUpdate);
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
}
public void SetEquipment(ushort[] slots, ushort[] itemSlots)
{
if (slots.Length != itemSlots.Length)
return;
for (int i = 0; i < slots.Length; i++)
{
InventoryItem item = normalInventory.GetItemAtSlot(itemSlots[i]);
if (item == null)
continue;
Database.EquipItem(owner, slots[i], item.uniqueId);
list[slots[i]] = normalInventory.GetItemAtSlot(itemSlots[i]);
}
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
SendFullEquipment(false);
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
}
public void SetEquipment(InventoryItem[] toEquip)
{
List<ushort> slotsToUpdate = new List<ushort>();
for (ushort i = 0; i < toEquip.Length; i++)
{
if (toEquip[i] != null)
slotsToUpdate.Add(i);
}
list = toEquip;
}
public void Equip(ushort slot, ushort invSlot)
{
InventoryItem item = normalInventory.GetItemAtSlot(invSlot);
if (item == null)
return;
Equip(slot, item);
}
public void Equip(ushort slot, InventoryItem item)
{
if (slot >= list.Length)
return;
if (writeToDB)
Database.EquipItem(owner, slot, item.uniqueId);
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
if (list[slot] != null)
normalInventory.RefreshItem(owner, list[slot], item);
else
normalInventory.RefreshItem(owner, item);
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendEquipmentPackets(slot, item);
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
list[slot] = item;
owner.CalculateBaseStats();// RecalculateStats();
}
public void ToggleDBWrite(bool flag)
{
writeToDB = flag;
}
public void Unequip(ushort slot)
{
if (slot >= list.Length)
return;
if (writeToDB)
Database.UnequipItem(owner, slot);
owner.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId));
normalInventory.RefreshItem(owner, list[slot]);
owner.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, inventoryCapacity, inventoryCode));
SendEquipmentPackets(slot, null);
owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId));
owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId));
list[slot] = null;
owner.RecalculateStats();
}
private void SendEquipmentPackets(ushort equipSlot, InventoryItem item)
{
if (item == null)
owner.QueuePacket(InventoryRemoveX01Packet.BuildPacket(owner.actorId, equipSlot));
else
owner.QueuePacket(EquipmentListX01Packet.BuildPacket(owner.actorId, equipSlot, item.slot));
}
private void SendEquipmentPackets(List<ushort> slotsToUpdate)
{
int currentIndex = 0;
while (true)
{
if (slotsToUpdate.Count - currentIndex >= 64)
owner.QueuePacket(EquipmentListX64Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex >= 32)
owner.QueuePacket(EquipmentListX32Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex >= 16)
owner.QueuePacket(EquipmentListX16Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex > 1)
owner.QueuePacket(EquipmentListX08Packet.BuildPacket(owner.actorId, list, slotsToUpdate, ref currentIndex));
else if (slotsToUpdate.Count - currentIndex == 1)
{
owner.QueuePacket(EquipmentListX01Packet.BuildPacket(owner.actorId, slotsToUpdate[currentIndex], list[slotsToUpdate[currentIndex]].slot));
currentIndex++;
}
else
break;
}
}
public int GetCapacity()
{
return list.Length;
}
}
}

View file

@ -23,19 +23,12 @@ using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using FFXIVClassic_Map_Server.packets.send.player; using FFXIVClassic_Map_Server.packets.send.player;
using FFXIVClassic_Map_Server.packets.send.actor.battle; using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.packets.receive.events; using FFXIVClassic_Map_Server.packets.receive.events;
using static FFXIVClassic_Map_Server.LuaUtils;
namespace FFXIVClassic_Map_Server.Actors namespace FFXIVClassic_Map_Server.Actors
{ {
class Player : Character class Player : Character
{ {
public const int MAXSIZE_INVENTORY_NORMAL = 200;
public const int MAXSIZE_INVENTORY_CURRANCY = 320;
public const int MAXSIZE_INVENTORY_KEYITEMS = 500;
public const int MAXSIZE_INVENTORY_LOOT = 10;
public const int MAXSIZE_INVENTORY_MELDREQUEST = 4;
public const int MAXSIZE_INVENTORY_BAZAAR = 10;
public const int MAXSIZE_INVENTORY_EQUIPMENT = 35;
public const int TIMER_TOTORAK = 0; public const int TIMER_TOTORAK = 0;
public const int TIMER_DZEMAEL = 1; public const int TIMER_DZEMAEL = 1;
public const int TIMER_BOWL_OF_EMBERS_HARD = 2; public const int TIMER_BOWL_OF_EMBERS_HARD = 2;
@ -62,6 +55,25 @@ namespace FFXIVClassic_Map_Server.Actors
public const int NPCLS_ACTIVE = 2; public const int NPCLS_ACTIVE = 2;
public const int NPCLS_ALERT = 3; public const int NPCLS_ALERT = 3;
public const int SLOT_MAINHAND = 0;
public const int SLOT_OFFHAND = 1;
public const int SLOT_THROWINGWEAPON = 4;
public const int SLOT_PACK = 5;
public const int SLOT_POUCH = 6;
public const int SLOT_HEAD = 8;
public const int SLOT_UNDERSHIRT = 9;
public const int SLOT_BODY = 10;
public const int SLOT_UNDERGARMENT = 11;
public const int SLOT_LEGS = 12;
public const int SLOT_HANDS = 13;
public const int SLOT_BOOTS = 14;
public const int SLOT_WAIST = 15;
public const int SLOT_NECK = 16;
public const int SLOT_EARS = 17;
public const int SLOT_WRISTS = 19;
public const int SLOT_RIGHTFINGER = 21;
public const int SLOT_LEFTFINGER = 22;
public static int[] MAXEXP = {570, 700, 880, 1100, 1500, 1800, 2300, 3200, 4300, 5000, //Level <= 10 public static int[] MAXEXP = {570, 700, 880, 1100, 1500, 1800, 2300, 3200, 4300, 5000, //Level <= 10
5900, 6800, 7700, 8700, 9700, 11000, 12000, 13000, 15000, 16000, //Level <= 20 5900, 6800, 7700, 8700, 9700, 11000, 12000, 13000, 15000, 16000, //Level <= 20
20000, 22000, 23000, 25000, 27000, 29000, 31000, 33000, 35000, 38000, //Level <= 30 20000, 22000, 23000, 25000, 27000, 29000, 31000, 33000, 35000, 38000, //Level <= 30
@ -71,7 +83,6 @@ namespace FFXIVClassic_Map_Server.Actors
//Event Related //Event Related
public uint currentEventOwner = 0; public uint currentEventOwner = 0;
public string currentEventName = ""; public string currentEventName = "";
public Coroutine currentEventRunning; public Coroutine currentEventRunning;
//Player Info //Player Info
@ -84,9 +95,10 @@ namespace FFXIVClassic_Map_Server.Actors
public bool isGM = false; public bool isGM = false;
public bool isZoneChanging = true; public bool isZoneChanging = true;
//Inventory //Trading
private Dictionary<ushort, Inventory> inventories = new Dictionary<ushort, Inventory>(); private Player otherTrader = null;
private Equipment equipment; private ReferencedItemPackage myOfferings;
private bool isTradeAccepted = false;
//GC Related //GC Related
public byte gcCurrent; public byte gcCurrent;
@ -115,6 +127,10 @@ namespace FFXIVClassic_Map_Server.Actors
public uint homepoint = 0; public uint homepoint = 0;
public byte homepointInn = 0; public byte homepointInn = 0;
//Nameplate Stuff
public uint currentLSPlate = 0;
public byte repairType = 0;
//Retainer //Retainer
RetainerMeetingRelationGroup retainerMeetingGroup = null; RetainerMeetingRelationGroup retainerMeetingGroup = null;
public Retainer currentSpawnedRetainer = null; public Retainer currentSpawnedRetainer = null;
@ -140,14 +156,13 @@ namespace FFXIVClassic_Map_Server.Actors
moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN; moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE; moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
inventories[Inventory.NORMAL] = new Inventory(this, MAXSIZE_INVENTORY_NORMAL, Inventory.NORMAL); itemPackages[ItemPackage.NORMAL] = new ItemPackage(this, ItemPackage.MAXSIZE_NORMAL, ItemPackage.NORMAL);
inventories[Inventory.KEYITEMS] = new Inventory(this, MAXSIZE_INVENTORY_KEYITEMS, Inventory.KEYITEMS); itemPackages[ItemPackage.KEYITEMS] = new ItemPackage(this, ItemPackage.MAXSIZE_KEYITEMS, ItemPackage.KEYITEMS);
inventories[Inventory.CURRENCY_CRYSTALS] = new Inventory(this, MAXSIZE_INVENTORY_CURRANCY, Inventory.CURRENCY_CRYSTALS); itemPackages[ItemPackage.CURRENCY_CRYSTALS] = new ItemPackage(this, ItemPackage.MAXSIZE_CURRANCY, ItemPackage.CURRENCY_CRYSTALS);
inventories[Inventory.MELDREQUEST] = new Inventory(this, MAXSIZE_INVENTORY_MELDREQUEST, Inventory.MELDREQUEST); itemPackages[ItemPackage.MELDREQUEST] = new ItemPackage(this, ItemPackage.MAXSIZE_MELDREQUEST, ItemPackage.MELDREQUEST);
inventories[Inventory.BAZAAR] = new Inventory(this, MAXSIZE_INVENTORY_BAZAAR, Inventory.BAZAAR); itemPackages[ItemPackage.BAZAAR] = new ItemPackage(this, ItemPackage.MAXSIZE_BAZAAR, ItemPackage.BAZAAR);
inventories[Inventory.LOOT] = new Inventory(this, MAXSIZE_INVENTORY_LOOT, Inventory.LOOT); itemPackages[ItemPackage.LOOT] = new ItemPackage(this, ItemPackage.MAXSIZE_LOOT, ItemPackage.LOOT);
equipment = new ReferencedItemPackage(this, ItemPackage.MAXSIZE_EQUIPMENT, ItemPackage.EQUIPMENT);
equipment = new Equipment(this, inventories[Inventory.NORMAL], MAXSIZE_INVENTORY_EQUIPMENT, Inventory.EQUIPMENT);
//Set the Skill level caps of all FFXIV (classes)skills to 50 //Set the Skill level caps of all FFXIV (classes)skills to 50
for (int i = 0; i < charaWork.battleSave.skillLevelCap.Length; i++) for (int i = 0; i < charaWork.battleSave.skillLevelCap.Length; i++)
@ -476,6 +491,17 @@ namespace FFXIVClassic_Map_Server.Actors
propPacketUtil.AddProperty(String.Format("work.guildleveChecked[{0}]", i)); propPacketUtil.AddProperty(String.Format("work.guildleveChecked[{0}]", i));
} }
//Bazaar
CheckBazaarFlags(true);
if (charaWork.eventSave.repairType != 0)
propPacketUtil.AddProperty("charaWork.eventSave.repairType");
if (charaWork.eventTemp.bazaarRetail)
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRetail");
if (charaWork.eventTemp.bazaarRepair)
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRepair");
if (charaWork.eventTemp.bazaarMateria)
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarMateria");
//NPC Linkshell //NPC Linkshell
for (int i = 0; i < playerWork.npcLinkshellChatCalling.Length; i++) for (int i = 0; i < playerWork.npcLinkshellChatCalling.Length; i++)
{ {
@ -516,14 +542,14 @@ namespace FFXIVClassic_Map_Server.Actors
//GetSpawnPackets(actorId, spawnType).DebugPrintPacket(); //GetSpawnPackets(actorId, spawnType).DebugPrintPacket();
#region Inventory & Equipment #region Inventory & Equipment
QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId)); QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
inventories[Inventory.NORMAL].SendFullInventory(this); itemPackages[ItemPackage.NORMAL].SendFullPackage(this);
inventories[Inventory.CURRENCY_CRYSTALS].SendFullInventory(this); itemPackages[ItemPackage.CURRENCY_CRYSTALS].SendFullPackage(this);
inventories[Inventory.KEYITEMS].SendFullInventory(this); itemPackages[ItemPackage.KEYITEMS].SendFullPackage(this);
inventories[Inventory.BAZAAR].SendFullInventory(this); itemPackages[ItemPackage.BAZAAR].SendFullPackage(this);
inventories[Inventory.MELDREQUEST].SendFullInventory(this); itemPackages[ItemPackage.MELDREQUEST].SendFullPackage(this);
inventories[Inventory.LOOT].SendFullInventory(this); itemPackages[ItemPackage.LOOT].SendFullPackage(this);
equipment.SendFullEquipment(false); equipment.SendUpdate(this);
playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId)); playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
#endregion #endregion
@ -625,6 +651,33 @@ namespace FFXIVClassic_Map_Server.Actors
} }
} }
public void BroadcastPackets(List<SubPacket> packets, bool sendToSelf)
{
foreach (SubPacket packet in packets)
{
if (sendToSelf)
{
SubPacket clonedPacket = new SubPacket(packet, actorId);
QueuePacket(clonedPacket);
}
foreach (Actor a in playerSession.actorInstanceList)
{
if (a is Player)
{
Player p = (Player)a;
if (p.Equals(this))
continue;
SubPacket clonedPacket = new SubPacket(packet, a.actorId);
p.QueuePacket(clonedPacket);
}
}
}
}
public void BroadcastPacket(SubPacket packet, bool sendToSelf) public void BroadcastPacket(SubPacket packet, bool sendToSelf)
{ {
if (sendToSelf) if (sendToSelf)
@ -940,6 +993,8 @@ namespace FFXIVClassic_Map_Server.Actors
public void PrepareClassChange(byte classId) public void PrepareClassChange(byte classId)
{ {
//If new class, init abilties and level //If new class, init abilties and level
if (charaWork.battleSave.skillLevel[classId - 1] <= 0)
UpdateClassLevel(classId, 1);
SendCharaExpInfo(); SendCharaExpInfo();
} }
@ -1012,6 +1067,16 @@ namespace FFXIVClassic_Map_Server.Actors
RecalculateStats(); RecalculateStats();
} }
public void UpdateClassLevel(byte classId, short level)
{
Database.PlayerCharacterUpdateClassLevel(this, classId, level);
charaWork.battleSave.skillLevel[classId - 1] = level;
ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("charaWork/exp", this);
propertyBuilder.AddProperty(String.Format("charaWork.battleSave.skillLevel[{0}]", classId-1));
List<SubPacket> packets = propertyBuilder.Done();
QueuePackets(packets);
}
public void GraphicChange(int slot, InventoryItem invItem) public void GraphicChange(int slot, InventoryItem invItem)
{ {
if (invItem == null) if (invItem == null)
@ -1057,18 +1122,68 @@ namespace FFXIVClassic_Map_Server.Actors
BroadcastPacket(CreateAppearancePacket(), true); BroadcastPacket(CreateAppearancePacket(), true);
} }
public Inventory GetInventory(ushort type) public void SetRepairRequest(byte type)
{ {
if (inventories.ContainsKey(type)) charaWork.eventSave.repairType = type;
return inventories[type]; ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/bazaar", this);
else propPacketUtil.AddProperty("charaWork.eventSave.repairType");
return null; QueuePackets(propPacketUtil.Done());
}
public void CheckBazaarFlags(bool noUpdate = false)
{
bool isDealing = false, isRepairing = false, seekingItem = false;
lock (GetItemPackage(ItemPackage.BAZAAR))
{
foreach (InventoryItem item in GetItemPackage(ItemPackage.BAZAAR).GetRawList())
{
if (item == null)
break;
if (item.GetBazaarMode() == InventoryItem.TYPE_SINGLE || item.GetBazaarMode() == InventoryItem.TYPE_MULTI || item.GetBazaarMode() == InventoryItem.TYPE_STACK)
isDealing = true;
if (item.GetBazaarMode() == InventoryItem.TYPE_SEEK_REPAIR)
isRepairing = true;
if (item.GetBazaarMode() == InventoryItem.TYPE_SEEK_ITEM)
isDealing = true;
if (isDealing && isRepairing && seekingItem)
break;
}
}
bool doUpdate = false;
ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/bazaar", this);
if (charaWork.eventTemp.bazaarRetail != isDealing)
{
charaWork.eventTemp.bazaarRetail = isDealing;
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRetail");
doUpdate = true;
}
if (charaWork.eventTemp.bazaarRepair != isRepairing)
{
charaWork.eventTemp.bazaarRepair = isRepairing;
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRepair");
doUpdate = true;
}
if (charaWork.eventTemp.bazaarMateria != (GetItemPackage(ItemPackage.MELDREQUEST).GetCount() != 0))
{
charaWork.eventTemp.bazaarMateria = GetItemPackage(ItemPackage.MELDREQUEST).GetCount() != 0;
propPacketUtil.AddProperty("charaWork.eventTemp.bazaarMateria");
doUpdate = true;
}
if (!noUpdate && doUpdate)
BroadcastPackets(propPacketUtil.Done(), true);
} }
public int GetCurrentGil() public int GetCurrentGil()
{ {
if (GetInventory(Inventory.CURRENCY_CRYSTALS).HasItem(1000001)) if (HasItem(1000001))
return GetInventory(Inventory.CURRENCY_CRYSTALS).GetItemByCatelogId(1000001).quantity; return GetItemPackage(ItemPackage.CURRENCY_CRYSTALS).GetItemByCatelogId(1000001).quantity;
else else
return 0; return 0;
} }
@ -1094,7 +1209,7 @@ namespace FFXIVClassic_Map_Server.Actors
return isZoneChanging; return isZoneChanging;
} }
public Equipment GetEquipment() public ReferencedItemPackage GetEquipment()
{ {
return equipment; return equipment;
} }
@ -1578,17 +1693,11 @@ namespace FFXIVClassic_Map_Server.Actors
else else
return; return;
QueuePacket(InventoryBeginChangePacket.BuildPacket(toBeExamined.actorId)); QueuePacket(InventoryBeginChangePacket.BuildPacket(toBeExamined.actorId, true));
toBeExamined.GetEquipment().SendCheckEquipmentToPlayer(this); toBeExamined.GetEquipment().SendUpdateAsItemPackage(this, ItemPackage.MAXSIZE_EQUIPMENT_OTHERPLAYER, ItemPackage.EQUIPMENT_OTHERPLAYER);
QueuePacket(InventoryEndChangePacket.BuildPacket(toBeExamined.actorId)); QueuePacket(InventoryEndChangePacket.BuildPacket(toBeExamined.actorId));
} }
public void SendMyTradeToPlayer(Player player)
{
Inventory tradeInventory = new Inventory(this, 4, Inventory.TRADE);
tradeInventory.SendFullInventory(player);
}
public void SendDataPacket(params object[] parameters) public void SendDataPacket(params object[] parameters)
{ {
List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters); List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters);
@ -1599,6 +1708,8 @@ namespace FFXIVClassic_Map_Server.Actors
public void StartEvent(Actor owner, EventStartPacket start) public void StartEvent(Actor owner, EventStartPacket start)
{ {
currentEventOwner = start.scriptOwnerActorID;
currentEventName = start.triggerName;
LuaEngine.GetInstance().EventStarted(this, owner, start); LuaEngine.GetInstance().EventStarted(this, owner, start);
} }
@ -1613,7 +1724,18 @@ namespace FFXIVClassic_Map_Server.Actors
return; return;
List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters); List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters);
SubPacket spacket = KickEventPacket.BuildPacket(actorId, actor.actorId, conditionName, lParams); SubPacket spacket = KickEventPacket.BuildPacket(actorId, actor.actorId, 0x75dc1705, conditionName, lParams);
spacket.DebugPrintSubPacket();
QueuePacket(spacket);
}
public void KickEventSpecial(Actor actor, uint unknown, string conditionName, params object[] parameters)
{
if (actor == null)
return;
List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters);
SubPacket spacket = KickEventPacket.BuildPacket(actorId, actor.actorId, unknown, conditionName, lParams);
spacket.DebugPrintSubPacket(); spacket.DebugPrintSubPacket();
QueuePacket(spacket); QueuePacket(spacket);
} }
@ -2475,7 +2597,7 @@ namespace FFXIVClassic_Map_Server.Actors
base.CalculateBaseStats(); base.CalculateBaseStats();
//Add weapon property mod //Add weapon property mod
var equip = GetEquipment(); var equip = GetEquipment();
var mainHandItem = equip.GetItemAtSlot(Equipment.SLOT_MAINHAND); var mainHandItem = equip.GetItemAtSlot(SLOT_MAINHAND);
var damageAttribute = 0; var damageAttribute = 0;
var attackDelay = 3000; var attackDelay = 3000;
var hitCount = 1; var hitCount = 1;
@ -2549,5 +2671,120 @@ namespace FFXIVClassic_Map_Server.Actors
return equippedItem != null && equippedItem.itemId == itemId; return equippedItem != null && equippedItem.itemId == itemId;
} }
public Retainer GetSpawnedRetainer()
{
return currentSpawnedRetainer;
}
public void StartTradeTransaction(Player otherPlayer)
{
myOfferings = new ReferencedItemPackage(this, ItemPackage.MAXSIZE_TRADE, ItemPackage.TRADE);
otherTrader = otherPlayer;
isTradeAccepted = false;
}
public Player GetOtherTrader()
{
return otherTrader;
}
public ReferencedItemPackage GetTradeOfferings()
{
return myOfferings;
}
public bool IsTrading()
{
return otherTrader != null;
}
public bool IsTradeAccepted()
{
return isTradeAccepted;
}
public void AddTradeItem(ushort slot, ItemRefParam chosenItem, int tradeQuantity)
{
if (!IsTrading())
return;
//Get chosen item
InventoryItem offeredItem = itemPackages[chosenItem.itemPackage].GetItemAtSlot(chosenItem.slot);
offeredItem.SetTradeQuantity(tradeQuantity);
myOfferings.Set(slot, offeredItem);
SendTradePackets();
}
public void RemoveTradeItem(ushort slot)
{
if (!IsTrading())
return;
InventoryItem offeredItem = myOfferings.GetItemAtSlot(slot);
offeredItem.SetNormal();
myOfferings.Clear(slot);
SendTradePackets();
}
public void ClearTradeItems()
{
if (!IsTrading())
return;
for (ushort i = 0; i < myOfferings.GetCapacity(); i++)
{
InventoryItem offeredItem = myOfferings.GetItemAtSlot(i);
if (offeredItem != null)
offeredItem.SetNormal();
}
myOfferings.ClearAll();
SendTradePackets();
}
private void SendTradePackets()
{
//Send to self
QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
myOfferings.SendUpdate(this);
QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
//Send to other trader
otherTrader.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
myOfferings.SendUpdateAsItemPackage(otherTrader);
otherTrader.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
}
public void AcceptTrade(bool accepted)
{
if (!IsTrading())
return;
isTradeAccepted = accepted;
}
public void FinishTradeTransaction()
{
if (myOfferings != null)
{
myOfferings.ClearAll();
for (ushort i = 0; i < myOfferings.GetCapacity(); i++)
{
InventoryItem offeredItem = myOfferings.GetItemAtSlot(i);
if (offeredItem != null)
offeredItem.SetNormal();
}
QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
myOfferings.SendUpdate(this);
QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
}
isTradeAccepted = false;
myOfferings = null;
otherTrader = null;
}
} }
} }

View file

@ -8,7 +8,6 @@ using FFXIVClassic_Map_Server.packets.send.actor;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
namespace FFXIVClassic_Map_Server.actors.director namespace FFXIVClassic_Map_Server.actors.director
{ {

View file

@ -1,15 +1,10 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.actors.director.Work; using FFXIVClassic_Map_Server.actors.director.Work;
using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.utils; using FFXIVClassic_Map_Server.utils;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.director namespace FFXIVClassic_Map_Server.actors.director
{ {

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.director.Work
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.director.Work
{ {
class GuildleveWork class GuildleveWork

View file

@ -5,12 +5,7 @@ using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group; using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.send.groups; using FFXIVClassic_Map_Server.packets.send.groups;
using FFXIVClassic_Map_Server.utils;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group namespace FFXIVClassic_Map_Server.actors.group
{ {

View file

@ -1,16 +1,4 @@
using FFXIVClassic.Common; using FFXIVClassic_Map_Server.actors.director;
using FFXIVClassic_Map_Server.actors.director;
using FFXIVClassic_Map_Server.actors.group.Work;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.send.groups;
using FFXIVClassic_Map_Server.utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group namespace FFXIVClassic_Map_Server.actors.group
{ {

View file

@ -2,11 +2,7 @@
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group; using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.send.groups; using FFXIVClassic_Map_Server.packets.send.groups;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group namespace FFXIVClassic_Map_Server.actors.group
{ {

View file

@ -1,12 +1,6 @@
using FFXIVClassic.Common; using FFXIVClassic_Map_Server.actors.group.Work;
using FFXIVClassic_Map_Server.actors.group.Work;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group; using FFXIVClassic_Map_Server.packets.send.group;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group namespace FFXIVClassic_Map_Server.actors.group
{ {

View file

@ -3,21 +3,17 @@ using FFXIVClassic_Map_Server.actors.group.Work;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group; using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.send.groups; using FFXIVClassic_Map_Server.packets.send.groups;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group namespace FFXIVClassic_Map_Server.actors.group
{ {
class Relation : Group class RelationGroup : Group
{ {
public RelationWork work = new RelationWork(); public RelationWork work = new RelationWork();
private uint charaOther; private uint charaOther;
private ulong topicGroup; private ulong topicGroup;
public Relation(ulong groupIndex, uint host, uint other, uint command, ulong topicGroup) : base (groupIndex) public RelationGroup(ulong groupIndex, uint host, uint other, uint command, ulong topicGroup) : base (groupIndex)
{ {
this.charaOther = other; this.charaOther = other;
work._globalTemp.host = ((ulong)host << 32) | (0xc17909); work._globalTemp.host = ((ulong)host << 32) | (0xc17909);

View file

@ -4,11 +4,7 @@ using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group; using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.send.groups; using FFXIVClassic_Map_Server.packets.send.groups;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group namespace FFXIVClassic_Map_Server.actors.group
{ {

View file

@ -0,0 +1,73 @@
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.group.Work;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.send.groups;
using System.Collections.Generic;
namespace FFXIVClassic_Map_Server.actors.group
{
class TradeGroup : Group
{
public RelationWork work = new RelationWork();
private uint charaOther;
private ulong topicGroup;
public TradeGroup(ulong groupIndex, uint host, uint other)
: base(groupIndex)
{
this.charaOther = other;
work._globalTemp.host = ((ulong)host << 32) | (0xc17909);
work._globalTemp.variableCommand = 30001;
}
public uint GetHost()
{
return (uint)(((ulong)work._globalTemp.host >> 32) & 0xFFFFFFFF);
}
public uint GetOther()
{
return charaOther;
}
public override int GetMemberCount()
{
return 2;
}
public override uint GetTypeId()
{
return Group.TradeRelationGroup;
}
public ulong GetTopicGroupIndex()
{
return topicGroup;
}
public override List<GroupMember> BuildMemberList(uint id)
{
List<GroupMember> groupMembers = new List<GroupMember>();
uint hostId = (uint)((work._globalTemp.host >> 32) & 0xFFFFFFFF);
groupMembers.Add(new GroupMember(hostId, -1, 0, false, Server.GetServer().GetSession(hostId) != null, Server.GetWorldManager().GetActorInWorld(hostId).customDisplayName));
groupMembers.Add(new GroupMember(charaOther, -1, 0, false, Server.GetServer().GetSession(charaOther) != null, Server.GetWorldManager().GetActorInWorld(charaOther).customDisplayName));
return groupMembers;
}
public override void SendInitWorkValues(Session session)
{
SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupIndex);
groupWork.addProperty(this, "work._globalTemp.host");
groupWork.addProperty(this, "work._globalTemp.variableCommand");
groupWork.setTarget("/_init");
SubPacket test = groupWork.buildPacket(session.id);
test.DebugPrintSubPacket();
session.QueuePacket(test);
}
}
}

View file

@ -1,9 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.group.Work
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FFXIVClassic_Map_Server.actors.group.Work
{ {
class ContentGroupWork class ContentGroupWork
{ {

View file

@ -1,9 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.group.Work
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FFXIVClassic_Map_Server.actors.group.Work
{ {
class GlobalTemp class GlobalTemp
{ {

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.group.Work
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.Work
{ {
class GroupGlobalSave class GroupGlobalSave
{ {

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.group.Work
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.Work
{ {
class GroupGlobalTemp class GroupGlobalTemp
{ {

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.group.Work
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.Work
{ {
class GroupMemberSave class GroupMemberSave
{ {

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.group.Work
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.Work
{ {
class PartyWork class PartyWork
{ {

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.actors.group.Work
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.Work
{ {
class RelationWork class RelationWork
{ {

View file

@ -1,5 +1,4 @@
using FFXIVClassic.Common; using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.lua;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

View file

@ -1,9 +1,4 @@
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.dataobjects namespace FFXIVClassic_Map_Server.dataobjects
{ {

View file

@ -1,73 +1,149 @@
using System; using FFXIVClassic_Map_Server.Actors;
using System;
using System.IO; using System.IO;
namespace FFXIVClassic_Map_Server.dataobjects namespace FFXIVClassic_Map_Server.dataobjects
{ {
class InventoryItem class InventoryItem
{ {
public const byte DEALINGMODE_NONE = 0;
public const byte DEALINGMODE_REFERENCED = 1;
public const byte DEALINGMODE_PRICED = 2;
public const byte TAG_EXCLUSIVE = 0x3;
public const byte TAG_DEALING = 0xC9;
public const byte TAG_ATTACHED = 0xCA;
public const byte TYPE_SINGLE = 11;
public const byte TYPE_MULTI = 12;
public const byte TYPE_STACK = 13;
public const byte TYPE_SEEK_ITEM = 20;
public const byte TYPE_SEEK_REPAIR = 30;
public ulong uniqueId; public ulong uniqueId;
public uint itemId; public uint itemId;
public int quantity = 1; public int quantity = 1;
public ushort slot;
public byte itemType; public byte dealingVal = 0;
public byte dealingMode = DEALINGMODE_NONE;
public int dealingAttached1 = 0;
public int dealingAttached2 = 0;
public int dealingAttached3 = 0;
public byte[] tags = new byte[4];
public byte[] tagValues = new byte[4];
public byte quality = 1; public byte quality = 1;
public int durability = 0; private ulong attachedTo = 0;
public ushort spiritbind = 0;
public byte materia1 = 0; public ItemModifier modifiers;
public byte materia2 = 0;
public byte materia3 = 0; public readonly ItemData itemData;
public byte materia4 = 0; public Character owner = null;
public byte materia5 = 0; public ushort slot = 0xFFFF;
public ushort linkSlot = 0xFFFF;
public ushort itemPackage = 0xFFFF;
public class ItemModifier
{
public uint durability = 0;
public ushort use = 0;
public uint materiaId = 0;
public uint materiaLife = 0;
public byte mainQuality = 0;
public byte[] subQuality = new byte[3];
public uint polish = 0;
public uint param1 = 0;
public uint param2 = 0;
public uint param3 = 0;
public ushort spiritbind = 0;
public byte[] materiaType = new byte[5];
public byte[] materiaGrade = new byte[5];
public ItemModifier()
{
}
public ItemModifier(MySql.Data.MySqlClient.MySqlDataReader reader)
{
durability = reader.GetUInt32("durability");
mainQuality = reader.GetByte("mainQuality");
subQuality[0] = reader.GetByte("subQuality1");
subQuality[1] = reader.GetByte("subQuality2");
subQuality[2] = reader.GetByte("subQuality3");
param1 = reader.GetUInt32("param1");
param2 = reader.GetUInt32("param2");
param3 = reader.GetUInt32("param3");
spiritbind = reader.GetUInt16("spiritbind");
ushort materia1 = reader.GetUInt16("materia1");
ushort materia2 = reader.GetUInt16("materia2");
ushort materia3 = reader.GetUInt16("materia3");
ushort materia4 = reader.GetUInt16("materia4");
ushort materia5 = reader.GetUInt16("materia5");
materiaType[0] = (byte)(materia1 & 0xFF);
materiaGrade[0] = (byte)((materia1 >> 8) & 0xFF);
materiaType[1] = (byte)(materia2 & 0xFF);
materiaGrade[1] = (byte)((materia2 >> 8) & 0xFF);
materiaType[2] = (byte)(materia3 & 0xFF);
materiaGrade[2] = (byte)((materia3 >> 8) & 0xFF);
materiaType[3] = (byte)(materia4 & 0xFF);
materiaGrade[3] = (byte)((materia4 >> 8) & 0xFF);
materiaType[4] = (byte)(materia5 & 0xFF);
materiaGrade[4] = (byte)((materia5 >> 8) & 0xFF);
}
public void WriteBytes(BinaryWriter binWriter)
{
binWriter.Write((UInt32) durability);
binWriter.Write((UInt16) use);
binWriter.Write((UInt32) materiaId);
binWriter.Write((UInt32) materiaLife);
binWriter.Write((Byte) mainQuality);
binWriter.Write((Byte) subQuality[0]);
binWriter.Write((Byte) subQuality[1]);
binWriter.Write((Byte) subQuality[2]);
binWriter.Write((UInt32) polish);
binWriter.Write((UInt32) param1);
binWriter.Write((UInt32) param2);
binWriter.Write((UInt32) param3);
binWriter.Write((UInt16) spiritbind);
binWriter.Write((Byte) materiaType[0]);
binWriter.Write((Byte) materiaType[1]);
binWriter.Write((Byte) materiaType[2]);
binWriter.Write((Byte) materiaType[3]);
binWriter.Write((Byte) materiaType[4]);
binWriter.Write((Byte) materiaGrade[0]);
binWriter.Write((Byte) materiaGrade[1]);
binWriter.Write((Byte) materiaGrade[2]);
binWriter.Write((Byte) materiaGrade[3]);
binWriter.Write((Byte) materiaGrade[4]);
}
}
//Bare Minimum //Bare Minimum
public InventoryItem(uint id, uint itemId) public InventoryItem(uint id, ItemData data)
{ {
this.uniqueId = id; this.uniqueId = id;
this.itemId = itemId; this.itemId = data.catalogID;
this.itemData = data;
this.quantity = 1; this.quantity = 1;
ItemData gItem = Server.GetItemGamedata(itemId); tags[1] = itemData.isExclusive ? TAG_EXCLUSIVE : (byte)0;
itemType = gItem.isExclusive ? (byte)0x3 : (byte)0x0;
} }
//For check command public InventoryItem(uint uniqueId, ItemData itemData, int quantity, byte qualityNumber, ItemModifier modifiers = null)
public InventoryItem(InventoryItem item, ushort equipSlot)
{
this.uniqueId = item.uniqueId;
this.itemId = item.itemId;
this.quantity = item.quantity;
this.slot = equipSlot;
this.itemType = item.itemType;
this.quality = item.quality;
this.durability = item.durability;
this.spiritbind = item.spiritbind;
this.materia1 = item.materia1;
this.materia2 = item.materia2;
this.materia3 = item.materia3;
this.materia4 = item.materia4;
this.materia5 = item.materia5;
}
public InventoryItem(uint uniqueId, uint itemId, int quantity, byte itemType, byte qualityNumber, int durability, ushort spiritbind, byte materia1, byte materia2, byte materia3, byte materia4, byte materia5)
{ {
this.uniqueId = uniqueId; this.uniqueId = uniqueId;
this.itemId = itemId; this.itemId = itemData.catalogID;
this.itemData = itemData;
this.quantity = quantity; this.quantity = quantity;
this.itemType = itemType;
this.quality = qualityNumber; this.quality = qualityNumber;
this.durability = durability; this.modifiers = modifiers;
this.spiritbind = spiritbind;
this.materia1 = materia1; tags[1] = itemData.isExclusive ? TAG_EXCLUSIVE : (byte)0;
this.materia2 = materia2;
this.materia3 = materia3;
this.materia4 = materia4;
this.materia5 = materia5;
} }
public byte[] ToPacketBytes() public byte[] ToPacketBytes()
@ -81,42 +157,174 @@ namespace FFXIVClassic_Map_Server.dataobjects
binWriter.Write((UInt64)uniqueId); binWriter.Write((UInt64)uniqueId);
binWriter.Write((Int32)quantity); binWriter.Write((Int32)quantity);
binWriter.Write((UInt32)itemId); binWriter.Write((UInt32)itemId);
binWriter.Write((UInt16)slot);
binWriter.Write((UInt16)0x0001); if (linkSlot == 0xFFFF)
binWriter.Write((UInt32)0x00000000); binWriter.Write((UInt16)slot);
binWriter.Write((UInt32)0x00000000); else
binWriter.Write((UInt32)0x00000000); binWriter.Write((UInt16)linkSlot);
linkSlot = 0xFFFF;
binWriter.Write((UInt32)itemType); binWriter.Write((Byte)dealingVal);
binWriter.Write((Byte)dealingMode);
binWriter.Write((UInt32)0x00000000); binWriter.Write((UInt32)dealingAttached1);
binWriter.Write((UInt32)dealingAttached2);
binWriter.Write((UInt32)dealingAttached3);
binWriter.Write((byte)quality); for (int i = 0; i < tags.Length; i++)
binWriter.Write((byte)0x01); binWriter.Write((Byte) tags[i]);
binWriter.Write((uint)durability); for (int i = 0; i < tagValues.Length; i++)
binWriter.Write((Byte) tagValues[i]);
binWriter.BaseStream.Seek(0x10-0x06, SeekOrigin.Current); binWriter.Write((Byte)quality);
binWriter.Write((byte)0x01); if (modifiers != null)
binWriter.Write((byte)0x01); {
binWriter.Write((byte)0x01); binWriter.Write((Byte)0x01);
binWriter.Write((byte)0x01); modifiers.WriteBytes(binWriter);
}
binWriter.BaseStream.Seek(0x10, SeekOrigin.Current);
binWriter.Write((ushort)spiritbind);
binWriter.Write((byte)materia1);
binWriter.Write((byte)materia2);
binWriter.Write((byte)materia3);
binWriter.Write((byte)materia4);
binWriter.Write((byte)materia5);
} }
} }
return data; return data;
} }
public void SetQuantity(uint quantity)
{
lock (owner.GetItemPackage(itemPackage))
{
this.quantity = (int)quantity;
if (quantity < 0)
quantity = 0;
Database.SetQuantity(uniqueId, this.quantity);
if (owner != null)
owner.GetItemPackage(itemPackage).MarkDirty(this);
}
}
public void ChangeQuantity(int quantityDelta)
{
lock (owner.GetItemPackage(itemPackage))
{
this.quantity += quantityDelta;
if (quantity < 0)
quantity = 0;
if (quantity == 0)
{
owner.RemoveItem(this);
return;
}
Database.SetQuantity(uniqueId, this.quantity);
if (owner != null)
owner.GetItemPackage(itemPackage).MarkDirty(this);
}
}
public void RefreshPositioning(Character owner, ushort itemPackage, ushort slot)
{
this.owner = owner;
this.itemPackage = itemPackage;
this.slot = slot;
}
public void SetHasAttached(bool isAttached)
{
tags[0] = isAttached ? TAG_ATTACHED : (byte)0;
}
public void SetNormal()
{
tags[0] = 0;
tagValues[0] = 0;
attachedTo = 0;
dealingVal = 0;
dealingMode = 0;
dealingAttached1 = 0;
dealingAttached2 = 0;
dealingAttached3 = 0;
if (owner != null)
owner.GetItemPackage(itemPackage).MarkDirty(this);
}
public void SetDealing(byte mode, int price)
{
tags[0] = TAG_DEALING;
tagValues[0] = mode;
if (mode == TYPE_SINGLE || mode == TYPE_MULTI || mode == TYPE_STACK)
{
dealingVal = 1;
dealingMode = DEALINGMODE_PRICED;
dealingAttached1 = 1;
dealingAttached2 = price;
dealingAttached3 = 0;
}
if (owner != null)
owner.GetItemPackage(itemPackage).MarkDirty(this);
}
public void SetDealingAttached(byte mode, ulong attached)
{
tags[0] = TAG_DEALING;
tagValues[0] = mode;
attachedTo = attached;
if (owner != null)
owner.GetItemPackage(itemPackage).MarkDirty(this);
}
public ulong GetAttached()
{
return attachedTo;
}
public void SetAttachedIndex(ushort package, ushort index)
{
dealingVal = 1;
dealingMode = DEALINGMODE_REFERENCED;
dealingAttached1 = ((package << 16) | index);
dealingAttached2 = 0;
dealingAttached3 = 0;
if (owner != null)
owner.GetItemPackage(itemPackage).MarkDirty(this);
}
public void SetTradeQuantity(int quantity)
{
dealingAttached3 = quantity;
if (owner != null)
owner.GetItemPackage(itemPackage).MarkDirty(this);
}
public int GetTradeQuantity()
{
return dealingAttached3;
}
public ItemData GetItemData()
{
return itemData;
}
public byte GetBazaarMode()
{
if (tags[0] == 0xC9)
return tagValues[0];
return 0;
}
public bool IsSelling()
{
return GetBazaarMode() == TYPE_SINGLE || GetBazaarMode() == TYPE_MULTI || GetBazaarMode() == TYPE_STACK;
}
} }
} }

View file

@ -1,10 +1,4 @@
using System; namespace FFXIVClassic_Map_Server.dataobjects
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.dataobjects
{ {
class SeamlessBoundry class SeamlessBoundry
{ {

View file

@ -0,0 +1,3 @@
namespace FFXIVClassic_Map_Server.dataobjects
{
}

View file

@ -4,7 +4,6 @@ using System.Net.Sockets;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net; using System.Net;
using System.Collections.Generic;
using FFXIVClassic_Map_Server.packets.WorldPackets.Send; using FFXIVClassic_Map_Server.packets.WorldPackets.Send;
namespace FFXIVClassic_Map_Server.dataobjects namespace FFXIVClassic_Map_Server.dataobjects
@ -19,7 +18,7 @@ namespace FFXIVClassic_Map_Server.dataobjects
public void QueuePacket(SubPacket subpacket) public void QueuePacket(SubPacket subpacket)
{ {
if(SendPacketQueue.Count == 1000) if (SendPacketQueue.Count == SendPacketQueue.BoundedCapacity - 1)
FlushQueuedSendPackets(); FlushQueuedSendPackets();
SendPacketQueue.Add(subpacket); SendPacketQueue.Add(subpacket);

View file

@ -11,8 +11,6 @@ using MoonSharp.Interpreter.Loaders;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Diagnostics;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.area; using FFXIVClassic_Map_Server.actors.area;
using System.Threading; using System.Threading;
@ -93,7 +91,7 @@ namespace FFXIVClassic_Map_Server.lua
} }
} }
public void OnSignal(string signal) public void OnSignal(string signal, params object[] args)
{ {
List<Coroutine> mToAwake = new List<Coroutine>(); List<Coroutine> mToAwake = new List<Coroutine>();
@ -105,7 +103,7 @@ namespace FFXIVClassic_Map_Server.lua
foreach (Coroutine key in mToAwake) foreach (Coroutine key in mToAwake)
{ {
DynValue value = key.Resume(); DynValue value = key.Resume(args);
ResolveResume(null, key, value); ResolveResume(null, key, value);
} }
} }
@ -642,6 +640,7 @@ namespace FFXIVClassic_Map_Server.lua
public static void RunGMCommand(Player player, String cmd, string[] param, bool help = false) public static void RunGMCommand(Player player, String cmd, string[] param, bool help = false)
{ {
bool playerNull = player == null; bool playerNull = player == null;
if (playerNull) if (playerNull)
{ {
if (param.Length >= 2 && param[1].Contains("\"")) if (param.Length >= 2 && param[1].Contains("\""))
@ -649,6 +648,10 @@ namespace FFXIVClassic_Map_Server.lua
else if (param.Length > 2) else if (param.Length > 2)
player = Server.GetWorldManager().GetPCInWorld(param[1] + param[2]); player = Server.GetWorldManager().GetPCInWorld(param[1] + param[2]);
} }
if (playerNull && param.Length >= 3)
player = Server.GetWorldManager().GetPCInWorld(param[1] + " " + param[2]);
// load from scripts/commands/gm/ directory // load from scripts/commands/gm/ directory
var path = String.Format("./scripts/commands/gm/{0}.lua", cmd.ToLower()); var path = String.Format("./scripts/commands/gm/{0}.lua", cmd.ToLower());

View file

@ -1,9 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MoonSharp;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
using NLog; using NLog;
using MoonSharp.Interpreter.Debugging; using MoonSharp.Interpreter.Debugging;

View file

@ -12,19 +12,37 @@ namespace FFXIVClassic_Map_Server
class LuaUtils class LuaUtils
{ {
public class Type7Param public class ItemRefParam
{ {
public uint actorId; public uint actorId;
public byte unknown; public byte unknown;
public byte slot; public byte slot;
public byte inventoryType; public byte itemPackage;
public Type7Param(uint actorId, byte unknown, byte slot, byte inventoryType) public ItemRefParam(uint actorId, byte unknown, byte slot, byte itemPackage)
{ {
this.actorId = actorId; this.actorId = actorId;
this.unknown = unknown; this.unknown = unknown;
this.slot = slot; this.slot = slot;
this.inventoryType = inventoryType; this.itemPackage = itemPackage;
}
}
public class ItemOfferParam
{
public uint actorId;
public ushort offerSlot;
public ushort unknown1;
public ushort seekSlot;
public ushort unknown2;
public ItemOfferParam(uint actorId, ushort unknown1, ushort offerSlot, ushort seekSlot, ushort unknown2)
{
this.actorId = actorId;
this.unknown1 = unknown1;
this.offerSlot = offerSlot;
this.seekSlot = seekSlot;
this.unknown2 = unknown2;
} }
} }
@ -81,12 +99,24 @@ namespace FFXIVClassic_Map_Server
case 0x6: //Actor (By Id) case 0x6: //Actor (By Id)
value = Utils.SwapEndian(reader.ReadUInt32()); value = Utils.SwapEndian(reader.ReadUInt32());
break; break;
case 0x7: //Weird one used for inventory case 0x7: //Item Reference to Inventory Spot
uint type7ActorId = Utils.SwapEndian(reader.ReadUInt32()); {
byte type7Unknown = reader.ReadByte(); uint type7ActorId = Utils.SwapEndian(reader.ReadUInt32());
byte type7Slot = reader.ReadByte(); byte type7Unknown = reader.ReadByte();
byte type7InventoryType = reader.ReadByte(); byte type7Slot = reader.ReadByte();
value = new Type7Param(type7ActorId, type7Unknown, type7Slot, type7InventoryType); byte type7InventoryType = reader.ReadByte();
value = new ItemRefParam(type7ActorId, type7Unknown, type7Slot, type7InventoryType);
}
break;
case 0x8: //Used for offering
{
uint actorId = Utils.SwapEndian(reader.ReadUInt32());
ushort unk1 = Utils.SwapEndian(reader.ReadUInt16());
ushort offerSlot = Utils.SwapEndian(reader.ReadUInt16());
ushort seekSlot = Utils.SwapEndian(reader.ReadUInt16());
ushort unk2 = Utils.SwapEndian(reader.ReadUInt16());
value = new ItemOfferParam(actorId, unk1, offerSlot, seekSlot, unk2);
}
break; break;
case 0x9: //Two Longs (only storing first one) case 0x9: //Two Longs (only storing first one)
value = new Type9Param(Utils.SwapEndian(reader.ReadUInt64()), Utils.SwapEndian(reader.ReadUInt64())); value = new Type9Param(Utils.SwapEndian(reader.ReadUInt64()), Utils.SwapEndian(reader.ReadUInt64()));
@ -105,7 +135,13 @@ namespace FFXIVClassic_Map_Server
if (isDone) if (isDone)
break; break;
if (value != null) //Special case cause fuck Type8
if (value != null && value is ItemOfferParam)
{
luaParams.Add(new LuaParam(code, value));
luaParams.Add(new LuaParam(5, null));
}
else if (value != null)
luaParams.Add(new LuaParam(code, value)); luaParams.Add(new LuaParam(code, value));
else if (wasNil) else if (wasNil)
luaParams.Add(new LuaParam(code, value)); luaParams.Add(new LuaParam(code, value));
@ -152,11 +188,11 @@ namespace FFXIVClassic_Map_Server
writer.Write((UInt32)Utils.SwapEndian((UInt32)l.value)); writer.Write((UInt32)Utils.SwapEndian((UInt32)l.value));
break; break;
case 0x7: //Weird one used for inventory case 0x7: //Weird one used for inventory
Type7Param type7 = (Type7Param)l.value; ItemRefParam type7 = (ItemRefParam)l.value;
writer.Write((UInt32)Utils.SwapEndian((UInt32)type7.actorId)); writer.Write((UInt32)Utils.SwapEndian((UInt32)type7.actorId));
writer.Write((Byte)type7.unknown); writer.Write((Byte)type7.unknown);
writer.Write((Byte)type7.slot); writer.Write((Byte)type7.slot);
writer.Write((Byte)type7.inventoryType); writer.Write((Byte)type7.itemPackage);
break; break;
case 0x9: //Two Longs (only storing first one) case 0x9: //Two Longs (only storing first one)
writer.Write((UInt64)Utils.SwapEndian(((Type9Param)l.value).item1)); writer.Write((UInt64)Utils.SwapEndian(((Type9Param)l.value).item1));
@ -226,7 +262,7 @@ namespace FFXIVClassic_Map_Server
byte type7Unknown = reader.ReadByte(); byte type7Unknown = reader.ReadByte();
byte type7Slot = reader.ReadByte(); byte type7Slot = reader.ReadByte();
byte type7InventoryType = reader.ReadByte(); byte type7InventoryType = reader.ReadByte();
value = new Type7Param(type7ActorId, type7Unknown, type7Slot, type7InventoryType); value = new ItemRefParam(type7ActorId, type7Unknown, type7Slot, type7InventoryType);
break; break;
case 0x9: //Two Longs (only storing first one) case 0x9: //Two Longs (only storing first one)
value = new Type9Param(Utils.SwapEndian(reader.ReadUInt64()), Utils.SwapEndian(reader.ReadUInt64())); value = new Type9Param(Utils.SwapEndian(reader.ReadUInt64()), Utils.SwapEndian(reader.ReadUInt64()));
@ -359,9 +395,13 @@ namespace FFXIVClassic_Map_Server
{ {
luaParams.Add(new LuaParam(0x6, ((Actor)o).actorId)); luaParams.Add(new LuaParam(0x6, ((Actor)o).actorId));
} }
else if (o is Type7Param) else if (o is ItemRefParam)
{ {
luaParams.Add(new LuaParam(0x7, (Type7Param)o)); luaParams.Add(new LuaParam(0x7, (ItemRefParam)o));
}
else if (o is ItemOfferParam)
{
luaParams.Add(new LuaParam(0x8, (ItemOfferParam)o));
} }
else if (o is Type9Param) else if (o is Type9Param)
{ {
@ -416,16 +456,20 @@ namespace FFXIVClassic_Map_Server
dumpString += String.Format("0x{0:X}", (uint)lParams[i].value); dumpString += String.Format("0x{0:X}", (uint)lParams[i].value);
break; break;
case 0x7: //Weird one used for inventory case 0x7: //Weird one used for inventory
Type7Param type7Param = ((Type7Param)lParams[i].value); ItemRefParam type7Param = ((ItemRefParam)lParams[i].value);
dumpString += String.Format("Type7 Param: (0x{0:X}, 0x{1:X}, 0x{2:X}, 0x{3:X})", type7Param.actorId, type7Param.unknown, type7Param.slot, type7Param.inventoryType); dumpString += String.Format("Type7 Param: (0x{0:X}, 0x{1:X}, 0x{2:X}, 0x{3:X})", type7Param.actorId, type7Param.unknown, type7Param.slot, type7Param.itemPackage);
break; break;
case 0xC: //Byte case 0x8: //Weird one used for inventory
dumpString += String.Format("0x{0:X}", (byte)lParams[i].value); ItemOfferParam itemOfferParam = ((ItemOfferParam)lParams[i].value);
dumpString += String.Format("Type8 Param: (0x{0:X}, 0x{1:X}, 0x{2:X}, 0x{3:X}, 0x{4:X})", itemOfferParam.actorId, itemOfferParam.unknown1, itemOfferParam.offerSlot, itemOfferParam.seekSlot, itemOfferParam.unknown2);
break; break;
case 0x9: //Long (+ 8 bytes ignored) case 0x9: //Long (+ 8 bytes ignored)
Type9Param type9Param = ((Type9Param)lParams[i].value); Type9Param type9Param = ((Type9Param)lParams[i].value);
dumpString += String.Format("Type9 Param: (0x{0:X}, 0x{1:X})", type9Param.item1, type9Param.item2); dumpString += String.Format("Type9 Param: (0x{0:X}, 0x{1:X})", type9Param.item1, type9Param.item2);
break; break;
case 0xC: //Byte
dumpString += String.Format("0x{0:X}", (byte)lParams[i].value);
break;
case 0x1B: //Short? case 0x1B: //Short?
dumpString += String.Format("0x{0:X}", (ushort)lParams[i].value); dumpString += String.Format("0x{0:X}", (ushort)lParams[i].value);
break; break;

View file

@ -1,9 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive
{ {

View file

@ -0,0 +1,31 @@
using System;
using System.IO;
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive
{
class LinkshellResultPacket
{
public int resultCode;
public bool invalidPacket = false;
public LinkshellResultPacket(byte[] data)
{
using (MemoryStream mem = new MemoryStream(data))
{
using (BinaryReader binReader = new BinaryReader(mem))
{
try
{
resultCode = binReader.ReadInt32();
}
catch (Exception)
{
invalidPacket = true;
}
}
}
}
}
}

View file

@ -1,10 +1,5 @@
using FFXIVClassic_Map_Server.actors.group; using System;
using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive
{ {

View file

@ -1,9 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive
{ {

View file

@ -1,9 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive
{ {

View file

@ -1,7 +1,6 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
@ -20,6 +19,7 @@ namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group
using (BinaryWriter binWriter = new BinaryWriter(mem)) using (BinaryWriter binWriter = new BinaryWriter(mem))
{ {
binWriter.Write(Encoding.ASCII.GetBytes(name), 0, Encoding.ASCII.GetByteCount(name) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(name)); binWriter.Write(Encoding.ASCII.GetBytes(name), 0, Encoding.ASCII.GetByteCount(name) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(name));
binWriter.BaseStream.Seek(0x20, SeekOrigin.Begin);
binWriter.Write((UInt16)crest); binWriter.Write((UInt16)crest);
binWriter.Write((UInt32)master); binWriter.Write((UInt32)master);
} }

View file

@ -1,6 +1,5 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using System;
using System.IO; using System.IO;
using System.Text; using System.Text;

View file

@ -1,11 +1,7 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group
{ {

View file

@ -1,8 +1,5 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;

View file

@ -1,11 +1,5 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group
{ {

View file

@ -1,11 +1,8 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group
{ {

View file

@ -1,8 +1,6 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;

View file

@ -1,8 +1,6 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;

View file

@ -1,11 +1,8 @@
using FFXIVClassic.Common; using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group
{ {

Some files were not shown because too many files have changed in this diff Show more