diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs index ccb966bf..8b2600ce 100644 --- a/FFXIVClassic Map Server/Database.cs +++ b/FFXIVClassic Map Server/Database.cs @@ -64,7 +64,7 @@ namespace FFXIVClassic_Lobby_Server } } - public static Character getCharacter(uint userId, uint charId) + public static Character getCharacter(uint charId) { using (var 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))) { @@ -72,7 +72,7 @@ namespace FFXIVClassic_Lobby_Server try { conn.Open(); - chara = conn.Query("SELECT * FROM characters WHERE id=@CharaId and userId=@UserId", new { UserId = userId, CharaId = charId }).SingleOrDefault(); + chara = conn.Query("SELECT * FROM characters WHERE id=@CharaId", new { CharaId = charId }).SingleOrDefault(); } catch (MySqlException e) { @@ -86,5 +86,27 @@ namespace FFXIVClassic_Lobby_Server } } + public static Appearance getAppearance(uint charaId) + { + using (var 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))) + { + Appearance appearance = null; + try + { + conn.Open(); + appearance = conn.Query("SELECT * FROM characters_appearance WHERE characterId=@CharaId", new { CharaId = charaId }).SingleOrDefault(); + } + catch (MySqlException e) + { + } + finally + { + conn.Dispose(); + } + + return appearance; + } + } + } } diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index 9598507e..70a5ce68 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -67,6 +67,7 @@ + @@ -75,10 +76,14 @@ + + + + diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/FFXIVClassic Map Server/PacketProcessor.cs index 6d40e112..7d0381f8 100644 --- a/FFXIVClassic Map Server/PacketProcessor.cs +++ b/FFXIVClassic Map Server/PacketProcessor.cs @@ -15,6 +15,7 @@ using FFXIVClassic_Map_Server.packets.receive; using FFXIVClassic_Map_Server.packets.send; using FFXIVClassic_Map_Server.packets.send.login; using FFXIVClassic_Map_Server.packets.send.Actor.inventory; +using FFXIVClassic_Map_Server.packets.send.Actor; namespace FFXIVClassic_Lobby_Server { @@ -165,8 +166,8 @@ namespace FFXIVClassic_Lobby_Server //Get Character info //Create player actor - client.sendPacketQueue.Add(init); - client.sendPacketQueue.Add(reply2); + client.queuePacket(init); + client.queuePacket(reply2); break; //Ping case 0x0001: @@ -177,9 +178,6 @@ namespace FFXIVClassic_Lobby_Server //Unknown case 0x0002: subpacket.debugPrintSubPacket(); - - BasePacket setMapPacket = BasePacket.createPacket(SetMapPacket.buildPacket(player.actorID, 0xD1), true, false); - BasePacket setPlayerActorPacket = BasePacket.createPacket(_0x2Packet.buildPacket(player.actorID), true, false); BasePacket reply5 = new BasePacket("./packets/login/login5.bin"); BasePacket reply6 = new BasePacket("./packets/login/login6_data.bin"); @@ -192,6 +190,7 @@ namespace FFXIVClassic_Lobby_Server BasePacket keyitems = new BasePacket("./packets/login/keyitems.bin"); BasePacket currancy = new BasePacket("./packets/login/currancy.bin"); +#region replaceid setinv.replaceActorID(player.actorID); currancy.replaceActorID(player.actorID); keyitems.replaceActorID(player.actorID); @@ -201,20 +200,31 @@ namespace FFXIVClassic_Lobby_Server reply7.replaceActorID(player.actorID); reply8.replaceActorID(player.actorID); reply9.replaceActorID(player.actorID); +#endregion - client.sendPacketQueue.Add(setMapPacket); - client.sendPacketQueue.Add(setPlayerActorPacket); - client.sendPacketQueue.Add(reply5); - client.sendPacketQueue.Add(reply6); - + client.queuePacket(BasePacket.createPacket(SetMapPacket.buildPacket(player.actorID, 0xD1), true, false)); + client.queuePacket(BasePacket.createPacket(_0x2Packet.buildPacket(player.actorID), true, false)); + client.queuePacket(reply5); + client.queuePacket(reply6); + client.queuePacket(BasePacket.createPacket(player.getActor().createNamePacket(player.actorID), true, false)); + client.queuePacket(BasePacket.createPacket(player.getActor().createAppearancePacket(player.actorID), true, false)); + + ////////ITEMS//////// + client.queuePacket(BasePacket.createPacket(InventoryBeginChangePacket.buildPacket(player.actorID), true, false)); + +#region itemsetup + //TEST List items = new List(); - items.Add(new Item(1337, 8030920, 0)); //Leather Jacket + items.Add(new Item(1337, 8030920, 5)); //Leather Jacket items.Add(new Item(1338, 8013626, 1)); //Chocobo Mask items.Add(new Item(1339, 5030402, 2)); //Thyrus items.Add(new Item(1340, 8013635, 3)); //Dalamud Horn items.Add(new Item(1341, 10100132, 4)); //Savage Might 4 + items.Add(new Item(1342, 8032407, 6)); //Green Summer Halter (Female) + items.Add(new Item(1343, 8051307, 7)); //Green Summer Tanga (Female) + items.Add(new Item(1344, 8050766, 8)); //Flame Private's Saroul int count = 0; @@ -240,20 +250,37 @@ namespace FFXIVClassic_Lobby_Server setinvPackets.Add(beginInventory); setinvPackets.Add(setInventory); setinvPackets.Add(endInventory); +#endregion - BasePacket setInvBasePacket = BasePacket.createPacket(setinvPackets, true, false); - client.sendPacketQueue.Add(setInvBasePacket); + client.queuePacket(BasePacket.createPacket(setinvPackets, true, false)); + //client.queuePacket(setinv); + //client.queuePacket(currancy); + //client.queuePacket(keyitems); - //client.sendPacketQueue.Add(setinv); - //client.sendPacketQueue.Add(currancy); - //client.sendPacketQueue.Add(keyitems); +#region equipsetup + SetInitialEquipmentPacket initialEqupmentPacket = new SetInitialEquipmentPacket(); + initialEqupmentPacket.setItem(SetInitialEquipmentPacket.SLOT_BODY, 5); + initialEqupmentPacket.setItem(SetInitialEquipmentPacket.SLOT_HEAD, 3); + initialEqupmentPacket.setItem(SetInitialEquipmentPacket.SLOT_UNDERSHIRT, 6); + initialEqupmentPacket.setItem(SetInitialEquipmentPacket.SLOT_UNDERGARMENT, 7); + initialEqupmentPacket.setItem(SetInitialEquipmentPacket.SLOT_MAINHAND, 2); + initialEqupmentPacket.setItem(SetInitialEquipmentPacket.SLOT_LEGS, 8); +#endregion + //Equip Init + client.queuePacket(BasePacket.createPacket(InventorySetBeginPacket.buildPacket(player.actorID, 0x23, InventorySetBeginPacket.CODE_EQUIPMENT), true, false)); + client.queuePacket(BasePacket.createPacket(initialEqupmentPacket.buildPackets(player.actorID), true, false)); + client.queuePacket(BasePacket.createPacket(InventorySetEndPacket.buildPacket(player.actorID), true, false)); - client.sendPacketQueue.Add(reply7); - client.sendPacketQueue.Add(reply8); - client.sendPacketQueue.Add(reply9); - client.sendPacketQueue.Add(reply10); + client.queuePacket(BasePacket.createPacket(InventoryEndChangePacket.buildPacket(player.actorID), true, false)); + ////////ITEMS//////// + + //The rest of hardcode + client.queuePacket(reply7); + client.queuePacket(reply8); + client.queuePacket(reply9); + client.queuePacket(reply10); break; //Chat Received diff --git a/FFXIVClassic Map Server/bin/Debug/FFXIVClassic Map Server.vshost.exe.manifest b/FFXIVClassic Map Server/bin/Debug/FFXIVClassic Map Server.vshost.exe.manifest deleted file mode 100644 index 061c9ca9..00000000 --- a/FFXIVClassic Map Server/bin/Debug/FFXIVClassic Map Server.vshost.exe.manifest +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/FFXIVClassic Map Server/bin/Debug/packets/login/login6_data.bin b/FFXIVClassic Map Server/bin/Debug/packets/login/login6_data.bin index 51c98980..95c8e4c2 100644 Binary files a/FFXIVClassic Map Server/bin/Debug/packets/login/login6_data.bin and b/FFXIVClassic Map Server/bin/Debug/packets/login/login6_data.bin differ diff --git a/FFXIVClassic Map Server/bin/Debug/packets/login/login7_data.bin b/FFXIVClassic Map Server/bin/Debug/packets/login/login7_data.bin index ec1a0710..c13225ea 100644 Binary files a/FFXIVClassic Map Server/bin/Debug/packets/login/login7_data.bin and b/FFXIVClassic Map Server/bin/Debug/packets/login/login7_data.bin differ diff --git a/FFXIVClassic Map Server/common/Blowfish.cs b/FFXIVClassic Map Server/common/Blowfish.cs index 25eab806..92305b58 100644 --- a/FFXIVClassic Map Server/common/Blowfish.cs +++ b/FFXIVClassic Map Server/common/Blowfish.cs @@ -1,31 +1,293 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Text; -using System.IO; -using System.Runtime.InteropServices; +using System.Threading.Tasks; namespace FFXIVClassic_Lobby_Server.common { - public class Blowfish - { - [DllImport("./Blowfish.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern short initializeBlowfish(byte[] key, short keySize, uint[] P, uint[,] S); - [DllImport("./Blowfish.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern void blowfish_encipher(ref int xl, ref int xr, uint[] P); - [DllImport("./Blowfish.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern void blowfish_decipher(ref int xl, ref int xr, uint[] P); + { + const int N = 16; + UInt32 [] P = new uint[16 + 2]; + UInt32 [,] S = new UInt32[4,256]; + + #region P and S Values + + byte [] P_values = + { + 0x88, 0x6A, 0x3F, 0x24, 0xD3, 0x08, 0xA3, 0x85, 0x2E, 0x8A, 0x19, 0x13, 0x44, 0x73, 0x70, 0x03, + 0x22, 0x38, 0x09, 0xA4, 0xD0, 0x31, 0x9F, 0x29, 0x98, 0xFA, 0x2E, 0x08, 0x89, 0x6C, 0x4E, 0xEC, + 0xE6, 0x21, 0x28, 0x45, 0x77, 0x13, 0xD0, 0x38, 0xCF, 0x66, 0x54, 0xBE, 0x6C, 0x0C, 0xE9, 0x34, + 0xB7, 0x29, 0xAC, 0xC0, 0xDD, 0x50, 0x7C, 0xC9, 0xB5, 0xD5, 0x84, 0x3F, 0x17, 0x09, 0x47, 0xB5, + 0xD9, 0xD5, 0x16, 0x92, 0x1B, 0xFB, 0x79, 0x89 + }; + + byte [] S_values = + { + 0xA6, 0x0B, 0x31, 0xD1, 0xAC, 0xB5, 0xDF, 0x98, 0xDB, 0x72, 0xFD, 0x2F, 0xB7, 0xDF, 0x1A, 0xD0, + 0xED, 0xAF, 0xE1, 0xB8, 0x96, 0x7E, 0x26, 0x6A, 0x45, 0x90, 0x7C, 0xBA, 0x99, 0x7F, 0x2C, 0xF1, + 0x47, 0x99, 0xA1, 0x24, 0xF7, 0x6C, 0x91, 0xB3, 0xE2, 0xF2, 0x01, 0x08, 0x16, 0xFC, 0x8E, 0x85, + 0xD8, 0x20, 0x69, 0x63, 0x69, 0x4E, 0x57, 0x71, 0xA3, 0xFE, 0x58, 0xA4, 0x7E, 0x3D, 0x93, 0xF4, + 0x8F, 0x74, 0x95, 0x0D, 0x58, 0xB6, 0x8E, 0x72, 0x58, 0xCD, 0x8B, 0x71, 0xEE, 0x4A, 0x15, 0x82, + 0x1D, 0xA4, 0x54, 0x7B, 0xB5, 0x59, 0x5A, 0xC2, 0x39, 0xD5, 0x30, 0x9C, 0x13, 0x60, 0xF2, 0x2A, + 0x23, 0xB0, 0xD1, 0xC5, 0xF0, 0x85, 0x60, 0x28, 0x18, 0x79, 0x41, 0xCA, 0xEF, 0x38, 0xDB, 0xB8, + 0xB0, 0xDC, 0x79, 0x8E, 0x0E, 0x18, 0x3A, 0x60, 0x8B, 0x0E, 0x9E, 0x6C, 0x3E, 0x8A, 0x1E, 0xB0, + 0xC1, 0x77, 0x15, 0xD7, 0x27, 0x4B, 0x31, 0xBD, 0xDA, 0x2F, 0xAF, 0x78, 0x60, 0x5C, 0x60, 0x55, + 0xF3, 0x25, 0x55, 0xE6, 0x94, 0xAB, 0x55, 0xAA, 0x62, 0x98, 0x48, 0x57, 0x40, 0x14, 0xE8, 0x63, + 0x6A, 0x39, 0xCA, 0x55, 0xB6, 0x10, 0xAB, 0x2A, 0x34, 0x5C, 0xCC, 0xB4, 0xCE, 0xE8, 0x41, 0x11, + 0xAF, 0x86, 0x54, 0xA1, 0x93, 0xE9, 0x72, 0x7C, 0x11, 0x14, 0xEE, 0xB3, 0x2A, 0xBC, 0x6F, 0x63, + 0x5D, 0xC5, 0xA9, 0x2B, 0xF6, 0x31, 0x18, 0x74, 0x16, 0x3E, 0x5C, 0xCE, 0x1E, 0x93, 0x87, 0x9B, + 0x33, 0xBA, 0xD6, 0xAF, 0x5C, 0xCF, 0x24, 0x6C, 0x81, 0x53, 0x32, 0x7A, 0x77, 0x86, 0x95, 0x28, + 0x98, 0x48, 0x8F, 0x3B, 0xAF, 0xB9, 0x4B, 0x6B, 0x1B, 0xE8, 0xBF, 0xC4, 0x93, 0x21, 0x28, 0x66, + 0xCC, 0x09, 0xD8, 0x61, 0x91, 0xA9, 0x21, 0xFB, 0x60, 0xAC, 0x7C, 0x48, 0x32, 0x80, 0xEC, 0x5D, + 0x5D, 0x5D, 0x84, 0xEF, 0xB1, 0x75, 0x85, 0xE9, 0x02, 0x23, 0x26, 0xDC, 0x88, 0x1B, 0x65, 0xEB, + 0x81, 0x3E, 0x89, 0x23, 0xC5, 0xAC, 0x96, 0xD3, 0xF3, 0x6F, 0x6D, 0x0F, 0x39, 0x42, 0xF4, 0x83, + 0x82, 0x44, 0x0B, 0x2E, 0x04, 0x20, 0x84, 0xA4, 0x4A, 0xF0, 0xC8, 0x69, 0x5E, 0x9B, 0x1F, 0x9E, + 0x42, 0x68, 0xC6, 0x21, 0x9A, 0x6C, 0xE9, 0xF6, 0x61, 0x9C, 0x0C, 0x67, 0xF0, 0x88, 0xD3, 0xAB, + 0xD2, 0xA0, 0x51, 0x6A, 0x68, 0x2F, 0x54, 0xD8, 0x28, 0xA7, 0x0F, 0x96, 0xA3, 0x33, 0x51, 0xAB, + 0x6C, 0x0B, 0xEF, 0x6E, 0xE4, 0x3B, 0x7A, 0x13, 0x50, 0xF0, 0x3B, 0xBA, 0x98, 0x2A, 0xFB, 0x7E, + 0x1D, 0x65, 0xF1, 0xA1, 0x76, 0x01, 0xAF, 0x39, 0x3E, 0x59, 0xCA, 0x66, 0x88, 0x0E, 0x43, 0x82, + 0x19, 0x86, 0xEE, 0x8C, 0xB4, 0x9F, 0x6F, 0x45, 0xC3, 0xA5, 0x84, 0x7D, 0xBE, 0x5E, 0x8B, 0x3B, + 0xD8, 0x75, 0x6F, 0xE0, 0x73, 0x20, 0xC1, 0x85, 0x9F, 0x44, 0x1A, 0x40, 0xA6, 0x6A, 0xC1, 0x56, + 0x62, 0xAA, 0xD3, 0x4E, 0x06, 0x77, 0x3F, 0x36, 0x72, 0xDF, 0xFE, 0x1B, 0x3D, 0x02, 0x9B, 0x42, + 0x24, 0xD7, 0xD0, 0x37, 0x48, 0x12, 0x0A, 0xD0, 0xD3, 0xEA, 0x0F, 0xDB, 0x9B, 0xC0, 0xF1, 0x49, + 0xC9, 0x72, 0x53, 0x07, 0x7B, 0x1B, 0x99, 0x80, 0xD8, 0x79, 0xD4, 0x25, 0xF7, 0xDE, 0xE8, 0xF6, + 0x1A, 0x50, 0xFE, 0xE3, 0x3B, 0x4C, 0x79, 0xB6, 0xBD, 0xE0, 0x6C, 0x97, 0xBA, 0x06, 0xC0, 0x04, + 0xB6, 0x4F, 0xA9, 0xC1, 0xC4, 0x60, 0x9F, 0x40, 0xC2, 0x9E, 0x5C, 0x5E, 0x63, 0x24, 0x6A, 0x19, + 0xAF, 0x6F, 0xFB, 0x68, 0xB5, 0x53, 0x6C, 0x3E, 0xEB, 0xB2, 0x39, 0x13, 0x6F, 0xEC, 0x52, 0x3B, + 0x1F, 0x51, 0xFC, 0x6D, 0x2C, 0x95, 0x30, 0x9B, 0x44, 0x45, 0x81, 0xCC, 0x09, 0xBD, 0x5E, 0xAF, + 0x04, 0xD0, 0xE3, 0xBE, 0xFD, 0x4A, 0x33, 0xDE, 0x07, 0x28, 0x0F, 0x66, 0xB3, 0x4B, 0x2E, 0x19, + 0x57, 0xA8, 0xCB, 0xC0, 0x0F, 0x74, 0xC8, 0x45, 0x39, 0x5F, 0x0B, 0xD2, 0xDB, 0xFB, 0xD3, 0xB9, + 0xBD, 0xC0, 0x79, 0x55, 0x0A, 0x32, 0x60, 0x1A, 0xC6, 0x00, 0xA1, 0xD6, 0x79, 0x72, 0x2C, 0x40, + 0xFE, 0x25, 0x9F, 0x67, 0xCC, 0xA3, 0x1F, 0xFB, 0xF8, 0xE9, 0xA5, 0x8E, 0xF8, 0x22, 0x32, 0xDB, + 0xDF, 0x16, 0x75, 0x3C, 0x15, 0x6B, 0x61, 0xFD, 0xC8, 0x1E, 0x50, 0x2F, 0xAB, 0x52, 0x05, 0xAD, + 0xFA, 0xB5, 0x3D, 0x32, 0x60, 0x87, 0x23, 0xFD, 0x48, 0x7B, 0x31, 0x53, 0x82, 0xDF, 0x00, 0x3E, + 0xBB, 0x57, 0x5C, 0x9E, 0xA0, 0x8C, 0x6F, 0xCA, 0x2E, 0x56, 0x87, 0x1A, 0xDB, 0x69, 0x17, 0xDF, + 0xF6, 0xA8, 0x42, 0xD5, 0xC3, 0xFF, 0x7E, 0x28, 0xC6, 0x32, 0x67, 0xAC, 0x73, 0x55, 0x4F, 0x8C, + 0xB0, 0x27, 0x5B, 0x69, 0xC8, 0x58, 0xCA, 0xBB, 0x5D, 0xA3, 0xFF, 0xE1, 0xA0, 0x11, 0xF0, 0xB8, + 0x98, 0x3D, 0xFA, 0x10, 0xB8, 0x83, 0x21, 0xFD, 0x6C, 0xB5, 0xFC, 0x4A, 0x5B, 0xD3, 0xD1, 0x2D, + 0x79, 0xE4, 0x53, 0x9A, 0x65, 0x45, 0xF8, 0xB6, 0xBC, 0x49, 0x8E, 0xD2, 0x90, 0x97, 0xFB, 0x4B, + 0xDA, 0xF2, 0xDD, 0xE1, 0x33, 0x7E, 0xCB, 0xA4, 0x41, 0x13, 0xFB, 0x62, 0xE8, 0xC6, 0xE4, 0xCE, + 0xDA, 0xCA, 0x20, 0xEF, 0x01, 0x4C, 0x77, 0x36, 0xFE, 0x9E, 0x7E, 0xD0, 0xB4, 0x1F, 0xF1, 0x2B, + 0x4D, 0xDA, 0xDB, 0x95, 0x98, 0x91, 0x90, 0xAE, 0x71, 0x8E, 0xAD, 0xEA, 0xA0, 0xD5, 0x93, 0x6B, + 0xD0, 0xD1, 0x8E, 0xD0, 0xE0, 0x25, 0xC7, 0xAF, 0x2F, 0x5B, 0x3C, 0x8E, 0xB7, 0x94, 0x75, 0x8E, + 0xFB, 0xE2, 0xF6, 0x8F, 0x64, 0x2B, 0x12, 0xF2, 0x12, 0xB8, 0x88, 0x88, 0x1C, 0xF0, 0x0D, 0x90, + 0xA0, 0x5E, 0xAD, 0x4F, 0x1C, 0xC3, 0x8F, 0x68, 0x91, 0xF1, 0xCF, 0xD1, 0xAD, 0xC1, 0xA8, 0xB3, + 0x18, 0x22, 0x2F, 0x2F, 0x77, 0x17, 0x0E, 0xBE, 0xFE, 0x2D, 0x75, 0xEA, 0xA1, 0x1F, 0x02, 0x8B, + 0x0F, 0xCC, 0xA0, 0xE5, 0xE8, 0x74, 0x6F, 0xB5, 0xD6, 0xF3, 0xAC, 0x18, 0x99, 0xE2, 0x89, 0xCE, + 0xE0, 0x4F, 0xA8, 0xB4, 0xB7, 0xE0, 0x13, 0xFD, 0x81, 0x3B, 0xC4, 0x7C, 0xD9, 0xA8, 0xAD, 0xD2, + 0x66, 0xA2, 0x5F, 0x16, 0x05, 0x77, 0x95, 0x80, 0x14, 0x73, 0xCC, 0x93, 0x77, 0x14, 0x1A, 0x21, + 0x65, 0x20, 0xAD, 0xE6, 0x86, 0xFA, 0xB5, 0x77, 0xF5, 0x42, 0x54, 0xC7, 0xCF, 0x35, 0x9D, 0xFB, + 0x0C, 0xAF, 0xCD, 0xEB, 0xA0, 0x89, 0x3E, 0x7B, 0xD3, 0x1B, 0x41, 0xD6, 0x49, 0x7E, 0x1E, 0xAE, + 0x2D, 0x0E, 0x25, 0x00, 0x5E, 0xB3, 0x71, 0x20, 0xBB, 0x00, 0x68, 0x22, 0xAF, 0xE0, 0xB8, 0x57, + 0x9B, 0x36, 0x64, 0x24, 0x1E, 0xB9, 0x09, 0xF0, 0x1D, 0x91, 0x63, 0x55, 0xAA, 0xA6, 0xDF, 0x59, + 0x89, 0x43, 0xC1, 0x78, 0x7F, 0x53, 0x5A, 0xD9, 0xA2, 0x5B, 0x7D, 0x20, 0xC5, 0xB9, 0xE5, 0x02, + 0x76, 0x03, 0x26, 0x83, 0xA9, 0xCF, 0x95, 0x62, 0x68, 0x19, 0xC8, 0x11, 0x41, 0x4A, 0x73, 0x4E, + 0xCA, 0x2D, 0x47, 0xB3, 0x4A, 0xA9, 0x14, 0x7B, 0x52, 0x00, 0x51, 0x1B, 0x15, 0x29, 0x53, 0x9A, + 0x3F, 0x57, 0x0F, 0xD6, 0xE4, 0xC6, 0x9B, 0xBC, 0x76, 0xA4, 0x60, 0x2B, 0x00, 0x74, 0xE6, 0x81, + 0xB5, 0x6F, 0xBA, 0x08, 0x1F, 0xE9, 0x1B, 0x57, 0x6B, 0xEC, 0x96, 0xF2, 0x15, 0xD9, 0x0D, 0x2A, + 0x21, 0x65, 0x63, 0xB6, 0xB6, 0xF9, 0xB9, 0xE7, 0x2E, 0x05, 0x34, 0xFF, 0x64, 0x56, 0x85, 0xC5, + 0x5D, 0x2D, 0xB0, 0x53, 0xA1, 0x8F, 0x9F, 0xA9, 0x99, 0x47, 0xBA, 0x08, 0x6A, 0x07, 0x85, 0x6E, + 0xE9, 0x70, 0x7A, 0x4B, 0x44, 0x29, 0xB3, 0xB5, 0x2E, 0x09, 0x75, 0xDB, 0x23, 0x26, 0x19, 0xC4, + 0xB0, 0xA6, 0x6E, 0xAD, 0x7D, 0xDF, 0xA7, 0x49, 0xB8, 0x60, 0xEE, 0x9C, 0x66, 0xB2, 0xED, 0x8F, + 0x71, 0x8C, 0xAA, 0xEC, 0xFF, 0x17, 0x9A, 0x69, 0x6C, 0x52, 0x64, 0x56, 0xE1, 0x9E, 0xB1, 0xC2, + 0xA5, 0x02, 0x36, 0x19, 0x29, 0x4C, 0x09, 0x75, 0x40, 0x13, 0x59, 0xA0, 0x3E, 0x3A, 0x18, 0xE4, + 0x9A, 0x98, 0x54, 0x3F, 0x65, 0x9D, 0x42, 0x5B, 0xD6, 0xE4, 0x8F, 0x6B, 0xD6, 0x3F, 0xF7, 0x99, + 0x07, 0x9C, 0xD2, 0xA1, 0xF5, 0x30, 0xE8, 0xEF, 0xE6, 0x38, 0x2D, 0x4D, 0xC1, 0x5D, 0x25, 0xF0, + 0x86, 0x20, 0xDD, 0x4C, 0x26, 0xEB, 0x70, 0x84, 0xC6, 0xE9, 0x82, 0x63, 0x5E, 0xCC, 0x1E, 0x02, + 0x3F, 0x6B, 0x68, 0x09, 0xC9, 0xEF, 0xBA, 0x3E, 0x14, 0x18, 0x97, 0x3C, 0xA1, 0x70, 0x6A, 0x6B, + 0x84, 0x35, 0x7F, 0x68, 0x86, 0xE2, 0xA0, 0x52, 0x05, 0x53, 0x9C, 0xB7, 0x37, 0x07, 0x50, 0xAA, + 0x1C, 0x84, 0x07, 0x3E, 0x5C, 0xAE, 0xDE, 0x7F, 0xEC, 0x44, 0x7D, 0x8E, 0xB8, 0xF2, 0x16, 0x57, + 0x37, 0xDA, 0x3A, 0xB0, 0x0D, 0x0C, 0x50, 0xF0, 0x04, 0x1F, 0x1C, 0xF0, 0xFF, 0xB3, 0x00, 0x02, + 0x1A, 0xF5, 0x0C, 0xAE, 0xB2, 0x74, 0xB5, 0x3C, 0x58, 0x7A, 0x83, 0x25, 0xBD, 0x21, 0x09, 0xDC, + 0xF9, 0x13, 0x91, 0xD1, 0xF6, 0x2F, 0xA9, 0x7C, 0x73, 0x47, 0x32, 0x94, 0x01, 0x47, 0xF5, 0x22, + 0x81, 0xE5, 0xE5, 0x3A, 0xDC, 0xDA, 0xC2, 0x37, 0x34, 0x76, 0xB5, 0xC8, 0xA7, 0xDD, 0xF3, 0x9A, + 0x46, 0x61, 0x44, 0xA9, 0x0E, 0x03, 0xD0, 0x0F, 0x3E, 0xC7, 0xC8, 0xEC, 0x41, 0x1E, 0x75, 0xA4, + 0x99, 0xCD, 0x38, 0xE2, 0x2F, 0x0E, 0xEA, 0x3B, 0xA1, 0xBB, 0x80, 0x32, 0x31, 0xB3, 0x3E, 0x18, + 0x38, 0x8B, 0x54, 0x4E, 0x08, 0xB9, 0x6D, 0x4F, 0x03, 0x0D, 0x42, 0x6F, 0xBF, 0x04, 0x0A, 0xF6, + 0x90, 0x12, 0xB8, 0x2C, 0x79, 0x7C, 0x97, 0x24, 0x72, 0xB0, 0x79, 0x56, 0xAF, 0x89, 0xAF, 0xBC, + 0x1F, 0x77, 0x9A, 0xDE, 0x10, 0x08, 0x93, 0xD9, 0x12, 0xAE, 0x8B, 0xB3, 0x2E, 0x3F, 0xCF, 0xDC, + 0x1F, 0x72, 0x12, 0x55, 0x24, 0x71, 0x6B, 0x2E, 0xE6, 0xDD, 0x1A, 0x50, 0x87, 0xCD, 0x84, 0x9F, + 0x18, 0x47, 0x58, 0x7A, 0x17, 0xDA, 0x08, 0x74, 0xBC, 0x9A, 0x9F, 0xBC, 0x8C, 0x7D, 0x4B, 0xE9, + 0x3A, 0xEC, 0x7A, 0xEC, 0xFA, 0x1D, 0x85, 0xDB, 0x66, 0x43, 0x09, 0x63, 0xD2, 0xC3, 0x64, 0xC4, + 0x47, 0x18, 0x1C, 0xEF, 0x08, 0xD9, 0x15, 0x32, 0x37, 0x3B, 0x43, 0xDD, 0x16, 0xBA, 0xC2, 0x24, + 0x43, 0x4D, 0xA1, 0x12, 0x51, 0xC4, 0x65, 0x2A, 0x02, 0x00, 0x94, 0x50, 0xDD, 0xE4, 0x3A, 0x13, + 0x9E, 0xF8, 0xDF, 0x71, 0x55, 0x4E, 0x31, 0x10, 0xD6, 0x77, 0xAC, 0x81, 0x9B, 0x19, 0x11, 0x5F, + 0xF1, 0x56, 0x35, 0x04, 0x6B, 0xC7, 0xA3, 0xD7, 0x3B, 0x18, 0x11, 0x3C, 0x09, 0xA5, 0x24, 0x59, + 0xED, 0xE6, 0x8F, 0xF2, 0xFA, 0xFB, 0xF1, 0x97, 0x2C, 0xBF, 0xBA, 0x9E, 0x6E, 0x3C, 0x15, 0x1E, + 0x70, 0x45, 0xE3, 0x86, 0xB1, 0x6F, 0xE9, 0xEA, 0x0A, 0x5E, 0x0E, 0x86, 0xB3, 0x2A, 0x3E, 0x5A, + 0x1C, 0xE7, 0x1F, 0x77, 0xFA, 0x06, 0x3D, 0x4E, 0xB9, 0xDC, 0x65, 0x29, 0x0F, 0x1D, 0xE7, 0x99, + 0xD6, 0x89, 0x3E, 0x80, 0x25, 0xC8, 0x66, 0x52, 0x78, 0xC9, 0x4C, 0x2E, 0x6A, 0xB3, 0x10, 0x9C, + 0xBA, 0x0E, 0x15, 0xC6, 0x78, 0xEA, 0xE2, 0x94, 0x53, 0x3C, 0xFC, 0xA5, 0xF4, 0x2D, 0x0A, 0x1E, + 0xA7, 0x4E, 0xF7, 0xF2, 0x3D, 0x2B, 0x1D, 0x36, 0x0F, 0x26, 0x39, 0x19, 0x60, 0x79, 0xC2, 0x19, + 0x08, 0xA7, 0x23, 0x52, 0xB6, 0x12, 0x13, 0xF7, 0x6E, 0xFE, 0xAD, 0xEB, 0x66, 0x1F, 0xC3, 0xEA, + 0x95, 0x45, 0xBC, 0xE3, 0x83, 0xC8, 0x7B, 0xA6, 0xD1, 0x37, 0x7F, 0xB1, 0x28, 0xFF, 0x8C, 0x01, + 0xEF, 0xDD, 0x32, 0xC3, 0xA5, 0x5A, 0x6C, 0xBE, 0x85, 0x21, 0x58, 0x65, 0x02, 0x98, 0xAB, 0x68, + 0x0F, 0xA5, 0xCE, 0xEE, 0x3B, 0x95, 0x2F, 0xDB, 0xAD, 0x7D, 0xEF, 0x2A, 0x84, 0x2F, 0x6E, 0x5B, + 0x28, 0xB6, 0x21, 0x15, 0x70, 0x61, 0x07, 0x29, 0x75, 0x47, 0xDD, 0xEC, 0x10, 0x15, 0x9F, 0x61, + 0x30, 0xA8, 0xCC, 0x13, 0x96, 0xBD, 0x61, 0xEB, 0x1E, 0xFE, 0x34, 0x03, 0xCF, 0x63, 0x03, 0xAA, + 0x90, 0x5C, 0x73, 0xB5, 0x39, 0xA2, 0x70, 0x4C, 0x0B, 0x9E, 0x9E, 0xD5, 0x14, 0xDE, 0xAA, 0xCB, + 0xBC, 0x86, 0xCC, 0xEE, 0xA7, 0x2C, 0x62, 0x60, 0xAB, 0x5C, 0xAB, 0x9C, 0x6E, 0x84, 0xF3, 0xB2, + 0xAF, 0x1E, 0x8B, 0x64, 0xCA, 0xF0, 0xBD, 0x19, 0xB9, 0x69, 0x23, 0xA0, 0x50, 0xBB, 0x5A, 0x65, + 0x32, 0x5A, 0x68, 0x40, 0xB3, 0xB4, 0x2A, 0x3C, 0xD5, 0xE9, 0x9E, 0x31, 0xF7, 0xB8, 0x21, 0xC0, + 0x19, 0x0B, 0x54, 0x9B, 0x99, 0xA0, 0x5F, 0x87, 0x7E, 0x99, 0xF7, 0x95, 0xA8, 0x7D, 0x3D, 0x62, + 0x9A, 0x88, 0x37, 0xF8, 0x77, 0x2D, 0xE3, 0x97, 0x5F, 0x93, 0xED, 0x11, 0x81, 0x12, 0x68, 0x16, + 0x29, 0x88, 0x35, 0x0E, 0xD6, 0x1F, 0xE6, 0xC7, 0xA1, 0xDF, 0xDE, 0x96, 0x99, 0xBA, 0x58, 0x78, + 0xA5, 0x84, 0xF5, 0x57, 0x63, 0x72, 0x22, 0x1B, 0xFF, 0xC3, 0x83, 0x9B, 0x96, 0x46, 0xC2, 0x1A, + 0xEB, 0x0A, 0xB3, 0xCD, 0x54, 0x30, 0x2E, 0x53, 0xE4, 0x48, 0xD9, 0x8F, 0x28, 0x31, 0xBC, 0x6D, + 0xEF, 0xF2, 0xEB, 0x58, 0xEA, 0xFF, 0xC6, 0x34, 0x61, 0xED, 0x28, 0xFE, 0x73, 0x3C, 0x7C, 0xEE, + 0xD9, 0x14, 0x4A, 0x5D, 0xE3, 0xB7, 0x64, 0xE8, 0x14, 0x5D, 0x10, 0x42, 0xE0, 0x13, 0x3E, 0x20, + 0xB6, 0xE2, 0xEE, 0x45, 0xEA, 0xAB, 0xAA, 0xA3, 0x15, 0x4F, 0x6C, 0xDB, 0xD0, 0x4F, 0xCB, 0xFA, + 0x42, 0xF4, 0x42, 0xC7, 0xB5, 0xBB, 0x6A, 0xEF, 0x1D, 0x3B, 0x4F, 0x65, 0x05, 0x21, 0xCD, 0x41, + 0x9E, 0x79, 0x1E, 0xD8, 0xC7, 0x4D, 0x85, 0x86, 0x6A, 0x47, 0x4B, 0xE4, 0x50, 0x62, 0x81, 0x3D, + 0xF2, 0xA1, 0x62, 0xCF, 0x46, 0x26, 0x8D, 0x5B, 0xA0, 0x83, 0x88, 0xFC, 0xA3, 0xB6, 0xC7, 0xC1, + 0xC3, 0x24, 0x15, 0x7F, 0x92, 0x74, 0xCB, 0x69, 0x0B, 0x8A, 0x84, 0x47, 0x85, 0xB2, 0x92, 0x56, + 0x00, 0xBF, 0x5B, 0x09, 0x9D, 0x48, 0x19, 0xAD, 0x74, 0xB1, 0x62, 0x14, 0x00, 0x0E, 0x82, 0x23, + 0x2A, 0x8D, 0x42, 0x58, 0xEA, 0xF5, 0x55, 0x0C, 0x3E, 0xF4, 0xAD, 0x1D, 0x61, 0x70, 0x3F, 0x23, + 0x92, 0xF0, 0x72, 0x33, 0x41, 0x7E, 0x93, 0x8D, 0xF1, 0xEC, 0x5F, 0xD6, 0xDB, 0x3B, 0x22, 0x6C, + 0x59, 0x37, 0xDE, 0x7C, 0x60, 0x74, 0xEE, 0xCB, 0xA7, 0xF2, 0x85, 0x40, 0x6E, 0x32, 0x77, 0xCE, + 0x84, 0x80, 0x07, 0xA6, 0x9E, 0x50, 0xF8, 0x19, 0x55, 0xD8, 0xEF, 0xE8, 0x35, 0x97, 0xD9, 0x61, + 0xAA, 0xA7, 0x69, 0xA9, 0xC2, 0x06, 0x0C, 0xC5, 0xFC, 0xAB, 0x04, 0x5A, 0xDC, 0xCA, 0x0B, 0x80, + 0x2E, 0x7A, 0x44, 0x9E, 0x84, 0x34, 0x45, 0xC3, 0x05, 0x67, 0xD5, 0xFD, 0xC9, 0x9E, 0x1E, 0x0E, + 0xD3, 0xDB, 0x73, 0xDB, 0xCD, 0x88, 0x55, 0x10, 0x79, 0xDA, 0x5F, 0x67, 0x40, 0x43, 0x67, 0xE3, + 0x65, 0x34, 0xC4, 0xC5, 0xD8, 0x38, 0x3E, 0x71, 0x9E, 0xF8, 0x28, 0x3D, 0x20, 0xFF, 0x6D, 0xF1, + 0xE7, 0x21, 0x3E, 0x15, 0x4A, 0x3D, 0xB0, 0x8F, 0x2B, 0x9F, 0xE3, 0xE6, 0xF7, 0xAD, 0x83, 0xDB, + 0x68, 0x5A, 0x3D, 0xE9, 0xF7, 0x40, 0x81, 0x94, 0x1C, 0x26, 0x4C, 0xF6, 0x34, 0x29, 0x69, 0x94, + 0xF7, 0x20, 0x15, 0x41, 0xF7, 0xD4, 0x02, 0x76, 0x2E, 0x6B, 0xF4, 0xBC, 0x68, 0x00, 0xA2, 0xD4, + 0x71, 0x24, 0x08, 0xD4, 0x6A, 0xF4, 0x20, 0x33, 0xB7, 0xD4, 0xB7, 0x43, 0xAF, 0x61, 0x00, 0x50, + 0x2E, 0xF6, 0x39, 0x1E, 0x46, 0x45, 0x24, 0x97, 0x74, 0x4F, 0x21, 0x14, 0x40, 0x88, 0x8B, 0xBF, + 0x1D, 0xFC, 0x95, 0x4D, 0xAF, 0x91, 0xB5, 0x96, 0xD3, 0xDD, 0xF4, 0x70, 0x45, 0x2F, 0xA0, 0x66, + 0xEC, 0x09, 0xBC, 0xBF, 0x85, 0x97, 0xBD, 0x03, 0xD0, 0x6D, 0xAC, 0x7F, 0x04, 0x85, 0xCB, 0x31, + 0xB3, 0x27, 0xEB, 0x96, 0x41, 0x39, 0xFD, 0x55, 0xE6, 0x47, 0x25, 0xDA, 0x9A, 0x0A, 0xCA, 0xAB, + 0x25, 0x78, 0x50, 0x28, 0xF4, 0x29, 0x04, 0x53, 0xDA, 0x86, 0x2C, 0x0A, 0xFB, 0x6D, 0xB6, 0xE9, + 0x62, 0x14, 0xDC, 0x68, 0x00, 0x69, 0x48, 0xD7, 0xA4, 0xC0, 0x0E, 0x68, 0xEE, 0x8D, 0xA1, 0x27, + 0xA2, 0xFE, 0x3F, 0x4F, 0x8C, 0xAD, 0x87, 0xE8, 0x06, 0xE0, 0x8C, 0xB5, 0xB6, 0xD6, 0xF4, 0x7A, + 0x7C, 0x1E, 0xCE, 0xAA, 0xEC, 0x5F, 0x37, 0xD3, 0x99, 0xA3, 0x78, 0xCE, 0x42, 0x2A, 0x6B, 0x40, + 0x35, 0x9E, 0xFE, 0x20, 0xB9, 0x85, 0xF3, 0xD9, 0xAB, 0xD7, 0x39, 0xEE, 0x8B, 0x4E, 0x12, 0x3B, + 0xF7, 0xFA, 0xC9, 0x1D, 0x56, 0x18, 0x6D, 0x4B, 0x31, 0x66, 0xA3, 0x26, 0xB2, 0x97, 0xE3, 0xEA, + 0x74, 0xFA, 0x6E, 0x3A, 0x32, 0x43, 0x5B, 0xDD, 0xF7, 0xE7, 0x41, 0x68, 0xFB, 0x20, 0x78, 0xCA, + 0x4E, 0xF5, 0x0A, 0xFB, 0x97, 0xB3, 0xFE, 0xD8, 0xAC, 0x56, 0x40, 0x45, 0x27, 0x95, 0x48, 0xBA, + 0x3A, 0x3A, 0x53, 0x55, 0x87, 0x8D, 0x83, 0x20, 0xB7, 0xA9, 0x6B, 0xFE, 0x4B, 0x95, 0x96, 0xD0, + 0xBC, 0x67, 0xA8, 0x55, 0x58, 0x9A, 0x15, 0xA1, 0x63, 0x29, 0xA9, 0xCC, 0x33, 0xDB, 0xE1, 0x99, + 0x56, 0x4A, 0x2A, 0xA6, 0xF9, 0x25, 0x31, 0x3F, 0x1C, 0x7E, 0xF4, 0x5E, 0x7C, 0x31, 0x29, 0x90, + 0x02, 0xE8, 0xF8, 0xFD, 0x70, 0x2F, 0x27, 0x04, 0x5C, 0x15, 0xBB, 0x80, 0xE3, 0x2C, 0x28, 0x05, + 0x48, 0x15, 0xC1, 0x95, 0x22, 0x6D, 0xC6, 0xE4, 0x3F, 0x13, 0xC1, 0x48, 0xDC, 0x86, 0x0F, 0xC7, + 0xEE, 0xC9, 0xF9, 0x07, 0x0F, 0x1F, 0x04, 0x41, 0xA4, 0x79, 0x47, 0x40, 0x17, 0x6E, 0x88, 0x5D, + 0xEB, 0x51, 0x5F, 0x32, 0xD1, 0xC0, 0x9B, 0xD5, 0x8F, 0xC1, 0xBC, 0xF2, 0x64, 0x35, 0x11, 0x41, + 0x34, 0x78, 0x7B, 0x25, 0x60, 0x9C, 0x2A, 0x60, 0xA3, 0xE8, 0xF8, 0xDF, 0x1B, 0x6C, 0x63, 0x1F, + 0xC2, 0xB4, 0x12, 0x0E, 0x9E, 0x32, 0xE1, 0x02, 0xD1, 0x4F, 0x66, 0xAF, 0x15, 0x81, 0xD1, 0xCA, + 0xE0, 0x95, 0x23, 0x6B, 0xE1, 0x92, 0x3E, 0x33, 0x62, 0x0B, 0x24, 0x3B, 0x22, 0xB9, 0xBE, 0xEE, + 0x0E, 0xA2, 0xB2, 0x85, 0x99, 0x0D, 0xBA, 0xE6, 0x8C, 0x0C, 0x72, 0xDE, 0x28, 0xF7, 0xA2, 0x2D, + 0x45, 0x78, 0x12, 0xD0, 0xFD, 0x94, 0xB7, 0x95, 0x62, 0x08, 0x7D, 0x64, 0xF0, 0xF5, 0xCC, 0xE7, + 0x6F, 0xA3, 0x49, 0x54, 0xFA, 0x48, 0x7D, 0x87, 0x27, 0xFD, 0x9D, 0xC3, 0x1E, 0x8D, 0x3E, 0xF3, + 0x41, 0x63, 0x47, 0x0A, 0x74, 0xFF, 0x2E, 0x99, 0xAB, 0x6E, 0x6F, 0x3A, 0x37, 0xFD, 0xF8, 0xF4, + 0x60, 0xDC, 0x12, 0xA8, 0xF8, 0xDD, 0xEB, 0xA1, 0x4C, 0xE1, 0x1B, 0x99, 0x0D, 0x6B, 0x6E, 0xDB, + 0x10, 0x55, 0x7B, 0xC6, 0x37, 0x2C, 0x67, 0x6D, 0x3B, 0xD4, 0x65, 0x27, 0x04, 0xE8, 0xD0, 0xDC, + 0xC7, 0x0D, 0x29, 0xF1, 0xA3, 0xFF, 0x00, 0xCC, 0x92, 0x0F, 0x39, 0xB5, 0x0B, 0xED, 0x0F, 0x69, + 0xFB, 0x9F, 0x7B, 0x66, 0x9C, 0x7D, 0xDB, 0xCE, 0x0B, 0xCF, 0x91, 0xA0, 0xA3, 0x5E, 0x15, 0xD9, + 0x88, 0x2F, 0x13, 0xBB, 0x24, 0xAD, 0x5B, 0x51, 0xBF, 0x79, 0x94, 0x7B, 0xEB, 0xD6, 0x3B, 0x76, + 0xB3, 0x2E, 0x39, 0x37, 0x79, 0x59, 0x11, 0xCC, 0x97, 0xE2, 0x26, 0x80, 0x2D, 0x31, 0x2E, 0xF4, + 0xA7, 0xAD, 0x42, 0x68, 0x3B, 0x2B, 0x6A, 0xC6, 0xCC, 0x4C, 0x75, 0x12, 0x1C, 0xF1, 0x2E, 0x78, + 0x37, 0x42, 0x12, 0x6A, 0xE7, 0x51, 0x92, 0xB7, 0xE6, 0xBB, 0xA1, 0x06, 0x50, 0x63, 0xFB, 0x4B, + 0x18, 0x10, 0x6B, 0x1A, 0xFA, 0xED, 0xCA, 0x11, 0xD8, 0xBD, 0x25, 0x3D, 0xC9, 0xC3, 0xE1, 0xE2, + 0x59, 0x16, 0x42, 0x44, 0x86, 0x13, 0x12, 0x0A, 0x6E, 0xEC, 0x0C, 0xD9, 0x2A, 0xEA, 0xAB, 0xD5, + 0x4E, 0x67, 0xAF, 0x64, 0x5F, 0xA8, 0x86, 0xDA, 0x88, 0xE9, 0xBF, 0xBE, 0xFE, 0xC3, 0xE4, 0x64, + 0x57, 0x80, 0xBC, 0x9D, 0x86, 0xC0, 0xF7, 0xF0, 0xF8, 0x7B, 0x78, 0x60, 0x4D, 0x60, 0x03, 0x60, + 0x46, 0x83, 0xFD, 0xD1, 0xB0, 0x1F, 0x38, 0xF6, 0x04, 0xAE, 0x45, 0x77, 0xCC, 0xFC, 0x36, 0xD7, + 0x33, 0x6B, 0x42, 0x83, 0x71, 0xAB, 0x1E, 0xF0, 0x87, 0x41, 0x80, 0xB0, 0x5F, 0x5E, 0x00, 0x3C, + 0xBE, 0x57, 0xA0, 0x77, 0x24, 0xAE, 0xE8, 0xBD, 0x99, 0x42, 0x46, 0x55, 0x61, 0x2E, 0x58, 0xBF, + 0x8F, 0xF4, 0x58, 0x4E, 0xA2, 0xFD, 0xDD, 0xF2, 0x38, 0xEF, 0x74, 0xF4, 0xC2, 0xBD, 0x89, 0x87, + 0xC3, 0xF9, 0x66, 0x53, 0x74, 0x8E, 0xB3, 0xC8, 0x55, 0xF2, 0x75, 0xB4, 0xB9, 0xD9, 0xFC, 0x46, + 0x61, 0x26, 0xEB, 0x7A, 0x84, 0xDF, 0x1D, 0x8B, 0x79, 0x0E, 0x6A, 0x84, 0xE2, 0x95, 0x5F, 0x91, + 0x8E, 0x59, 0x6E, 0x46, 0x70, 0x57, 0xB4, 0x20, 0x91, 0x55, 0xD5, 0x8C, 0x4C, 0xDE, 0x02, 0xC9, + 0xE1, 0xAC, 0x0B, 0xB9, 0xD0, 0x05, 0x82, 0xBB, 0x48, 0x62, 0xA8, 0x11, 0x9E, 0xA9, 0x74, 0x75, + 0xB6, 0x19, 0x7F, 0xB7, 0x09, 0xDC, 0xA9, 0xE0, 0xA1, 0x09, 0x2D, 0x66, 0x33, 0x46, 0x32, 0xC4, + 0x02, 0x1F, 0x5A, 0xE8, 0x8C, 0xBE, 0xF0, 0x09, 0x25, 0xA0, 0x99, 0x4A, 0x10, 0xFE, 0x6E, 0x1D, + 0x1D, 0x3D, 0xB9, 0x1A, 0xDF, 0xA4, 0xA5, 0x0B, 0x0F, 0xF2, 0x86, 0xA1, 0x69, 0xF1, 0x68, 0x28, + 0x83, 0xDA, 0xB7, 0xDC, 0xFE, 0x06, 0x39, 0x57, 0x9B, 0xCE, 0xE2, 0xA1, 0x52, 0x7F, 0xCD, 0x4F, + 0x01, 0x5E, 0x11, 0x50, 0xFA, 0x83, 0x06, 0xA7, 0xC4, 0xB5, 0x02, 0xA0, 0x27, 0xD0, 0xE6, 0x0D, + 0x27, 0x8C, 0xF8, 0x9A, 0x41, 0x86, 0x3F, 0x77, 0x06, 0x4C, 0x60, 0xC3, 0xB5, 0x06, 0xA8, 0x61, + 0x28, 0x7A, 0x17, 0xF0, 0xE0, 0x86, 0xF5, 0xC0, 0xAA, 0x58, 0x60, 0x00, 0x62, 0x7D, 0xDC, 0x30, + 0xD7, 0x9E, 0xE6, 0x11, 0x63, 0xEA, 0x38, 0x23, 0x94, 0xDD, 0xC2, 0x53, 0x34, 0x16, 0xC2, 0xC2, + 0x56, 0xEE, 0xCB, 0xBB, 0xDE, 0xB6, 0xBC, 0x90, 0xA1, 0x7D, 0xFC, 0xEB, 0x76, 0x1D, 0x59, 0xCE, + 0x09, 0xE4, 0x05, 0x6F, 0x88, 0x01, 0x7C, 0x4B, 0x3D, 0x0A, 0x72, 0x39, 0x24, 0x7C, 0x92, 0x7C, + 0x5F, 0x72, 0xE3, 0x86, 0xB9, 0x9D, 0x4D, 0x72, 0xB4, 0x5B, 0xC1, 0x1A, 0xFC, 0xB8, 0x9E, 0xD3, + 0x78, 0x55, 0x54, 0xED, 0xB5, 0xA5, 0xFC, 0x08, 0xD3, 0x7C, 0x3D, 0xD8, 0xC4, 0x0F, 0xAD, 0x4D, + 0x5E, 0xEF, 0x50, 0x1E, 0xF8, 0xE6, 0x61, 0xB1, 0xD9, 0x14, 0x85, 0xA2, 0x3C, 0x13, 0x51, 0x6C, + 0xE7, 0xC7, 0xD5, 0x6F, 0xC4, 0x4E, 0xE1, 0x56, 0xCE, 0xBF, 0x2A, 0x36, 0x37, 0xC8, 0xC6, 0xDD, + 0x34, 0x32, 0x9A, 0xD7, 0x12, 0x82, 0x63, 0x92, 0x8E, 0xFA, 0x0E, 0x67, 0xE0, 0x00, 0x60, 0x40, + 0x37, 0xCE, 0x39, 0x3A, 0xCF, 0xF5, 0xFA, 0xD3, 0x37, 0x77, 0xC2, 0xAB, 0x1B, 0x2D, 0xC5, 0x5A, + 0x9E, 0x67, 0xB0, 0x5C, 0x42, 0x37, 0xA3, 0x4F, 0x40, 0x27, 0x82, 0xD3, 0xBE, 0x9B, 0xBC, 0x99, + 0x9D, 0x8E, 0x11, 0xD5, 0x15, 0x73, 0x0F, 0xBF, 0x7E, 0x1C, 0x2D, 0xD6, 0x7B, 0xC4, 0x00, 0xC7, + 0x6B, 0x1B, 0x8C, 0xB7, 0x45, 0x90, 0xA1, 0x21, 0xBE, 0xB1, 0x6E, 0xB2, 0xB4, 0x6E, 0x36, 0x6A, + 0x2F, 0xAB, 0x48, 0x57, 0x79, 0x6E, 0x94, 0xBC, 0xD2, 0x76, 0xA3, 0xC6, 0xC8, 0xC2, 0x49, 0x65, + 0xEE, 0xF8, 0x0F, 0x53, 0x7D, 0xDE, 0x8D, 0x46, 0x1D, 0x0A, 0x73, 0xD5, 0xC6, 0x4D, 0xD0, 0x4C, + 0xDB, 0xBB, 0x39, 0x29, 0x50, 0x46, 0xBA, 0xA9, 0xE8, 0x26, 0x95, 0xAC, 0x04, 0xE3, 0x5E, 0xBE, + 0xF0, 0xD5, 0xFA, 0xA1, 0x9A, 0x51, 0x2D, 0x6A, 0xE2, 0x8C, 0xEF, 0x63, 0x22, 0xEE, 0x86, 0x9A, + 0xB8, 0xC2, 0x89, 0xC0, 0xF6, 0x2E, 0x24, 0x43, 0xAA, 0x03, 0x1E, 0xA5, 0xA4, 0xD0, 0xF2, 0x9C, + 0xBA, 0x61, 0xC0, 0x83, 0x4D, 0x6A, 0xE9, 0x9B, 0x50, 0x15, 0xE5, 0x8F, 0xD6, 0x5B, 0x64, 0xBA, + 0xF9, 0xA2, 0x26, 0x28, 0xE1, 0x3A, 0x3A, 0xA7, 0x86, 0x95, 0xA9, 0x4B, 0xE9, 0x62, 0x55, 0xEF, + 0xD3, 0xEF, 0x2F, 0xC7, 0xDA, 0xF7, 0x52, 0xF7, 0x69, 0x6F, 0x04, 0x3F, 0x59, 0x0A, 0xFA, 0x77, + 0x15, 0xA9, 0xE4, 0x80, 0x01, 0x86, 0xB0, 0x87, 0xAD, 0xE6, 0x09, 0x9B, 0x93, 0xE5, 0x3E, 0x3B, + 0x5A, 0xFD, 0x90, 0xE9, 0x97, 0xD7, 0x34, 0x9E, 0xD9, 0xB7, 0xF0, 0x2C, 0x51, 0x8B, 0x2B, 0x02, + 0x3A, 0xAC, 0xD5, 0x96, 0x7D, 0xA6, 0x7D, 0x01, 0xD6, 0x3E, 0xCF, 0xD1, 0x28, 0x2D, 0x7D, 0x7C, + 0xCF, 0x25, 0x9F, 0x1F, 0x9B, 0xB8, 0xF2, 0xAD, 0x72, 0xB4, 0xD6, 0x5A, 0x4C, 0xF5, 0x88, 0x5A, + 0x71, 0xAC, 0x29, 0xE0, 0xE6, 0xA5, 0x19, 0xE0, 0xFD, 0xAC, 0xB0, 0x47, 0x9B, 0xFA, 0x93, 0xED, + 0x8D, 0xC4, 0xD3, 0xE8, 0xCC, 0x57, 0x3B, 0x28, 0x29, 0x66, 0xD5, 0xF8, 0x28, 0x2E, 0x13, 0x79, + 0x91, 0x01, 0x5F, 0x78, 0x55, 0x60, 0x75, 0xED, 0x44, 0x0E, 0x96, 0xF7, 0x8C, 0x5E, 0xD3, 0xE3, + 0xD4, 0x6D, 0x05, 0x15, 0xBA, 0x6D, 0xF4, 0x88, 0x25, 0x61, 0xA1, 0x03, 0xBD, 0xF0, 0x64, 0x05, + 0x15, 0x9E, 0xEB, 0xC3, 0xA2, 0x57, 0x90, 0x3C, 0xEC, 0x1A, 0x27, 0x97, 0x2A, 0x07, 0x3A, 0xA9, + 0x9B, 0x6D, 0x3F, 0x1B, 0xF5, 0x21, 0x63, 0x1E, 0xFB, 0x66, 0x9C, 0xF5, 0x19, 0xF3, 0xDC, 0x26, + 0x28, 0xD9, 0x33, 0x75, 0xF5, 0xFD, 0x55, 0xB1, 0x82, 0x34, 0x56, 0x03, 0xBB, 0x3C, 0xBA, 0x8A, + 0x11, 0x77, 0x51, 0x28, 0xF8, 0xD9, 0x0A, 0xC2, 0x67, 0x51, 0xCC, 0xAB, 0x5F, 0x92, 0xAD, 0xCC, + 0x51, 0x17, 0xE8, 0x4D, 0x8E, 0xDC, 0x30, 0x38, 0x62, 0x58, 0x9D, 0x37, 0x91, 0xF9, 0x20, 0x93, + 0xC2, 0x90, 0x7A, 0xEA, 0xCE, 0x7B, 0x3E, 0xFB, 0x64, 0xCE, 0x21, 0x51, 0x32, 0xBE, 0x4F, 0x77, + 0x7E, 0xE3, 0xB6, 0xA8, 0x46, 0x3D, 0x29, 0xC3, 0x69, 0x53, 0xDE, 0x48, 0x80, 0xE6, 0x13, 0x64, + 0x10, 0x08, 0xAE, 0xA2, 0x24, 0xB2, 0x6D, 0xDD, 0xFD, 0x2D, 0x85, 0x69, 0x66, 0x21, 0x07, 0x09, + 0x0A, 0x46, 0x9A, 0xB3, 0xDD, 0xC0, 0x45, 0x64, 0xCF, 0xDE, 0x6C, 0x58, 0xAE, 0xC8, 0x20, 0x1C, + 0xDD, 0xF7, 0xBE, 0x5B, 0x40, 0x8D, 0x58, 0x1B, 0x7F, 0x01, 0xD2, 0xCC, 0xBB, 0xE3, 0xB4, 0x6B, + 0x7E, 0x6A, 0xA2, 0xDD, 0x45, 0xFF, 0x59, 0x3A, 0x44, 0x0A, 0x35, 0x3E, 0xD5, 0xCD, 0xB4, 0xBC, + 0xA8, 0xCE, 0xEA, 0x72, 0xBB, 0x84, 0x64, 0xFA, 0xAE, 0x12, 0x66, 0x8D, 0x47, 0x6F, 0x3C, 0xBF, + 0x63, 0xE4, 0x9B, 0xD2, 0x9E, 0x5D, 0x2F, 0x54, 0x1B, 0x77, 0xC2, 0xAE, 0x70, 0x63, 0x4E, 0xF6, + 0x8D, 0x0D, 0x0E, 0x74, 0x57, 0x13, 0x5B, 0xE7, 0x71, 0x16, 0x72, 0xF8, 0x5D, 0x7D, 0x53, 0xAF, + 0x08, 0xCB, 0x40, 0x40, 0xCC, 0xE2, 0xB4, 0x4E, 0x6A, 0x46, 0xD2, 0x34, 0x84, 0xAF, 0x15, 0x01, + 0x28, 0x04, 0xB0, 0xE1, 0x1D, 0x3A, 0x98, 0x95, 0xB4, 0x9F, 0xB8, 0x06, 0x48, 0xA0, 0x6E, 0xCE, + 0x82, 0x3B, 0x3F, 0x6F, 0x82, 0xAB, 0x20, 0x35, 0x4B, 0x1D, 0x1A, 0x01, 0xF8, 0x27, 0x72, 0x27, + 0xB1, 0x60, 0x15, 0x61, 0xDC, 0x3F, 0x93, 0xE7, 0x2B, 0x79, 0x3A, 0xBB, 0xBD, 0x25, 0x45, 0x34, + 0xE1, 0x39, 0x88, 0xA0, 0x4B, 0x79, 0xCE, 0x51, 0xB7, 0xC9, 0x32, 0x2F, 0xC9, 0xBA, 0x1F, 0xA0, + 0x7E, 0xC8, 0x1C, 0xE0, 0xF6, 0xD1, 0xC7, 0xBC, 0xC3, 0x11, 0x01, 0xCF, 0xC7, 0xAA, 0xE8, 0xA1, + 0x49, 0x87, 0x90, 0x1A, 0x9A, 0xBD, 0x4F, 0xD4, 0xCB, 0xDE, 0xDA, 0xD0, 0x38, 0xDA, 0x0A, 0xD5, + 0x2A, 0xC3, 0x39, 0x03, 0x67, 0x36, 0x91, 0xC6, 0x7C, 0x31, 0xF9, 0x8D, 0x4F, 0x2B, 0xB1, 0xE0, + 0xB7, 0x59, 0x9E, 0xF7, 0x3A, 0xBB, 0xF5, 0x43, 0xFF, 0x19, 0xD5, 0xF2, 0x9C, 0x45, 0xD9, 0x27, + 0x2C, 0x22, 0x97, 0xBF, 0x2A, 0xFC, 0xE6, 0x15, 0x71, 0xFC, 0x91, 0x0F, 0x25, 0x15, 0x94, 0x9B, + 0x61, 0x93, 0xE5, 0xFA, 0xEB, 0x9C, 0xB6, 0xCE, 0x59, 0x64, 0xA8, 0xC2, 0xD1, 0xA8, 0xBA, 0x12, + 0x5E, 0x07, 0xC1, 0xB6, 0x0C, 0x6A, 0x05, 0xE3, 0x65, 0x50, 0xD2, 0x10, 0x42, 0xA4, 0x03, 0xCB, + 0x0E, 0x6E, 0xEC, 0xE0, 0x3B, 0xDB, 0x98, 0x16, 0xBE, 0xA0, 0x98, 0x4C, 0x64, 0xE9, 0x78, 0x32, + 0x32, 0x95, 0x1F, 0x9F, 0xDF, 0x92, 0xD3, 0xE0, 0x2B, 0x34, 0xA0, 0xD3, 0x1E, 0xF2, 0x71, 0x89, + 0x41, 0x74, 0x0A, 0x1B, 0x8C, 0x34, 0xA3, 0x4B, 0x20, 0x71, 0xBE, 0xC5, 0xD8, 0x32, 0x76, 0xC3, + 0x8D, 0x9F, 0x35, 0xDF, 0x2E, 0x2F, 0x99, 0x9B, 0x47, 0x6F, 0x0B, 0xE6, 0x1D, 0xF1, 0xE3, 0x0F, + 0x54, 0xDA, 0x4C, 0xE5, 0x91, 0xD8, 0xDA, 0x1E, 0xCF, 0x79, 0x62, 0xCE, 0x6F, 0x7E, 0x3E, 0xCD, + 0x66, 0xB1, 0x18, 0x16, 0x05, 0x1D, 0x2C, 0xFD, 0xC5, 0xD2, 0x8F, 0x84, 0x99, 0x22, 0xFB, 0xF6, + 0x57, 0xF3, 0x23, 0xF5, 0x23, 0x76, 0x32, 0xA6, 0x31, 0x35, 0xA8, 0x93, 0x02, 0xCD, 0xCC, 0x56, + 0x62, 0x81, 0xF0, 0xAC, 0xB5, 0xEB, 0x75, 0x5A, 0x97, 0x36, 0x16, 0x6E, 0xCC, 0x73, 0xD2, 0x88, + 0x92, 0x62, 0x96, 0xDE, 0xD0, 0x49, 0xB9, 0x81, 0x1B, 0x90, 0x50, 0x4C, 0x14, 0x56, 0xC6, 0x71, + 0xBD, 0xC7, 0xC6, 0xE6, 0x0A, 0x14, 0x7A, 0x32, 0x06, 0xD0, 0xE1, 0x45, 0x9A, 0x7B, 0xF2, 0xC3, + 0xFD, 0x53, 0xAA, 0xC9, 0x00, 0x0F, 0xA8, 0x62, 0xE2, 0xBF, 0x25, 0xBB, 0xF6, 0xD2, 0xBD, 0x35, + 0x05, 0x69, 0x12, 0x71, 0x22, 0x02, 0x04, 0xB2, 0x7C, 0xCF, 0xCB, 0xB6, 0x2B, 0x9C, 0x76, 0xCD, + 0xC0, 0x3E, 0x11, 0x53, 0xD3, 0xE3, 0x40, 0x16, 0x60, 0xBD, 0xAB, 0x38, 0xF0, 0xAD, 0x47, 0x25, + 0x9C, 0x20, 0x38, 0xBA, 0x76, 0xCE, 0x46, 0xF7, 0xC5, 0xA1, 0xAF, 0x77, 0x60, 0x60, 0x75, 0x20, + 0x4E, 0xFE, 0xCB, 0x85, 0xD8, 0x8D, 0xE8, 0x8A, 0xB0, 0xF9, 0xAA, 0x7A, 0x7E, 0xAA, 0xF9, 0x4C, + 0x5C, 0xC2, 0x48, 0x19, 0x8C, 0x8A, 0xFB, 0x02, 0xE4, 0x6A, 0xC3, 0x01, 0xF9, 0xE1, 0xEB, 0xD6, + 0x69, 0xF8, 0xD4, 0x90, 0xA0, 0xDE, 0x5C, 0xA6, 0x2D, 0x25, 0x09, 0x3F, 0x9F, 0xE6, 0x08, 0xC2, + 0x32, 0x61, 0x4E, 0xB7, 0x5B, 0xE2, 0x77, 0xCE, 0xE3, 0xDF, 0x8F, 0x57, 0xE6, 0x72, 0xC3, 0x3A + }; + + #endregion - private uint[] P = new uint[16+2]; - private uint[,] S = new uint[4,256]; - public Blowfish(byte[] key) { - InitBlowfish(key); - } - - private int InitBlowfish(byte[] key) - { - return initializeBlowfish(key, (short)key.Length, P, S); + initializeBlowfish(key); } public void Encipher(byte[] data, int offset, int length) @@ -33,11 +295,11 @@ namespace FFXIVClassic_Lobby_Server.common if ((length - offset) % 8 != 0) throw new ArgumentException("Needs to be a multiple of 8"); - for (int i = offset; i < offset+length; i+=8) + for (int i = offset; i < offset + length; i += 8) { - int xl = (data[i + 0]) | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24); - int xr = (data[i + 4]) | (data[i + 5] << 8) | (data[i + 6] << 16) | (data[i + 7] << 24); - blowfish_encipher(ref xl, ref xr, P); + uint xl = (uint)((data[i + 0]) | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24)); + uint xr = (uint)((data[i + 4]) | (data[i + 5] << 8) | (data[i + 6] << 16) | (data[i + 7] << 24)); + blowfish_encipher(ref xl, ref xr); data[i + 0] = (byte)(xl >> 0); data[i + 1] = (byte)(xl >> 8); data[i + 2] = (byte)(xl >> 16); @@ -56,9 +318,9 @@ namespace FFXIVClassic_Lobby_Server.common for (int i = offset; i < offset + length; i += 8) { - int xl = (data[i + 0]) | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24); - int xr = (data[i + 4]) | (data[i + 5] << 8) | (data[i + 6] << 16) | (data[i + 7] << 24); - blowfish_decipher(ref xl, ref xr, P); + uint xl = (uint)((data[i + 0]) | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24)); + uint xr = (uint)((data[i + 4]) | (data[i + 5] << 8) | (data[i + 6] << 16) | (data[i + 7] << 24)); + blowfish_decipher(ref xl, ref xr); data[i + 0] = (byte)(xl >> 0); data[i + 1] = (byte)(xl >> 8); data[i + 2] = (byte)(xl >> 16); @@ -69,6 +331,130 @@ namespace FFXIVClassic_Lobby_Server.common data[i + 7] = (byte)(xr >> 24); } } + + private UInt32 F(UInt32 x) + { + UInt16 a; + UInt16 b; + UInt16 c; + UInt16 d; + UInt32 y; + + d = (UInt16)(x & 0x00FF); + x >>= 8; + c = (UInt16)(x & 0x00FF); + x >>= 8; + b = (UInt16)(x & 0x00FF); + x >>= 8; + a = (UInt16)(x & 0x00FF); + //y = ((S[0][a] + S[1][b]) ^ S[2][c]) + S[3][d]; + y = S[0,a] + S[1,b]; + y = y ^ S[2,c]; + y = y + S[3,d]; + + return y; + } + + private void blowfish_encipher(ref UInt32 xl, ref UInt32 xr) + { + UInt32 temp; + Int32 i; + + for (i = 0; i < N; ++i) { + xl = xl ^ P[i]; + xr = F(xl) ^ xr; + + temp = xl; + xl = xr; + xr = temp; + } + + temp = xl; + xl = xr; + xr = temp; + + xr = xr ^ P[N]; + xl = xl ^ P[N + 1]; + + } + + private void blowfish_decipher(ref UInt32 xl, ref UInt32 xr) + { + UInt32 temp; + Int32 i; + + for (i = N + 1; i > 1; --i) { + xl = xl ^ P[i]; + xr = F(xl) ^ xr; + + /* Exchange xl and xr */ + temp = xl; + xl = xr; + xr = temp; + } + + /* Exchange xl and xr */ + temp = xl; + xl = xr; + xr = temp; + + xr = xr ^ P[1]; + xl = xl ^ P[0]; + + } + + private int initializeBlowfish(byte [] key) + { + Int16 i; + Int16 j; + Int16 k; + + int data; + uint datal; + uint datar; + + Buffer.BlockCopy(P_values, 0, P, 0, P_values.Length); + Buffer.BlockCopy(S_values, 0, S, 0, S_values.Length); + + j = 0; + for (i = 0; i < N + 2; ++i) + { + data = 0x00000000; + for (k = 0; k < 4; ++k) + { + data = (data << 8) | (SByte)key[j]; + j = (short)(j + 1); + if (j >= key.Length) + { + j = 0; + } + } + P[i] = P[i] ^ (uint)data; + } + + datal = 0x00000000; + datar = 0x00000000; + + for (i = 0; i < N + 2; i += 2) + { + blowfish_encipher(ref datal, ref datar); + + P[i] = datal; + P[i + 1] = datar; + } + + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 256; j += 2) + { + blowfish_encipher(ref datal, ref datar); + S[i,j] = datal; + S[i,j + 1] = datar; + } + } + + return 0; + } + } - -} \ No newline at end of file +} diff --git a/FFXIVClassic Map Server/dataobjects/Actor.cs b/FFXIVClassic Map Server/dataobjects/Actor.cs index b85910aa..f349aabc 100644 --- a/FFXIVClassic Map Server/dataobjects/Actor.cs +++ b/FFXIVClassic Map Server/dataobjects/Actor.cs @@ -1,4 +1,10 @@ -using System; +using FFXIVClassic_Lobby_Server; +using FFXIVClassic_Lobby_Server.common; +using FFXIVClassic_Lobby_Server.dataobjects; +using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.packets.send.actor; +using FFXIVClassic_Map_Server.packets.send.Actor; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,38 +12,40 @@ using System.Text; namespace FFXIVClassic_Map_Server.dataobjects { class Actor - { - enum Appearance { - MODEL, - SIZE, - COLORINFO, - FACEINFO, - HIGHLIGHT_HAIR, - VOICE, - WEAPON1, - WEAPON2, - WEAPON3, - HEADGEAR, - BODYGEAR, - LEGSGEAR, - HANDSGEAR, - FEETGEAR, - WAISTGEAR, - UNKNOWN1, - R_EAR, - L_EAR, - UNKNOWN2, - UNKNOWN3, - R_FINGER, - L_FINGER - } + { + public const int SIZE = 0; + public const int COLORINFO = 1; + public const int FACEINFO = 2; + public const int HIGHLIGHT_HAIR = 3; + public const int VOICE = 4; + public const int WEAPON1 = 5; + public const int WEAPON2 = 6; + public const int WEAPON3 = 7; + public const int UNKNOWN1 = 8; + public const int UNKNOWN2 = 9; + public const int UNKNOWN3 = 10; + public const int UNKNOWN4 = 11; + public const int HEADGEAR = 12; + public const int BODYGEAR = 13; + public const int LEGSGEAR = 14; + public const int HANDSGEAR = 15; + public const int FEETGEAR = 16; + public const int WAISTGEAR = 17; + public const int UNKNOWN5 = 18; + public const int R_EAR = 19; + public const int L_EAR = 20; + public const int UNKNOWN6 = 21; + public const int UNKNOWN7 = 22; + public const int R_FINGER = 23; + public const int L_FINGER = 24; public uint actorID; public uint displayNameID; public string customDisplayName; - public uint[] appearanceIDs; + public uint modelID; + public uint[] appearanceIDs = new uint[0x1D]; public float positionX, positionY, positionZ; public float oldPositionX, oldPositionY, oldPositionZ; @@ -49,5 +57,40 @@ namespace FFXIVClassic_Map_Server.dataobjects actorID = id; } + public void setPlayerAppearance() + { + Appearance appearance = Database.getAppearance(actorID); + + modelID = Appearance.getTribeModel(appearance.tribe); + appearanceIDs[SIZE] = appearance.size; + appearanceIDs[COLORINFO] = (uint)(appearance.skinColor | (appearance.hairColor << 10) | (appearance.eyeColor << 20)); + appearanceIDs[FACEINFO] = PrimitiveConversion.ToUInt32(appearance.getFaceInfo()); + appearanceIDs[HIGHLIGHT_HAIR] = (uint)(appearance.hairHighlightColor | appearance.hairStyle << 10); + appearanceIDs[VOICE] = appearance.voice; + appearanceIDs[WEAPON1] = appearance.mainHand; + appearanceIDs[WEAPON2] = appearance.offHand; + appearanceIDs[HEADGEAR] = appearance.head; + appearanceIDs[BODYGEAR] = appearance.body; + appearanceIDs[LEGSGEAR] = appearance.legs; + appearanceIDs[HANDSGEAR] = appearance.hands; + appearanceIDs[FEETGEAR] = appearance.feet; + appearanceIDs[WAISTGEAR] = appearance.waist; + appearanceIDs[R_EAR] = appearance.rightEar; + appearanceIDs[L_EAR] = appearance.leftEar; + appearanceIDs[R_FINGER] = appearance.rightFinger; + appearanceIDs[L_FINGER] = appearance.leftFinger; + } + + public SubPacket createNamePacket(uint playerActorID) + { + return SetActorNamePacket.buildPacket(playerActorID, actorID, displayNameID, displayNameID == 0xFFFFFFFF ? customDisplayName : ""); + } + + public SubPacket createAppearancePacket(uint playerActorID) + { + SetActorAppearancePacket setappearance = new SetActorAppearancePacket(modelID, appearanceIDs); + return setappearance.buildPacket(playerActorID, actorID); + } + } } diff --git a/FFXIVClassic Map Server/dataobjects/Appearance.cs b/FFXIVClassic Map Server/dataobjects/Appearance.cs new file mode 100644 index 00000000..6abb0c37 --- /dev/null +++ b/FFXIVClassic Map Server/dataobjects/Appearance.cs @@ -0,0 +1,143 @@ +using FFXIVClassic_Lobby_Server.common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Lobby_Server.dataobjects +{ + class Appearance + { + //////////// + //Chara Info + public byte tribe = 0; + public byte size = 0; + public byte voice = 0; + public ushort skinColor = 0; + + public ushort hairStyle = 0; + public ushort hairColor = 0; + public ushort hairHighlightColor = 0; + public ushort eyeColor = 0; + public byte characteristicsColor = 0; + + public byte faceType = 0; + public byte faceEyebrows = 0; + public byte faceEyeShape = 0; + public byte faceIrisSize = 0; + public byte faceNose = 0; + public byte faceMouth = 0; + public byte faceFeatures = 0; + public byte characteristics = 0; + public byte ears = 0; + + public uint mainHand = 0; + public uint offHand = 0; + + public uint head = 0; + public uint body = 0; + public uint legs = 0; + public uint hands = 0; + public uint feet = 0; + public uint waist = 0; + public uint rightEar = 0; + public uint leftEar = 0; + public uint rightFinger = 0; + public uint leftFinger = 0; + //Chara Info + //////////// + + public struct FaceInfo + { + [BitfieldLength(5)] + public uint characteristics; + [BitfieldLength(3)] + public uint characteristicsColor; + [BitfieldLength(6)] + public uint type; + [BitfieldLength(2)] + public uint ears; + [BitfieldLength(2)] + public uint mouth; + [BitfieldLength(2)] + public uint features; + [BitfieldLength(3)] + public uint nose; + [BitfieldLength(3)] + public uint eyeShape; + [BitfieldLength(1)] + public uint irisSize; + [BitfieldLength(3)] + public uint eyebrows; + [BitfieldLength(2)] + public uint unknown; + } + + public FaceInfo getFaceInfo() + { + FaceInfo faceInfo = new FaceInfo(); + faceInfo.characteristics = characteristics; + faceInfo.characteristicsColor = characteristicsColor; + faceInfo.type = faceType; + faceInfo.ears = ears; + faceInfo.features = faceFeatures; + faceInfo.eyebrows = faceEyebrows; + faceInfo.eyeShape = faceEyeShape; + faceInfo.irisSize = faceIrisSize; + faceInfo.mouth = faceMouth; + faceInfo.nose = faceNose; + return faceInfo; + } + + public static UInt32 getTribeModel(byte tribe) + { + switch (tribe) + { + //Hyur Midlander Male + case 1: + default: + return 1; + + //Hyur Midlander Female + case 2: + return 2; + + //Elezen Male + case 4: + case 6: + return 3; + + //Elezen Female + case 5: + case 7: + return 4; + + //Lalafell Male + case 8: + case 10: + return 5; + + //Lalafell Female + case 9: + case 11: + return 6; + + //Miqo'te Female + case 12: + case 13: + return 8; + + //Roegadyn Male + case 14: + case 15: + return 7; + + //Hyur Highlander Male + case 3: + return 9; + } + } + + } +} diff --git a/FFXIVClassic Map Server/dataobjects/Player.cs b/FFXIVClassic Map Server/dataobjects/Player.cs index 61ece6da..9632421d 100644 --- a/FFXIVClassic Map Server/dataobjects/Player.cs +++ b/FFXIVClassic Map Server/dataobjects/Player.cs @@ -27,7 +27,8 @@ namespace FFXIVClassic_Map_Server.dataobjects public Player(uint actorId) { this.actorID = actorId; - createPlayerActor(actorId, null); + Character chara = Database.getCharacter(actorId); + createPlayerActor(actorId, chara); } public void addConnection(ClientConnection conn) @@ -72,9 +73,19 @@ namespace FFXIVClassic_Map_Server.dataobjects return conn1; } + public Actor getActor() + { + return playerActor; + } + public void createPlayerActor(uint actorId, Character chara) { playerActor = new Actor(actorId); + + playerActor.displayNameID = 0xFFFFFFFF; + playerActor.customDisplayName = chara.name; + playerActor.setPlayerAppearance(); + actorInstanceList.Add(playerActor); } diff --git a/FFXIVClassic Map Server/packets/send/Actor/SetActorAppearancePacket.cs b/FFXIVClassic Map Server/packets/send/Actor/SetActorAppearancePacket.cs index 2dcf56c3..09f427ac 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/SetActorAppearancePacket.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/SetActorAppearancePacket.cs @@ -38,14 +38,15 @@ namespace FFXIVClassic_Map_Server.packets.send.actor public uint modelID; public uint[] appearanceIDs; - public SetActorAppearancePacket(uint monsterModelID) + public SetActorAppearancePacket(uint modelID) { - modelID = monsterModelID; - appearanceIDs = new uint[22]; + this.modelID = modelID; + appearanceIDs = new uint[0x1D]; } - public SetActorAppearancePacket(uint[] appearanceTable) + public SetActorAppearancePacket(uint modelID, uint[] appearanceTable) { + this.modelID = modelID; appearanceIDs = appearanceTable; } @@ -58,7 +59,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor using (BinaryWriter binWriter = new BinaryWriter(mem)) { binWriter.Write((uint)modelID); - for (int i = 0; i < 0x1A; i++) + for (int i = 0; i <= 0x1A; i++) { binWriter.Write((uint)i); binWriter.Write((uint)appearanceIDs[i]); @@ -68,12 +69,12 @@ namespace FFXIVClassic_Map_Server.packets.send.actor binWriter.Write((uint) 0x1C); binWriter.Write((uint) 0x00); } - data = mem.GetBuffer(); + } SubPacket packet = new SubPacket(OPCODE, playerActorID, actorID, data); return packet; - } + } } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/SetActorNamePacket.cs b/FFXIVClassic Map Server/packets/send/Actor/SetActorNamePacket.cs index 7caf46d2..6274e641 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/SetActorNamePacket.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/SetActorNamePacket.cs @@ -32,7 +32,6 @@ namespace FFXIVClassic_Map_Server.packets.send.Actor } } - data = mem.GetBuffer(); } SubPacket packet = new SubPacket(OPCODE, playerActorID, targetActorID, data); diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryBeginChangePacket.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryBeginChangePacket.cs new file mode 100644 index 00000000..862f0eea --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryBeginChangePacket.cs @@ -0,0 +1,20 @@ +using FFXIVClassic_Lobby_Server.packets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory +{ + class InventoryBeginChangePacket + { + public const ushort OPCODE = 0x016D; + public const uint PACKET_SIZE = 0x28; + + public static SubPacket buildPacket(uint playerActorID) + { + return new SubPacket(OPCODE, playerActorID, playerActorID, new byte[8]); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryEndChangePacket.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryEndChangePacket.cs new file mode 100644 index 00000000..6d031497 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventoryEndChangePacket.cs @@ -0,0 +1,20 @@ +using FFXIVClassic_Lobby_Server.packets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory +{ + class InventoryEndChangePacket + { + public const ushort OPCODE = 0x016E; + public const uint PACKET_SIZE = 0x28; + + public static SubPacket buildPacket(uint playerActorID) + { + return new SubPacket(OPCODE, playerActorID, playerActorID, new byte[8]); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventorySetBeginPacket.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventorySetBeginPacket.cs index 2887cab9..0327af2e 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/inventory/InventorySetBeginPacket.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/InventorySetBeginPacket.cs @@ -16,7 +16,7 @@ namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory public const ushort CODE_ITEMS = 0x0000; public const ushort CODE_CURRANCYITEMS = 0x0063; public const ushort CODE_KEYITEMS = 0x0064; - public const ushort CODE_EQUIPMENT = 0x00FE; + public const ushort CODE_EQUIPMENT = 0x00FE; public static SubPacket buildPacket(uint playerActorID, ushort size, ushort code) { diff --git a/FFXIVClassic Map Server/packets/send/Actor/inventory/SetInitialEquipmentPacket.cs b/FFXIVClassic Map Server/packets/send/Actor/inventory/SetInitialEquipmentPacket.cs new file mode 100644 index 00000000..f21f3ae1 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/Actor/inventory/SetInitialEquipmentPacket.cs @@ -0,0 +1,98 @@ +using FFXIVClassic_Lobby_Server.packets; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory +{ + class SetInitialEquipmentPacket + { + public const ushort OPCODE = 0x014E; + public const uint PACKET_SIZE = 0x58; + + public const uint UNEQUIPPED = 0xFFFFFFFF; + + public const int SLOT_MAINHAND = 0x00; + public const int SLOT_OFFHAND = 0x01; + public const int SLOT_THROWINGWEAPON = 0x04; + public const int SLOT_PACK = 0x05; + public const int SLOT_POUCH = 0x06; + public const int SLOT_HEAD = 0x08; + public const int SLOT_UNDERSHIRT = 0x09; + public const int SLOT_BODY = 0x0A; + public const int SLOT_UNDERGARMENT = 0x0B; + public const int SLOT_LEGS = 0x0C; + public const int SLOT_HANDS = 0x0D; + public const int SLOT_BOOTS = 0x0E; + public const int SLOT_WAIST = 0x0F; + public const int SLOT_NECK = 0x10; + public const int SLOT_EARS = 0x11; + public const int SLOT_WRISTS = 0x13; + public const int SLOT_RIGHTFINGER = 0x15; + public const int SLOT_LEFTFINGER = 0x16; + + private uint[] equipment = new uint[0x17]; + + public SetInitialEquipmentPacket() + { + for (int i = 0; i < equipment.Length; i++) + equipment[i] = UNEQUIPPED; //We will use this as "Unequipped" + } + + public void setItem(int slot, uint itemSlot) + { + if (slot >= equipment.Length) + return; + + equipment[slot] = itemSlot; + } + + public List buildPackets(uint playerActorID) + { + List packets = new List(); + int packetCount = 0; + int runningCount = 0; + byte[] data = new byte[PACKET_SIZE - 0x20]; + MemoryStream mem = new MemoryStream(data); + BinaryWriter binWriter = new BinaryWriter(mem); + + for (int i = 0; i < equipment.Length; i++) + { + if (equipment[i] == UNEQUIPPED) + continue; + + binWriter.Write((UInt16)i); + binWriter.Write((UInt32)equipment[i]); + + packetCount++; + runningCount++; + + //Create another packet + if (runningCount >= 8) + { + packetCount = 0; + binWriter.Write((UInt32)8); + binWriter.Dispose(); + mem.Dispose(); + packets.Add(new SubPacket(OPCODE, playerActorID, playerActorID, data)); + data = new byte[PACKET_SIZE - 0x20]; + mem = new MemoryStream(data); + binWriter = new BinaryWriter(mem); + } + } + + //Create any leftover subpacket + binWriter.BaseStream.Seek(0x30, SeekOrigin.Begin); + binWriter.Write((UInt32)packetCount); + binWriter.Dispose(); + mem.Dispose(); + packets.Add(new SubPacket(OPCODE, playerActorID, playerActorID, data)); + + return packets; + } + + } +}