mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-24 13:47:46 +00:00
Implemented equipment and equip graphics. Add some zone callbacks and "first start" functionality. Added playtime.
This commit is contained in:
parent
c9116005d6
commit
44e5430fdc
17 changed files with 676 additions and 129 deletions
|
@ -63,6 +63,11 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
return String.Format("{0}:{1}", (socket.RemoteEndPoint as IPEndPoint).Address, (socket.RemoteEndPoint as IPEndPoint).Port);
|
return String.Format("{0}:{1}", (socket.RemoteEndPoint as IPEndPoint).Address, (socket.RemoteEndPoint as IPEndPoint).Port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool isConnected()
|
||||||
|
{
|
||||||
|
return (socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
|
||||||
|
}
|
||||||
|
|
||||||
public void disconnect()
|
public void disconnect()
|
||||||
{
|
{
|
||||||
if (socket.Connected)
|
if (socket.Connected)
|
||||||
|
|
|
@ -150,6 +150,132 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void savePlayerAppearance(Player player)
|
||||||
|
{
|
||||||
|
string query;
|
||||||
|
MySqlCommand cmd;
|
||||||
|
|
||||||
|
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 = @"
|
||||||
|
UPDATE characters_appearance SET
|
||||||
|
mainHand = @mainHand,
|
||||||
|
offHand = @offHand,
|
||||||
|
head = @head,
|
||||||
|
body = @body,
|
||||||
|
legs = @legs,
|
||||||
|
hands = @hands,
|
||||||
|
feet = @feet,
|
||||||
|
waist = @waist,
|
||||||
|
leftFinger = @leftFinger,
|
||||||
|
rightFinger = @rightFinger,
|
||||||
|
leftEar = @leftEar,
|
||||||
|
rightEar = @rightEar
|
||||||
|
WHERE characterId = @charaId
|
||||||
|
";
|
||||||
|
|
||||||
|
cmd = new MySqlCommand(query, conn);
|
||||||
|
cmd.Parameters.AddWithValue("@charaId", player.actorId);
|
||||||
|
cmd.Parameters.AddWithValue("@mainHand", player.appearanceIds[Character.MAINHAND]);
|
||||||
|
cmd.Parameters.AddWithValue("@offHand", player.appearanceIds[Character.OFFHAND]);
|
||||||
|
cmd.Parameters.AddWithValue("@head", player.appearanceIds[Character.HEADGEAR]);
|
||||||
|
cmd.Parameters.AddWithValue("@body", player.appearanceIds[Character.BODYGEAR]);
|
||||||
|
cmd.Parameters.AddWithValue("@legs", player.appearanceIds[Character.LEGSGEAR]);
|
||||||
|
cmd.Parameters.AddWithValue("@hands", player.appearanceIds[Character.HANDSGEAR]);
|
||||||
|
cmd.Parameters.AddWithValue("@feet", player.appearanceIds[Character.FEETGEAR]);
|
||||||
|
cmd.Parameters.AddWithValue("@waist", player.appearanceIds[Character.WAISTGEAR]);
|
||||||
|
cmd.Parameters.AddWithValue("@leftFinger", player.appearanceIds[Character.L_RINGFINGER]);
|
||||||
|
cmd.Parameters.AddWithValue("@rightFinger", player.appearanceIds[Character.R_RINGFINGER]);
|
||||||
|
cmd.Parameters.AddWithValue("@leftEar", player.appearanceIds[Character.L_EAR]);
|
||||||
|
cmd.Parameters.AddWithValue("@rightEar", player.appearanceIds[Character.R_EAR]);
|
||||||
|
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
catch (MySqlException e)
|
||||||
|
{ Console.WriteLine(e); }
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
conn.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void savePlayerPosition(Player player)
|
||||||
|
{
|
||||||
|
string query;
|
||||||
|
MySqlCommand cmd;
|
||||||
|
|
||||||
|
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 = @"
|
||||||
|
UPDATE characters SET
|
||||||
|
positionX = @x,
|
||||||
|
positionY = @y,
|
||||||
|
positionZ = @z,
|
||||||
|
rotation = @rot,
|
||||||
|
currentZoneId = @zoneId
|
||||||
|
WHERE id = @charaId
|
||||||
|
";
|
||||||
|
|
||||||
|
cmd = new MySqlCommand(query, conn);
|
||||||
|
cmd.Parameters.AddWithValue("@charaId", player.actorId);
|
||||||
|
cmd.Parameters.AddWithValue("@x", player.positionX);
|
||||||
|
cmd.Parameters.AddWithValue("@y", player.positionY);
|
||||||
|
cmd.Parameters.AddWithValue("@z", player.positionZ);
|
||||||
|
cmd.Parameters.AddWithValue("@rot", player.rotation);
|
||||||
|
cmd.Parameters.AddWithValue("@zoneId", player.zoneId);
|
||||||
|
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
catch (MySqlException e)
|
||||||
|
{ Console.WriteLine(e); }
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
conn.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void savePlayerPlayTime(Player player)
|
||||||
|
{
|
||||||
|
string query;
|
||||||
|
MySqlCommand cmd;
|
||||||
|
|
||||||
|
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 = @"
|
||||||
|
UPDATE characters SET
|
||||||
|
playTime = @playtime
|
||||||
|
WHERE id = @charaId
|
||||||
|
";
|
||||||
|
|
||||||
|
cmd = new MySqlCommand(query, conn);
|
||||||
|
cmd.Parameters.AddWithValue("@charaId", player.actorId);
|
||||||
|
cmd.Parameters.AddWithValue("@playtime", player.getPlayTime(true));
|
||||||
|
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
catch (MySqlException e)
|
||||||
|
{ Console.WriteLine(e); }
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
conn.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void loadPlayerCharacter(Player player)
|
public static void loadPlayerCharacter(Player player)
|
||||||
{
|
{
|
||||||
string query;
|
string query;
|
||||||
|
@ -184,7 +310,8 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
tribe,
|
tribe,
|
||||||
currentParty,
|
currentParty,
|
||||||
restBonus,
|
restBonus,
|
||||||
achievementPoints
|
achievementPoints,
|
||||||
|
playTime
|
||||||
FROM characters WHERE id = @charId";
|
FROM characters WHERE id = @charId";
|
||||||
|
|
||||||
cmd = new MySqlCommand(query, conn);
|
cmd = new MySqlCommand(query, conn);
|
||||||
|
@ -214,10 +341,11 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
player.playerWork.tribe = reader.GetByte(17);
|
player.playerWork.tribe = reader.GetByte(17);
|
||||||
player.playerWork.restBonusExpRate = reader.GetInt32(19);
|
player.playerWork.restBonusExpRate = reader.GetInt32(19);
|
||||||
player.achievementPoints = reader.GetUInt32(20);
|
player.achievementPoints = reader.GetUInt32(20);
|
||||||
|
player.playTime = reader.GetUInt32(21);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
player.charaWork.parameterSave.state_mainSkillLevel = 49;
|
player.charaWork.parameterSave.state_mainSkillLevel = 50;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
//Get level of our classjob
|
//Get level of our classjob
|
||||||
|
@ -312,8 +440,8 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
player.appearanceIds[Character.FACEINFO] = PrimitiveConversion.ToUInt32(CharacterUtils.getFaceInfo(reader.GetByte(8), reader.GetByte(9), reader.GetByte(10), reader.GetByte(11), reader.GetByte(12), reader.GetByte(13), reader.GetByte(14), reader.GetByte(15), reader.GetByte(16), reader.GetByte(17)));
|
player.appearanceIds[Character.FACEINFO] = PrimitiveConversion.ToUInt32(CharacterUtils.getFaceInfo(reader.GetByte(8), reader.GetByte(9), reader.GetByte(10), reader.GetByte(11), reader.GetByte(12), reader.GetByte(13), reader.GetByte(14), reader.GetByte(15), reader.GetByte(16), reader.GetByte(17)));
|
||||||
player.appearanceIds[Character.HIGHLIGHT_HAIR] = (uint)(reader.GetUInt16(6) | reader.GetUInt16(4) << 10);
|
player.appearanceIds[Character.HIGHLIGHT_HAIR] = (uint)(reader.GetUInt16(6) | reader.GetUInt16(4) << 10);
|
||||||
player.appearanceIds[Character.VOICE] = reader.GetByte(2);
|
player.appearanceIds[Character.VOICE] = reader.GetByte(2);
|
||||||
player.appearanceIds[Character.WEAPON1] = reader.GetUInt32(18);
|
player.appearanceIds[Character.MAINHAND] = reader.GetUInt32(18);
|
||||||
player.appearanceIds[Character.WEAPON2] = reader.GetUInt32(19);
|
player.appearanceIds[Character.OFFHAND] = reader.GetUInt32(19);
|
||||||
player.appearanceIds[Character.HEADGEAR] = reader.GetUInt32(20);
|
player.appearanceIds[Character.HEADGEAR] = reader.GetUInt32(20);
|
||||||
player.appearanceIds[Character.BODYGEAR] = reader.GetUInt32(21);
|
player.appearanceIds[Character.BODYGEAR] = reader.GetUInt32(21);
|
||||||
player.appearanceIds[Character.LEGSGEAR] = reader.GetUInt32(22);
|
player.appearanceIds[Character.LEGSGEAR] = reader.GetUInt32(22);
|
||||||
|
@ -322,8 +450,8 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
player.appearanceIds[Character.WAISTGEAR] = reader.GetUInt32(25);
|
player.appearanceIds[Character.WAISTGEAR] = reader.GetUInt32(25);
|
||||||
player.appearanceIds[Character.R_EAR] = reader.GetUInt32(26);
|
player.appearanceIds[Character.R_EAR] = reader.GetUInt32(26);
|
||||||
player.appearanceIds[Character.L_EAR] = reader.GetUInt32(27);
|
player.appearanceIds[Character.L_EAR] = reader.GetUInt32(27);
|
||||||
player.appearanceIds[Character.R_FINGER] = reader.GetUInt32(28);
|
player.appearanceIds[Character.R_RINGFINGER] = reader.GetUInt32(28);
|
||||||
player.appearanceIds[Character.L_FINGER] = reader.GetUInt32(29);
|
player.appearanceIds[Character.L_RINGFINGER] = reader.GetUInt32(29);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -947,5 +1075,6 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
return cheevosPacket.buildPacket(player.actorId);
|
return cheevosPacket.buildPacket(player.actorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,8 +146,6 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
}
|
}
|
||||||
else if (subpacket.header.type == 0x07)
|
else if (subpacket.header.type == 0x07)
|
||||||
{
|
{
|
||||||
//Ping?
|
|
||||||
//packet.debugPrintPacket();
|
|
||||||
BasePacket init = Login0x7ResponsePacket.buildPacket(BitConverter.ToUInt32(packet.data, 0x10), Utils.UnixTimeStampUTC());
|
BasePacket init = Login0x7ResponsePacket.buildPacket(BitConverter.ToUInt32(packet.data, 0x10), Utils.UnixTimeStampUTC());
|
||||||
//client.queuePacket(init);
|
//client.queuePacket(init);
|
||||||
}
|
}
|
||||||
|
@ -174,6 +172,7 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
//subpacket.debugPrintSubPacket();
|
//subpacket.debugPrintSubPacket();
|
||||||
PingPacket pingPacket = new PingPacket(subpacket.data);
|
PingPacket pingPacket = new PingPacket(subpacket.data);
|
||||||
client.queuePacket(BasePacket.createPacket(PongPacket.buildPacket(player.actorID, pingPacket.time), true, false));
|
client.queuePacket(BasePacket.createPacket(PongPacket.buildPacket(player.actorID, pingPacket.time), true, false));
|
||||||
|
player.ping();
|
||||||
break;
|
break;
|
||||||
//Unknown
|
//Unknown
|
||||||
case 0x0002:
|
case 0x0002:
|
||||||
|
@ -254,7 +253,7 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mServer.GetLuaEngine().doActorOnEventStarted(player.getActor(), ownerActor, eventStart);
|
LuaEngine.doActorOnEventStarted(player.getActor(), ownerActor, eventStart);
|
||||||
|
|
||||||
Log.debug(String.Format("\n===Event START===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nEvent Starter: {4}\nParams: {5}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.val1, eventStart.val2, eventStart.eventStarter, LuaUtils.dumpParams(eventStart.luaParams)));
|
Log.debug(String.Format("\n===Event START===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nEvent Starter: {4}\nParams: {5}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.val1, eventStart.val2, eventStart.eventStarter, LuaUtils.dumpParams(eventStart.luaParams)));
|
||||||
break;
|
break;
|
||||||
|
@ -273,7 +272,7 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mServer.GetLuaEngine().doActorOnEventUpdated(player.getActor(), updateOwnerActor, eventUpdate);
|
LuaEngine.doActorOnEventUpdated(player.getActor(), updateOwnerActor, eventUpdate);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 0x012F:
|
case 0x012F:
|
||||||
|
|
|
@ -23,6 +23,14 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
#endif
|
#endif
|
||||||
bool startServer = true;
|
bool startServer = true;
|
||||||
|
|
||||||
|
Utils.FFXIVLoginStringDecodeBinary("C:\\Program Files (x86)\\SquareEnix\\FINAL FANTASY XIV\\ffxivlogin.exe");
|
||||||
|
|
||||||
|
Console.WriteLine(Utils.FFXIVLoginStringDecode(new byte[]{0x6F, 0xD6, 0x3C, 0xD6, 0x20, 0x81, 0x3F, 0x06, 0x36, 0x78, 0xD3, 0xAE, 0xDB, 0x4E, 0x08, 0xF1, 0x7D, 0xAE, 0x90, 0x43, 0x18, 0x70, 0x32, 0x08, 0x6B, 0x75, 0x98, 0xA1, 0x51, 0x15, 0xA9, 0xF7, 0x74, 0xB3, 0x6F, 0x10, 0xEA, 0x76, 0x34, 0x0B, 0x7E, 0x2D, 0xD2, 0xAC, 0xD7, 0xC3, 0xD3, 0xC1, 0x4D, 0x96, 0xED, 0xD4, 0xCC, 0x5E, 0x0D, 0xF5, 0x7E, 0x35, 0x99, 0xB9, 0x57, 0x38, 0x51, 0x79, 0x39, 0x3F, 0x08, 0xFB, 0xE8, 0xEE, 0x25, 0x4F, 0xAE, 0xE2, 0xFC, 0x7E, 0x2A, 0x72, 0x34, 0x57, 0x7E}));
|
||||||
|
|
||||||
|
Console.WriteLine(Utils.ByteArrayToHex(Utils.FFXIVLoginStringEncode(0xd018, "http://141.117.163.26/login/")));
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||||
Console.WriteLine("---------FFXIV 1.0 Map Server---------");
|
Console.WriteLine("---------FFXIV 1.0 Map Server---------");
|
||||||
Console.ForegroundColor = ConsoleColor.Gray;
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
|
|
|
@ -25,6 +25,8 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
public const int FFXIV_MAP_PORT = 54992;
|
public const int FFXIV_MAP_PORT = 54992;
|
||||||
public const int BUFFER_SIZE = 0xFFFF; //Max basepacket size is 0xFFFF
|
public const int BUFFER_SIZE = 0xFFFF; //Max basepacket size is 0xFFFF
|
||||||
public const int BACKLOG = 100;
|
public const int BACKLOG = 100;
|
||||||
|
public const int HEALTH_THREAD_SLEEP_TIME = 5;
|
||||||
|
|
||||||
public const string STATIC_ACTORS_PATH = "./staticactors.bin";
|
public const string STATIC_ACTORS_PATH = "./staticactors.bin";
|
||||||
|
|
||||||
private static Server mSelf;
|
private static Server mSelf;
|
||||||
|
@ -41,6 +43,30 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
|
|
||||||
private PacketProcessor mProcessor;
|
private PacketProcessor mProcessor;
|
||||||
|
|
||||||
|
private Thread mConnectionHealthThread;
|
||||||
|
private bool killHealthThread = false;
|
||||||
|
|
||||||
|
private void connectionHealth()
|
||||||
|
{
|
||||||
|
Log.info(String.Format("Connection Health thread started; it will run every {0} seconds.", HEALTH_THREAD_SLEEP_TIME));
|
||||||
|
while (!killHealthThread)
|
||||||
|
{
|
||||||
|
lock (mConnectedPlayerList)
|
||||||
|
{
|
||||||
|
List<ConnectedPlayer> dcedPlayers = new List<ConnectedPlayer>();
|
||||||
|
foreach (ConnectedPlayer cp in mConnectedPlayerList.Values)
|
||||||
|
{
|
||||||
|
if (cp.checkIfDCing())
|
||||||
|
dcedPlayers.Add(cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ConnectedPlayer cp in dcedPlayers)
|
||||||
|
cp.getActor().cleanupAndSave();
|
||||||
|
}
|
||||||
|
Thread.Sleep(HEALTH_THREAD_SLEEP_TIME * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Server()
|
public Server()
|
||||||
{
|
{
|
||||||
mSelf = this;
|
mSelf = this;
|
||||||
|
@ -53,6 +79,10 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
|
|
||||||
public bool startServer()
|
public bool startServer()
|
||||||
{
|
{
|
||||||
|
mConnectionHealthThread = new Thread(new ThreadStart(connectionHealth));
|
||||||
|
mConnectionHealthThread.Name = "MapThread:Health";
|
||||||
|
//mConnectionHealthThread.Start();
|
||||||
|
|
||||||
mStaticActors = new StaticActors(STATIC_ACTORS_PATH);
|
mStaticActors = new StaticActors(STATIC_ACTORS_PATH);
|
||||||
|
|
||||||
gamedataItems = Database.getItemGamedata();
|
gamedataItems = Database.getItemGamedata();
|
||||||
|
@ -102,6 +132,15 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removePlayer(Player player)
|
||||||
|
{
|
||||||
|
lock (mConnectedPlayerList)
|
||||||
|
{
|
||||||
|
if (mConnectedPlayerList.ContainsKey(player.actorId))
|
||||||
|
mConnectedPlayerList.Remove(player.actorId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region Socket Handling
|
#region Socket Handling
|
||||||
private void acceptCallback(IAsyncResult result)
|
private void acceptCallback(IAsyncResult result)
|
||||||
{
|
{
|
||||||
|
@ -411,17 +450,11 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaEngine GetLuaEngine()
|
|
||||||
{
|
|
||||||
return mLuaEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WorldManager GetWorldManager()
|
public WorldManager GetWorldManager()
|
||||||
{
|
{
|
||||||
return mWorldManager;
|
return mWorldManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void printPos(ConnectedPlayer client)
|
public void printPos(ConnectedPlayer client)
|
||||||
{
|
{
|
||||||
if (client != null)
|
if (client != null)
|
||||||
|
@ -439,19 +472,36 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void giveItem(ConnectedPlayer client, uint itemId, int quantity)
|
private void setGraphic(ConnectedPlayer client, uint slot, uint wId, uint eId, uint vId, uint cId)
|
||||||
{
|
{
|
||||||
if (client != null)
|
if (client != null)
|
||||||
{
|
{
|
||||||
Player p = client.getActor();
|
Player p = client.getActor();
|
||||||
p.getInventory(Inventory.NORMAL).addItem(itemId, quantity, 1);
|
p.graphicChange(slot, wId, eId, vId, cId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
|
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
|
||||||
{
|
{
|
||||||
Player p = entry.Value.getActor();
|
Player p = entry.Value.getActor();
|
||||||
p.getInventory(Inventory.NORMAL).addItem(itemId, quantity, 1);
|
p.graphicChange(slot, wId, eId, vId, cId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void giveItem(ConnectedPlayer client, uint itemId, int quantity)
|
||||||
|
{
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
Player p = client.getActor();
|
||||||
|
p.getInventory(Inventory.NORMAL).addItem(itemId, quantity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
|
||||||
|
{
|
||||||
|
Player p = entry.Value.getActor();
|
||||||
|
p.getInventory(Inventory.NORMAL).addItem(itemId, quantity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +513,7 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
Player p = client.getActor();
|
Player p = client.getActor();
|
||||||
|
|
||||||
if (p.getInventory(type) != null)
|
if (p.getInventory(type) != null)
|
||||||
p.getInventory(type).addItem(itemId, quantity, 1);
|
p.getInventory(type).addItem(itemId, quantity);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -472,7 +522,7 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
Player p = entry.Value.getActor();
|
Player p = entry.Value.getActor();
|
||||||
|
|
||||||
if (p.getInventory(type) != null)
|
if (p.getInventory(type) != null)
|
||||||
p.getInventory(type).addItem(itemId, quantity, 1);
|
p.getInventory(type).addItem(itemId, quantity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -520,14 +570,14 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
if (client != null)
|
if (client != null)
|
||||||
{
|
{
|
||||||
Player p = client.getActor();
|
Player p = client.getActor();
|
||||||
p.getInventory(Inventory.CURRANCY).addItem(itemId, quantity, 1);
|
p.getInventory(Inventory.CURRANCY).addItem(itemId, quantity);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
|
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
|
||||||
{
|
{
|
||||||
Player p = entry.Value.getActor();
|
Player p = entry.Value.getActor();
|
||||||
p.getInventory(Inventory.CURRANCY).addItem(itemId, quantity, 1);
|
p.getInventory(Inventory.CURRANCY).addItem(itemId, quantity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,14 +604,14 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
if (client != null)
|
if (client != null)
|
||||||
{
|
{
|
||||||
Player p = client.getActor();
|
Player p = client.getActor();
|
||||||
p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1, 1);
|
p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
|
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
|
||||||
{
|
{
|
||||||
Player p = entry.Value.getActor();
|
Player p = entry.Value.getActor();
|
||||||
p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1, 1);
|
p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -618,6 +668,18 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
mWorldManager.reloadZone(client.getActor().zoneId);
|
mWorldManager.reloadZone(client.getActor().zoneId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (split[0].Equals("reloaditems"))
|
||||||
|
{
|
||||||
|
Log.info(String.Format("Got request to reload item gamedata"));
|
||||||
|
if (client != null)
|
||||||
|
client.getActor().queuePacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "Reloading Item Gamedata..."));
|
||||||
|
gamedataItems.Clear();
|
||||||
|
gamedataItems = Database.getItemGamedata();
|
||||||
|
Log.info(String.Format("Loaded {0} items.", gamedataItems.Count));
|
||||||
|
if (client != null)
|
||||||
|
client.getActor().queuePacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Loaded {0} items.", gamedataItems.Count)));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (split[0].Equals("sendpacket"))
|
else if (split[0].Equals("sendpacket"))
|
||||||
{
|
{
|
||||||
if (split.Length < 2)
|
if (split.Length < 2)
|
||||||
|
@ -633,6 +695,19 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
Log.error("Could not load packet: " + e);
|
Log.error("Could not load packet: " + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (split[0].Equals("graphic"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (split.Length == 6)
|
||||||
|
setGraphic(client, UInt32.Parse(split[1]), UInt32.Parse(split[2]), UInt32.Parse(split[3]), UInt32.Parse(split[4]), UInt32.Parse(split[5]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.error("Could not give item.");
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (split[0].Equals("giveitem"))
|
else if (split[0].Equals("giveitem"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -755,7 +830,7 @@ namespace FFXIVClassic_Lobby_Server
|
||||||
}
|
}
|
||||||
else if (split[0].Equals("property"))
|
else if (split[0].Equals("property"))
|
||||||
{
|
{
|
||||||
if (split.Length == 5)
|
if (split.Length == 4)
|
||||||
testCodePacket(Utils.MurmurHash2(split[1], 0), Convert.ToUInt32(split[2], 16), split[3]);
|
testCodePacket(Utils.MurmurHash2(split[1], 0), Convert.ToUInt32(split[2], 16), split[3]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.common.EfficientHashTables;
|
using FFXIVClassic_Map_Server.common.EfficientHashTables;
|
||||||
using FFXIVClassic_Map_Server.dataobjects;
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
using FFXIVClassic_Map_Server.dataobjects.chara;
|
using FFXIVClassic_Map_Server.dataobjects.chara;
|
||||||
|
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 FFXIVClassic_Map_Server.packets.send.login;
|
||||||
|
@ -275,7 +276,7 @@ namespace FFXIVClassic_Map_Server
|
||||||
if (player.zone != null)
|
if (player.zone != null)
|
||||||
{
|
{
|
||||||
oldZone = player.zone;
|
oldZone = player.zone;
|
||||||
oldZone.removeActorToZone(player);
|
oldZone.removeActorFromZone(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add player to new zone and update
|
//Add player to new zone and update
|
||||||
|
@ -286,6 +287,8 @@ namespace FFXIVClassic_Map_Server
|
||||||
return;
|
return;
|
||||||
|
|
||||||
newZone.addActorToZone(player);
|
newZone.addActorToZone(player);
|
||||||
|
|
||||||
|
LuaEngine.onZoneIn(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Moves actor to new zone, and sends packets to spawn at the given zone entrance
|
//Moves actor to new zone, and sends packets to spawn at the given zone entrance
|
||||||
|
@ -310,7 +313,7 @@ namespace FFXIVClassic_Map_Server
|
||||||
if (player.zone != null)
|
if (player.zone != null)
|
||||||
{
|
{
|
||||||
oldZone = player.zone;
|
oldZone = player.zone;
|
||||||
oldZone.removeActorToZone(player);
|
oldZone.removeActorFromZone(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add player to new zone and update
|
//Add player to new zone and update
|
||||||
|
@ -336,6 +339,8 @@ namespace FFXIVClassic_Map_Server
|
||||||
player.sendZoneInPackets(this, spawnType);
|
player.sendZoneInPackets(this, spawnType);
|
||||||
player.playerSession.clearInstance();
|
player.playerSession.clearInstance();
|
||||||
player.sendInstanceUpdate();
|
player.sendInstanceUpdate();
|
||||||
|
|
||||||
|
LuaEngine.onZoneIn(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Login Zone In
|
//Login Zone In
|
||||||
|
@ -358,6 +363,9 @@ namespace FFXIVClassic_Map_Server
|
||||||
player.sendZoneInPackets(this, 0x1);
|
player.sendZoneInPackets(this, 0x1);
|
||||||
player.playerSession.clearInstance();
|
player.playerSession.clearInstance();
|
||||||
player.sendInstanceUpdate();
|
player.sendInstanceUpdate();
|
||||||
|
|
||||||
|
LuaEngine.onLogin(player);
|
||||||
|
LuaEngine.onZoneIn(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reloadZone(uint zoneId)
|
public void reloadZone(uint zoneId)
|
||||||
|
|
|
@ -4,6 +4,7 @@ using FFXIVClassic_Map_Server.dataobjects;
|
||||||
using FFXIVClassic_Map_Server.dataobjects.chara;
|
using FFXIVClassic_Map_Server.dataobjects.chara;
|
||||||
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 MoonSharp.Interpreter;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -20,7 +21,6 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
public ushort weatherNormal, weatherCommon, weatherRare;
|
public ushort weatherNormal, weatherCommon, weatherRare;
|
||||||
public ushort bgmDay, bgmNight, bgmBattle;
|
public ushort bgmDay, bgmNight, bgmBattle;
|
||||||
|
|
||||||
|
|
||||||
private string classPath;
|
private string classPath;
|
||||||
|
|
||||||
public int boundingGridSize = 50;
|
public int boundingGridSize = 50;
|
||||||
|
@ -31,6 +31,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
private Dictionary<uint, Actor> mActorList = new Dictionary<uint,Actor>();
|
private Dictionary<uint, Actor> mActorList = new Dictionary<uint,Actor>();
|
||||||
private List<Actor>[,] mActorBlock;
|
private List<Actor>[,] mActorBlock;
|
||||||
|
|
||||||
|
Script areaScript;
|
||||||
|
|
||||||
public Area(uint id, string zoneName, ushort regionId, string className, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool isIsolated, bool isInn, bool canRideChocobo, bool canStealth, bool isInstanceRaid)
|
public Area(uint id, string zoneName, ushort regionId, string className, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool isIsolated, bool isInn, bool canRideChocobo, bool canStealth, bool isInstanceRaid)
|
||||||
: base(id)
|
: base(id)
|
||||||
{
|
{
|
||||||
|
@ -117,7 +119,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
mActorBlock[gridX, gridY].Add(actor);
|
mActorBlock[gridX, gridY].Add(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeActorToZone(Actor actor)
|
public void removeActorFromZone(Actor actor)
|
||||||
{
|
{
|
||||||
mActorList.Remove(actor.actorId);
|
mActorList.Remove(actor.actorId);
|
||||||
|
|
||||||
|
|
|
@ -16,29 +16,32 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
public const int FACEINFO = 2;
|
public const int FACEINFO = 2;
|
||||||
public const int HIGHLIGHT_HAIR = 3;
|
public const int HIGHLIGHT_HAIR = 3;
|
||||||
public const int VOICE = 4;
|
public const int VOICE = 4;
|
||||||
public const int WEAPON1 = 5;
|
public const int MAINHAND = 5;
|
||||||
public const int WEAPON2 = 6;
|
public const int OFFHAND = 6;
|
||||||
public const int WEAPON3 = 7;
|
public const int SPMAINHAND = 7;
|
||||||
public const int UNKNOWN1 = 8;
|
public const int SPOFFHAND = 8;
|
||||||
public const int UNKNOWN2 = 9;
|
public const int THROWING = 9;
|
||||||
public const int UNKNOWN3 = 10;
|
public const int PACK = 10;
|
||||||
public const int UNKNOWN4 = 11;
|
public const int POUCH = 11;
|
||||||
public const int HEADGEAR = 12;
|
public const int HEADGEAR = 12;
|
||||||
public const int BODYGEAR = 13;
|
public const int BODYGEAR = 13;
|
||||||
public const int LEGSGEAR = 14;
|
public const int LEGSGEAR = 14;
|
||||||
public const int HANDSGEAR = 15;
|
public const int HANDSGEAR = 15;
|
||||||
public const int FEETGEAR = 16;
|
public const int FEETGEAR = 16;
|
||||||
public const int WAISTGEAR = 17;
|
public const int WAISTGEAR = 17;
|
||||||
public const int UNKNOWN5 = 18;
|
public const int NECKGEAR = 18;
|
||||||
public const int R_EAR = 19;
|
public const int L_EAR = 19;
|
||||||
public const int L_EAR = 20;
|
public const int R_EAR = 20;
|
||||||
public const int UNKNOWN6 = 21;
|
public const int R_WRIST = 21;
|
||||||
public const int UNKNOWN7 = 22;
|
public const int L_WRIST = 22;
|
||||||
public const int R_FINGER = 23;
|
public const int R_RINGFINGER = 23;
|
||||||
public const int L_FINGER = 24;
|
public const int L_RINGFINGER = 24;
|
||||||
|
public const int R_INDEXFINGER = 25;
|
||||||
|
public const int L_INDEXFINGER = 26;
|
||||||
|
public const int UNKNOWN = 27;
|
||||||
|
|
||||||
public uint modelId;
|
public uint modelId;
|
||||||
public uint[] appearanceIds = new uint[0x1D];
|
public uint[] appearanceIds = new uint[28];
|
||||||
|
|
||||||
public uint animationId = 0;
|
public uint animationId = 0;
|
||||||
|
|
||||||
|
|
|
@ -49,9 +49,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
{
|
{
|
||||||
List<LuaParam> lParams;
|
List<LuaParam> lParams;
|
||||||
|
|
||||||
LuaEngine lua = Server.getServer().GetLuaEngine();
|
|
||||||
Player player = Server.getServer().GetWorldManager().GetPCInWorld(playerActorId);
|
Player player = Server.getServer().GetWorldManager().GetPCInWorld(playerActorId);
|
||||||
lParams = lua.doActorOnInstantiate(player, this);
|
lParams = LuaEngine.doActorOnInstantiate(player, this);
|
||||||
|
|
||||||
if (lParams == null)
|
if (lParams == null)
|
||||||
{
|
{
|
||||||
|
@ -154,7 +153,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
appearanceIds[Character.FACEINFO] = PrimitiveConversion.ToUInt32(CharacterUtils.getFaceInfo(reader.GetByte(6), reader.GetByte(7), reader.GetByte(5), reader.GetByte(14), reader.GetByte(13), reader.GetByte(12), reader.GetByte(11), reader.GetByte(10), reader.GetByte(9), reader.GetByte(8)));
|
appearanceIds[Character.FACEINFO] = PrimitiveConversion.ToUInt32(CharacterUtils.getFaceInfo(reader.GetByte(6), reader.GetByte(7), reader.GetByte(5), reader.GetByte(14), reader.GetByte(13), reader.GetByte(12), reader.GetByte(11), reader.GetByte(10), reader.GetByte(9), reader.GetByte(8)));
|
||||||
appearanceIds[Character.HIGHLIGHT_HAIR] = (uint)(reader.GetUInt32(3) | reader.GetUInt32(2) << 10); //5- Hair Highlight, 4 - Hair Style
|
appearanceIds[Character.HIGHLIGHT_HAIR] = (uint)(reader.GetUInt32(3) | reader.GetUInt32(2) << 10); //5- Hair Highlight, 4 - Hair Style
|
||||||
appearanceIds[Character.VOICE] = reader.GetUInt32(17);
|
appearanceIds[Character.VOICE] = reader.GetUInt32(17);
|
||||||
appearanceIds[Character.WEAPON1] = reader.GetUInt32(19);
|
appearanceIds[Character.MAINHAND] = reader.GetUInt32(19);
|
||||||
//appearanceIds[Character.WEAPON2] = reader.GetUInt32(22);
|
//appearanceIds[Character.WEAPON2] = reader.GetUInt32(22);
|
||||||
appearanceIds[Character.HEADGEAR] = reader.GetUInt32(26);
|
appearanceIds[Character.HEADGEAR] = reader.GetUInt32(26);
|
||||||
appearanceIds[Character.BODYGEAR] = reader.GetUInt32(27);
|
appearanceIds[Character.BODYGEAR] = reader.GetUInt32(27);
|
||||||
|
@ -164,8 +163,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
appearanceIds[Character.WAISTGEAR] = reader.GetUInt32(31);
|
appearanceIds[Character.WAISTGEAR] = reader.GetUInt32(31);
|
||||||
appearanceIds[Character.R_EAR] = reader.GetUInt32(32);
|
appearanceIds[Character.R_EAR] = reader.GetUInt32(32);
|
||||||
appearanceIds[Character.L_EAR] = reader.GetUInt32(33);
|
appearanceIds[Character.L_EAR] = reader.GetUInt32(33);
|
||||||
appearanceIds[Character.R_FINGER] = reader.GetUInt32(36);
|
appearanceIds[Character.R_RINGFINGER] = reader.GetUInt32(36);
|
||||||
appearanceIds[Character.L_FINGER] = reader.GetUInt32(37);
|
appearanceIds[Character.L_RINGFINGER] = reader.GetUInt32(37);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,24 +13,24 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
||||||
{
|
{
|
||||||
class Equipment
|
class Equipment
|
||||||
{
|
{
|
||||||
public const int SLOT_MAINHAND = 0x00;
|
public const int SLOT_MAINHAND = 0;
|
||||||
public const int SLOT_OFFHAND = 0x01;
|
public const int SLOT_OFFHAND = 1;
|
||||||
public const int SLOT_THROWINGWEAPON = 0x04;
|
public const int SLOT_THROWINGWEAPON = 4;
|
||||||
public const int SLOT_PACK = 0x05;
|
public const int SLOT_PACK = 5;
|
||||||
public const int SLOT_POUCH = 0x06;
|
public const int SLOT_POUCH = 6;
|
||||||
public const int SLOT_HEAD = 0x08;
|
public const int SLOT_HEAD = 8;
|
||||||
public const int SLOT_UNDERSHIRT = 0x09;
|
public const int SLOT_UNDERSHIRT = 9;
|
||||||
public const int SLOT_BODY = 0x0A;
|
public const int SLOT_BODY = 10;
|
||||||
public const int SLOT_UNDERGARMENT = 0x0B;
|
public const int SLOT_UNDERGARMENT = 11;
|
||||||
public const int SLOT_LEGS = 0x0C;
|
public const int SLOT_LEGS = 12;
|
||||||
public const int SLOT_HANDS = 0x0D;
|
public const int SLOT_HANDS = 13;
|
||||||
public const int SLOT_BOOTS = 0x0E;
|
public const int SLOT_BOOTS = 14;
|
||||||
public const int SLOT_WAIST = 0x0F;
|
public const int SLOT_WAIST = 15;
|
||||||
public const int SLOT_NECK = 0x10;
|
public const int SLOT_NECK = 16;
|
||||||
public const int SLOT_EARS = 0x11;
|
public const int SLOT_EARS = 17;
|
||||||
public const int SLOT_WRISTS = 0x13;
|
public const int SLOT_WRISTS = 19;
|
||||||
public const int SLOT_RIGHTFINGER = 0x15;
|
public const int SLOT_RIGHTFINGER = 21;
|
||||||
public const int SLOT_LEFTFINGER = 0x16;
|
public const int SLOT_LEFTFINGER = 22;
|
||||||
|
|
||||||
private Player owner;
|
private Player owner;
|
||||||
private ushort inventoryCapacity;
|
private ushort inventoryCapacity;
|
||||||
|
@ -71,6 +71,27 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
||||||
owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId));
|
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.getItem(itemSlots[i]);
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Database.equipItem(owner, slots[i], itemSlots[i]);
|
||||||
|
list[slots[i]] = normalInventory.getItem(itemSlots[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
owner.queuePacket(InventoryBeginChangePacket.buildPacket(owner.actorId));
|
||||||
|
SendFullEquipment(false);
|
||||||
|
owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId));
|
||||||
|
}
|
||||||
|
|
||||||
public void SetEquipment(List<Tuple<ushort, InventoryItem>> toEquip)
|
public void SetEquipment(List<Tuple<ushort, InventoryItem>> toEquip)
|
||||||
{
|
{
|
||||||
List<ushort> slotsToUpdate = new List<ushort>();
|
List<ushort> slotsToUpdate = new List<ushort>();
|
||||||
|
@ -81,6 +102,16 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Equip(ushort slot, ushort invSlot)
|
||||||
|
{
|
||||||
|
InventoryItem item = normalInventory.getItem(invSlot);
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Equip(slot, item);
|
||||||
|
}
|
||||||
|
|
||||||
public void Equip(ushort slot, InventoryItem item)
|
public void Equip(ushort slot, InventoryItem item)
|
||||||
{
|
{
|
||||||
if (slot >= list.Length)
|
if (slot >= list.Length)
|
||||||
|
|
|
@ -70,6 +70,16 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
||||||
owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId));
|
owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addItem(uint itemId)
|
||||||
|
{
|
||||||
|
addItem(itemId, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItem(uint itemId, int quantity)
|
||||||
|
{
|
||||||
|
addItem(itemId, quantity, 1);
|
||||||
|
}
|
||||||
|
|
||||||
public void addItem(uint itemId, int quantity, byte quality)
|
public void addItem(uint itemId, int quantity, byte quality)
|
||||||
{
|
{
|
||||||
if (!isSpaceForAdd(itemId, quantity))
|
if (!isSpaceForAdd(itemId, quantity))
|
||||||
|
@ -119,7 +129,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
||||||
//New item that spilled over
|
//New item that spilled over
|
||||||
while (quantityCount > 0)
|
while (quantityCount > 0)
|
||||||
{
|
{
|
||||||
InventoryItem addedItem = Database.addItem(owner, itemId, Math.Min(quantityCount, 5), quality, gItem.isExclusive ? (byte)0x3 : (byte)0x0, gItem.durability, inventoryCode);
|
InventoryItem addedItem = Database.addItem(owner, itemId, Math.Min(quantityCount, gItem.maxStack), quality, gItem.isExclusive ? (byte)0x3 : (byte)0x0, gItem.durability, inventoryCode);
|
||||||
|
|
||||||
|
|
||||||
list.Add(addedItem);
|
list.Add(addedItem);
|
||||||
|
@ -137,6 +147,31 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
|
||||||
owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId));
|
owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addItem(uint[] itemId)
|
||||||
|
{
|
||||||
|
if (!isSpaceForAdd(itemId[0], itemId.Length))
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Update lists and db
|
||||||
|
owner.queuePacket(InventoryBeginChangePacket.buildPacket(owner.actorId));
|
||||||
|
owner.queuePacket(InventorySetBeginPacket.buildPacket(owner.actorId, inventoryCapacity, inventoryCode));
|
||||||
|
|
||||||
|
int startPos = list.Count;
|
||||||
|
|
||||||
|
//New item that spilled over
|
||||||
|
for (int i = 0; i < itemId.Length; i++)
|
||||||
|
{
|
||||||
|
Item gItem = Server.getItemGamedata(itemId[i]);
|
||||||
|
InventoryItem addedItem = Database.addItem(owner, itemId[i], 1, (byte)1, gItem.isExclusive ? (byte)0x3 : (byte)0x0, gItem.durability, inventoryCode);
|
||||||
|
list.Add(addedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendInventoryPackets(startPos);
|
||||||
|
|
||||||
|
owner.queuePacket(InventorySetEndPacket.buildPacket(owner.actorId));
|
||||||
|
owner.queuePacket(InventoryEndChangePacket.buildPacket(owner.actorId));
|
||||||
|
}
|
||||||
|
|
||||||
public void removeItem(uint itemId, int quantity)
|
public void removeItem(uint itemId, int quantity)
|
||||||
{
|
{
|
||||||
if (!hasItem(itemId, quantity))
|
if (!hasItem(itemId, quantity))
|
||||||
|
|
|
@ -59,6 +59,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
public uint[] timers = new uint[20];
|
public uint[] timers = new uint[20];
|
||||||
public ushort currentJob;
|
public ushort currentJob;
|
||||||
public uint currentTitle;
|
public uint currentTitle;
|
||||||
|
public uint playTime;
|
||||||
|
public uint lastPlayTimeUpdate;
|
||||||
|
public bool isGM = false;
|
||||||
|
|
||||||
//Inventory
|
//Inventory
|
||||||
private Dictionary<ushort, Inventory> inventories = new Dictionary<ushort, Inventory>();
|
private Dictionary<ushort, Inventory> inventories = new Dictionary<ushort, Inventory>();
|
||||||
|
@ -162,6 +165,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
charaWork.parameterTemp.tp = 3000;
|
charaWork.parameterTemp.tp = 3000;
|
||||||
|
|
||||||
Database.loadPlayerCharacter(this);
|
Database.loadPlayerCharacter(this);
|
||||||
|
lastPlayTimeUpdate = Utils.UnixTimeStampUTC();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SubPacket> create0x132Packets(uint playerActorId)
|
public List<SubPacket> create0x132Packets(uint playerActorId)
|
||||||
|
@ -545,6 +549,34 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDCFlag(bool flag)
|
||||||
|
{
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
broadcastPacket(SetActorIconPacket.buildPacket(actorId, actorId, SetActorIconPacket.DISCONNECTING), true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isGM)
|
||||||
|
broadcastPacket(SetActorIconPacket.buildPacket(actorId, actorId, SetActorIconPacket.ISGM), true);
|
||||||
|
else
|
||||||
|
broadcastPacket(SetActorIconPacket.buildPacket(actorId, actorId, 0), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanupAndSave()
|
||||||
|
{
|
||||||
|
//Remove actor from zone and main server list
|
||||||
|
zone.removeActorFromZone(this);
|
||||||
|
Server.getServer().removePlayer(this);
|
||||||
|
|
||||||
|
//Save Player
|
||||||
|
Database.savePlayerPlayTime(this);
|
||||||
|
Database.savePlayerPosition(this);
|
||||||
|
|
||||||
|
Log.info(String.Format("{0} has been logged out and saved.", this.customDisplayName));
|
||||||
|
}
|
||||||
|
|
||||||
public Zone getZone()
|
public Zone getZone()
|
||||||
{
|
{
|
||||||
return zone;
|
return zone;
|
||||||
|
@ -558,11 +590,25 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
public void logout()
|
public void logout()
|
||||||
{
|
{
|
||||||
queuePacket(LogoutPacket.buildPacket(actorId));
|
queuePacket(LogoutPacket.buildPacket(actorId));
|
||||||
|
cleanupAndSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void quitGame()
|
public void quitGame()
|
||||||
{
|
{
|
||||||
queuePacket(QuitPacket.buildPacket(actorId));
|
queuePacket(QuitPacket.buildPacket(actorId));
|
||||||
|
cleanupAndSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint getPlayTime(bool doUpdate)
|
||||||
|
{
|
||||||
|
if (doUpdate)
|
||||||
|
{
|
||||||
|
uint curTime = Utils.UnixTimeStampUTC();
|
||||||
|
playTime += curTime - lastPlayTimeUpdate;
|
||||||
|
lastPlayTimeUpdate = curTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return playTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeMusic(ushort musicId)
|
public void changeMusic(ushort musicId)
|
||||||
|
@ -635,34 +681,63 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
//zone.broadcastPacketAroundActor(this, worldMasterMessage);
|
//zone.broadcastPacketAroundActor(this, worldMasterMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void graphicChange(int slot, InventoryItem invItem)
|
public void graphicChange(uint slot, uint graphicId)
|
||||||
{
|
{
|
||||||
Item item = Server.getItemGamedata(invItem.itemId);
|
appearanceIds[slot] = graphicId;
|
||||||
|
broadcastPacket(createAppearancePacket(actorId), true);
|
||||||
|
}
|
||||||
|
|
||||||
if (item == null)
|
public void graphicChange(uint slot, uint weapId, uint equipId, uint variantId, uint colorId)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
uint mixedVariantId;
|
||||||
|
|
||||||
|
if (weapId == 0)
|
||||||
|
mixedVariantId = ((variantId & 0x1F) << 5) | colorId;
|
||||||
|
else
|
||||||
|
mixedVariantId = variantId;
|
||||||
|
|
||||||
|
uint graphicId =
|
||||||
|
(weapId & 0x3FF) << 20 |
|
||||||
|
(equipId & 0x3FF) << 10 |
|
||||||
|
(mixedVariantId & 0x3FF);
|
||||||
|
|
||||||
|
appearanceIds[slot] = graphicId;
|
||||||
|
broadcastPacket(createAppearancePacket(actorId), true);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (item is EquipmentItem)
|
|
||||||
|
public void graphicChange(int slot, InventoryItem invItem)
|
||||||
|
{
|
||||||
|
if (invItem == null)
|
||||||
|
appearanceIds[slot] = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Item item = Server.getItemGamedata(invItem.itemId);
|
||||||
|
if (item is EquipmentItem)
|
||||||
{
|
{
|
||||||
EquipmentItem eqItem = (EquipmentItem)item;
|
EquipmentItem eqItem = (EquipmentItem)item;
|
||||||
|
|
||||||
uint graphicId;
|
uint mixedVariantId;
|
||||||
|
|
||||||
if (eqItem.graphicsWeaponId == null || eqItem.graphicsEquipmentId == null || eqItem.graphicsVariantId == null)
|
if (eqItem.graphicsWeaponId == 0)
|
||||||
graphicId = 1025;
|
mixedVariantId = ((eqItem.graphicsVariantId & 0x1F) << 5) | eqItem.graphicsColorId;
|
||||||
else
|
else
|
||||||
{
|
mixedVariantId = eqItem.graphicsVariantId;
|
||||||
graphicId =
|
|
||||||
eqItem.graphicsWeaponId << 20 |
|
uint graphicId =
|
||||||
eqItem.graphicsEquipmentId << 10 |
|
(eqItem.graphicsWeaponId & 0x3FF) << 20 |
|
||||||
eqItem.graphicsVariantId << 5 |
|
(eqItem.graphicsEquipmentId & 0x3FF) << 10 |
|
||||||
eqItem.graphicsColorId << 5;
|
(mixedVariantId & 0x3FF);
|
||||||
|
|
||||||
|
appearanceIds[slot] = graphicId;
|
||||||
}
|
}
|
||||||
appearanceIds[BODYGEAR] = graphicId;
|
}
|
||||||
|
|
||||||
|
Database.savePlayerAppearance(this);
|
||||||
|
|
||||||
broadcastPacket(createAppearancePacket(actorId), true);
|
broadcastPacket(createAppearancePacket(actorId), true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public Inventory getInventory(ushort type)
|
public Inventory getInventory(ushort type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,11 +19,13 @@ namespace FFXIVClassic_Lobby_Server.common
|
||||||
|
|
||||||
public static void debug(String message)
|
public static void debug(String message)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
Console.Write("[{0}]", DateTime.Now.ToString("dd/MMM HH:mm"));
|
Console.Write("[{0}]", DateTime.Now.ToString("dd/MMM HH:mm"));
|
||||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
Console.Write("[DEBUG] ");
|
Console.Write("[DEBUG] ");
|
||||||
Console.ForegroundColor = ConsoleColor.Gray;
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
Console.WriteLine(message);
|
Console.WriteLine(message);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void info(String message)
|
public static void info(String message)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -179,5 +180,127 @@ namespace FFXIVClassic_Lobby_Server.common
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string FFXIVLoginStringDecodeBinary(string path)
|
||||||
|
{
|
||||||
|
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
||||||
|
byte[] data = File.ReadAllBytes(path);
|
||||||
|
int offset = 0x5405a;
|
||||||
|
//int offset = 0x5425d;
|
||||||
|
//int offset = 0x53ea0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
uint key = (uint)data[offset + 0] << 8 | data[offset+1];
|
||||||
|
uint key2 = data[offset + 2];
|
||||||
|
key = RotateRight(key, 1) & 0xFFFF;
|
||||||
|
key -= 0x22AF;
|
||||||
|
key &= 0xFFFF;
|
||||||
|
key2 = key2 ^ key;
|
||||||
|
key = RotateRight(key, 1) & 0xFFFF;
|
||||||
|
key -= 0x22AF;
|
||||||
|
key &= 0xFFFF;
|
||||||
|
uint finalKey = key;
|
||||||
|
key = data[offset + 3];
|
||||||
|
uint count = (key2 & 0xFF) << 8;
|
||||||
|
key = key ^ finalKey;
|
||||||
|
key &= 0xFF;
|
||||||
|
count |= key;
|
||||||
|
|
||||||
|
int count2 = 0;
|
||||||
|
while (count != 0)
|
||||||
|
{
|
||||||
|
uint encrypted = data[offset + 4 + count2];
|
||||||
|
finalKey = RotateRight(finalKey, 1) & 0xFFFF;
|
||||||
|
finalKey -= 0x22AF;
|
||||||
|
finalKey &= 0xFFFF;
|
||||||
|
encrypted = encrypted ^ (finalKey & 0xFF);
|
||||||
|
|
||||||
|
result += (char)encrypted;
|
||||||
|
count--;
|
||||||
|
count2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += 4 + count2;
|
||||||
|
|
||||||
|
Console.WriteLine(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string FFXIVLoginStringDecode(byte[] data)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
uint key = (uint)data[0] << 8 | data[1];
|
||||||
|
uint key2 = data[2];
|
||||||
|
key = RotateRight(key, 1) & 0xFFFF;
|
||||||
|
key -= 0x22AF;
|
||||||
|
key2 = key2 ^ key;
|
||||||
|
key = RotateRight(key, 1) & 0xFFFF;
|
||||||
|
key -= 0x22AF;
|
||||||
|
uint finalKey = key;
|
||||||
|
key = data[3];
|
||||||
|
uint count = (key2 & 0xFF) << 8;
|
||||||
|
key = key ^ finalKey;
|
||||||
|
key &= 0xFF;
|
||||||
|
count |= key;
|
||||||
|
|
||||||
|
int count2 = 0;
|
||||||
|
while (count != 0)
|
||||||
|
{
|
||||||
|
uint encrypted = data[4 + count2];
|
||||||
|
finalKey = RotateRight(finalKey, 1) & 0xFFFF;
|
||||||
|
finalKey -= 0x22AF;
|
||||||
|
encrypted = encrypted ^ (finalKey & 0xFF);
|
||||||
|
result += (char)encrypted;
|
||||||
|
count--;
|
||||||
|
count2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] FFXIVLoginStringEncode(uint key, string text)
|
||||||
|
{
|
||||||
|
key = key & 0xFFFF;
|
||||||
|
|
||||||
|
uint count = 0;
|
||||||
|
byte[] asciiBytes = Encoding.ASCII.GetBytes(text);
|
||||||
|
byte[] result = new byte[4 + text.Length];
|
||||||
|
for (count = 0; count < text.Length; count++)
|
||||||
|
{
|
||||||
|
result[result.Length - count - 1] = (byte)(asciiBytes[asciiBytes.Length - count - 1] ^ (key & 0xFF));
|
||||||
|
key += 0x22AF;
|
||||||
|
key &= 0xFFFF;
|
||||||
|
key = RotateLeft(key, 1) & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = count ^ key;
|
||||||
|
result[3] = (byte) (count & 0xFF);
|
||||||
|
|
||||||
|
key += 0x22AF & 0xFFFF;
|
||||||
|
key = RotateLeft(key, 1) & 0xFFFF;
|
||||||
|
|
||||||
|
result[2] = (byte)(key & 0xFF);
|
||||||
|
|
||||||
|
key += 0x22AF & 0xFFFF;
|
||||||
|
key = RotateLeft(key, 1) & 0xFFFF;
|
||||||
|
|
||||||
|
|
||||||
|
result[1] = (byte)(key & 0xFF);
|
||||||
|
result[0] = (byte)((key >> 8) & 0xFF);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint RotateLeft(uint value, int bits)
|
||||||
|
{
|
||||||
|
return (value << bits) | (value >> (16 - bits));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint RotateRight(uint value, int bits)
|
||||||
|
{
|
||||||
|
return (value >> bits) | (value << (16 - bits));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Lobby_Server;
|
using FFXIVClassic_Lobby_Server;
|
||||||
|
using FFXIVClassic_Lobby_Server.common;
|
||||||
using FFXIVClassic_Lobby_Server.packets;
|
using FFXIVClassic_Lobby_Server.packets;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
@ -19,9 +20,9 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
private ClientConnection zoneConnection;
|
private ClientConnection zoneConnection;
|
||||||
private ClientConnection chatConnection;
|
private ClientConnection chatConnection;
|
||||||
|
|
||||||
public string errorMessage = "";
|
private uint lastPingPacket = Utils.UnixTimeStampUTC();
|
||||||
|
|
||||||
bool isDisconnected;
|
public string errorMessage = "";
|
||||||
|
|
||||||
public ConnectedPlayer(uint actorId)
|
public ConnectedPlayer(uint actorId)
|
||||||
{
|
{
|
||||||
|
@ -51,11 +52,15 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
|
|
||||||
public void disconnect()
|
public void disconnect()
|
||||||
{
|
{
|
||||||
isDisconnected = true;
|
|
||||||
zoneConnection.disconnect();
|
zoneConnection.disconnect();
|
||||||
chatConnection.disconnect();
|
chatConnection.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool isDisconnected()
|
||||||
|
{
|
||||||
|
return (!zoneConnection.isConnected() && !chatConnection.isConnected());
|
||||||
|
}
|
||||||
|
|
||||||
public void queuePacket(BasePacket basePacket)
|
public void queuePacket(BasePacket basePacket)
|
||||||
{
|
{
|
||||||
zoneConnection.queuePacket(basePacket);
|
zoneConnection.queuePacket(basePacket);
|
||||||
|
@ -71,6 +76,23 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
return playerActor;
|
return playerActor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ping()
|
||||||
|
{
|
||||||
|
lastPingPacket = Utils.UnixTimeStampUTC();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool checkIfDCing()
|
||||||
|
{
|
||||||
|
uint currentTime = Utils.UnixTimeStampUTC();
|
||||||
|
if (currentTime - lastPingPacket >= 5000) //Show D/C flag
|
||||||
|
playerActor.setDCFlag(true);
|
||||||
|
else if (currentTime - lastPingPacket >= 30000) //DCed
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
playerActor.setDCFlag(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void updatePlayerActorPosition(float x, float y, float z, float rot, ushort moveState)
|
public void updatePlayerActorPosition(float x, float y, float z, float rot, ushort moveState)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -89,16 +111,6 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMotd()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendChat(ConnectedPlayer sender, string message, int mode)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BasePacket> updateInstance(List<Actor> list)
|
public List<BasePacket> updateInstance(List<Actor> list)
|
||||||
{
|
{
|
||||||
List<BasePacket> basePackets = new List<BasePacket>();
|
List<BasePacket> basePackets = new List<BasePacket>();
|
||||||
|
|
|
@ -19,6 +19,8 @@ namespace FFXIVClassic_Map_Server.lua
|
||||||
{
|
{
|
||||||
class LuaEngine
|
class LuaEngine
|
||||||
{
|
{
|
||||||
|
const string FILEPATH_PLAYER = "./scripts/player.lua";
|
||||||
|
const string FILEPATH_ZONE = "./scripts/zones/{0}/zone.lua";
|
||||||
const string FILEPATH_COMMANDS = "./scripts/commands/{0}.lua";
|
const string FILEPATH_COMMANDS = "./scripts/commands/{0}.lua";
|
||||||
const string FILEPATH_NPCS = "./scripts/zones/{0}/npcs/{1}.lua";
|
const string FILEPATH_NPCS = "./scripts/zones/{0}/npcs/{1}.lua";
|
||||||
|
|
||||||
|
@ -27,7 +29,7 @@ namespace FFXIVClassic_Map_Server.lua
|
||||||
UserData.RegistrationPolicy = InteropRegistrationPolicy.Automatic;
|
UserData.RegistrationPolicy = InteropRegistrationPolicy.Automatic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LuaParam> doActorOnInstantiate(Player player, Actor target)
|
public static List<LuaParam> doActorOnInstantiate(Player player, Actor target)
|
||||||
{
|
{
|
||||||
string luaPath;
|
string luaPath;
|
||||||
|
|
||||||
|
@ -58,7 +60,7 @@ namespace FFXIVClassic_Map_Server.lua
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doActorOnEventStarted(Player player, Actor target, EventStartPacket eventStart)
|
public static void doActorOnEventStarted(Player player, Actor target, EventStartPacket eventStart)
|
||||||
{
|
{
|
||||||
string luaPath;
|
string luaPath;
|
||||||
|
|
||||||
|
@ -96,7 +98,7 @@ namespace FFXIVClassic_Map_Server.lua
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doActorOnEventUpdated(Player player, Actor target, EventUpdatePacket eventUpdate)
|
public static void doActorOnEventUpdated(Player player, Actor target, EventUpdatePacket eventUpdate)
|
||||||
{
|
{
|
||||||
string luaPath;
|
string luaPath;
|
||||||
|
|
||||||
|
@ -131,5 +133,38 @@ namespace FFXIVClassic_Map_Server.lua
|
||||||
player.playerSession.queuePacket(BasePacket.createPacket(sendError, true, false));
|
player.playerSession.queuePacket(BasePacket.createPacket(sendError, true, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void onZoneIn(Player player)
|
||||||
|
{
|
||||||
|
string luaPath = String.Format(FILEPATH_ZONE, player.getZone().actorId);
|
||||||
|
|
||||||
|
if (File.Exists(luaPath))
|
||||||
|
{
|
||||||
|
Script script = new Script();
|
||||||
|
((ScriptLoaderBase)script.Options.ScriptLoader).ModulePaths = new string[] { "./scripts/?", "./scripts/?.lua" };
|
||||||
|
script.Globals["getStaticActor"] = (Func<string, Actor>)Server.getStaticActors;
|
||||||
|
script.Globals["getWorldMaster"] = (Func<Actor>)Server.getServer().GetWorldManager().GetActor;
|
||||||
|
script.DoFile(luaPath);
|
||||||
|
|
||||||
|
//Run Script
|
||||||
|
DynValue result = script.Call(script.Globals["onZoneIn"], player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onLogin(Player player)
|
||||||
|
{
|
||||||
|
if (File.Exists(FILEPATH_PLAYER))
|
||||||
|
{
|
||||||
|
Script script = new Script();
|
||||||
|
((ScriptLoaderBase)script.Options.ScriptLoader).ModulePaths = new string[] { "./scripts/?", "./scripts/?.lua" };
|
||||||
|
script.Globals["getStaticActor"] = (Func<string, Actor>)Server.getStaticActors;
|
||||||
|
script.Globals["getWorldMaster"] = (Func<Actor>)Server.getServer().GetWorldManager().GetActor;
|
||||||
|
script.DoFile(FILEPATH_PLAYER);
|
||||||
|
|
||||||
|
//Run Script
|
||||||
|
DynValue result = script.Call(script.Globals["onLogin"], player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,22 +18,29 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
public const int FACEINFO = 2;
|
public const int FACEINFO = 2;
|
||||||
public const int HIGHLIGHT_HAIR = 3;
|
public const int HIGHLIGHT_HAIR = 3;
|
||||||
public const int VOICE = 4;
|
public const int VOICE = 4;
|
||||||
public const int WEAPON1 = 5;
|
public const int MAINHAND = 5;
|
||||||
public const int WEAPON2 = 6;
|
public const int OFFHAND = 6;
|
||||||
public const int WEAPON3 = 7;
|
public const int SPMAINHAND = 7;
|
||||||
|
public const int SPOFFHAND = 8;
|
||||||
|
public const int THROWING = 9;
|
||||||
|
public const int PACK = 10;
|
||||||
|
public const int POUCH = 11;
|
||||||
public const int HEADGEAR = 12;
|
public const int HEADGEAR = 12;
|
||||||
public const int BODYGEAR = 13;
|
public const int BODYGEAR = 13;
|
||||||
public const int LEGSGEAR = 14;
|
public const int LEGSGEAR = 14;
|
||||||
public const int HANDSGEAR = 15;
|
public const int HANDSGEAR = 15;
|
||||||
public const int FEETGEAR = 16;
|
public const int FEETGEAR = 16;
|
||||||
public const int WAISTGEAR = 17;
|
public const int WAISTGEAR = 17;
|
||||||
public const int UNKNOWN1 = 18;
|
public const int NECKGEAR = 18;
|
||||||
public const int R_EAR = 19;
|
public const int L_EAR = 19;
|
||||||
public const int L_EAR = 20;
|
public const int R_EAR = 20;
|
||||||
public const int UNKNOWN2 = 21;
|
public const int R_WRIST = 21;
|
||||||
public const int UNKNOWN3 = 22;
|
public const int L_WRIST = 22;
|
||||||
public const int R_FINGER = 23;
|
public const int R_RINGFINGER = 23;
|
||||||
public const int L_FINGER = 24;
|
public const int L_RINGFINGER = 24;
|
||||||
|
public const int R_INDEXFINGER = 25;
|
||||||
|
public const int L_INDEXFINGER = 26;
|
||||||
|
public const int UNKNOWN = 27;
|
||||||
|
|
||||||
public uint modelID;
|
public uint modelID;
|
||||||
public uint[] appearanceIDs;
|
public uint[] appearanceIDs;
|
||||||
|
@ -41,7 +48,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
public SetActorAppearancePacket(uint modelID)
|
public SetActorAppearancePacket(uint modelID)
|
||||||
{
|
{
|
||||||
this.modelID = modelID;
|
this.modelID = modelID;
|
||||||
appearanceIDs = new uint[0x1D];
|
appearanceIDs = new uint[28];
|
||||||
}
|
}
|
||||||
|
|
||||||
public SetActorAppearancePacket(uint modelID, uint[] appearanceTable)
|
public SetActorAppearancePacket(uint modelID, uint[] appearanceTable)
|
||||||
|
@ -59,15 +66,14 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||||
{
|
{
|
||||||
binWriter.Write((uint)modelID);
|
binWriter.Write((uint)modelID);
|
||||||
for (int i = 0; i <= 0x1A; i++)
|
for (int i = 0; i < appearanceIDs.Length; i++)
|
||||||
{
|
{
|
||||||
binWriter.Write((uint)i);
|
binWriter.Write((uint)i);
|
||||||
binWriter.Write((uint)appearanceIDs[i]);
|
binWriter.Write((uint)appearanceIDs[i]);
|
||||||
}
|
}
|
||||||
binWriter.Write((uint) 0x1B);
|
|
||||||
binWriter.Seek(0x20, SeekOrigin.Current);
|
binWriter.Seek(0x100, SeekOrigin.Begin);
|
||||||
binWriter.Write((uint) 0x1C);
|
binWriter.Write(appearanceIDs.Length);
|
||||||
binWriter.Write((uint) 0x00);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue