From d90cf6d953e2fcd7a784972581248072b085e902 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Thu, 10 Sep 2015 00:52:31 -0400 Subject: [PATCH] Import and Retainer lists now sent. --- FFXIVClassic_Lobby_Server/Database.cs | 40 +++++++ .../FFXIVClassic_Lobby_Server.csproj | 1 + FFXIVClassic_Lobby_Server/PacketProcessor.cs | 26 +++-- .../dataobjects/Retainer.cs | 9 +- .../packets/CharacterListPacket.cs | 6 +- .../packets/ImportListPacket.cs | 101 ++++++++++++++++++ .../packets/RetainerListPacket.cs | 30 +++--- .../packets/WorldListPacket.cs | 8 +- 8 files changed, 192 insertions(+), 29 deletions(-) create mode 100644 FFXIVClassic_Lobby_Server/packets/ImportListPacket.cs diff --git a/FFXIVClassic_Lobby_Server/Database.cs b/FFXIVClassic_Lobby_Server/Database.cs index bce3029a..3ffebe1b 100644 --- a/FFXIVClassic_Lobby_Server/Database.cs +++ b/FFXIVClassic_Lobby_Server/Database.cs @@ -244,5 +244,45 @@ namespace FFXIVClassic_Lobby_Server } } + public static List getReservedNames(uint userId) + { + 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))) + { + List nameList = null; + try + { + conn.Open(); + nameList = conn.Query("SELECT name FROM reserved_names WHERE userId=@UserId", new { UserId = userId }).ToList(); + } + catch (MySqlException e) + { nameList = new List(); } + finally + { + conn.Dispose(); + } + return nameList; + } + } + + public static List getRetainers(uint userId) + { + 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))) + { + List retainerList = null; + try + { + conn.Open(); + retainerList = conn.Query("SELECT * FROM retainers WHERE id=@UserId ORDER BY characterId, slot", new { UserId = userId }).ToList(); + } + catch (MySqlException e) + { retainerList = new List(); } + finally + { + conn.Dispose(); + } + return retainerList; + } + } + } } diff --git a/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj b/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj index 4a963dbd..b94227c1 100644 --- a/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj +++ b/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj @@ -75,6 +75,7 @@ + diff --git a/FFXIVClassic_Lobby_Server/PacketProcessor.cs b/FFXIVClassic_Lobby_Server/PacketProcessor.cs index 46299c1a..eb8fab4f 100644 --- a/FFXIVClassic_Lobby_Server/PacketProcessor.cs +++ b/FFXIVClassic_Lobby_Server/PacketProcessor.cs @@ -155,12 +155,10 @@ namespace FFXIVClassic_Lobby_Server Console.WriteLine("{0} => Get characters", client.currentUserId == 0 ? client.getAddress() : "User " + client.currentUserId); sendWorldList(client, packet); - - BasePacket outgoingPacket = new BasePacket("./packets/getChars_wo_chars"); - BasePacket.encryptPacket(client.blowfish, outgoingPacket); - client.queuePacket(outgoingPacket); - + sendImportList(client, packet); + sendRetainerList(client, packet); sendCharacterList(client, packet); + } private void ProcessSelectCharacter(ClientConnection client, SubPacket packet) @@ -262,7 +260,7 @@ namespace FFXIVClassic_Lobby_Server pid = 1; cid = client.newCharaCid; - name = client.newCharaName; + name = client.newCharaName; Log.info(String.Format("User {0} => Character created \"{1}\"", client.currentUserId, charaReq.characterName)); break; @@ -292,7 +290,7 @@ namespace FFXIVClassic_Lobby_Server private void sendWorldList(ClientConnection client, SubPacket packet) { List serverList = Database.getServers(); - WorldListPacket worldlistPacket = new WorldListPacket(serverList); + WorldListPacket worldlistPacket = new WorldListPacket(2, serverList); List subPackets = worldlistPacket.buildPackets(); BasePacket basePacket = BasePacket.createPacket(subPackets, true, false); @@ -303,12 +301,24 @@ namespace FFXIVClassic_Lobby_Server private void sendImportList(ClientConnection client, SubPacket packet) { + List names = Database.getReservedNames(client.currentUserId); + ImportListPacket importListPacket = new ImportListPacket(2, names); + List subPackets = importListPacket.buildPackets(); + BasePacket basePacket = BasePacket.createPacket(subPackets, true, false); + BasePacket.encryptPacket(client.blowfish, basePacket); + client.queuePacket(basePacket); } private void sendRetainerList(ClientConnection client, SubPacket packet) { - + List retainers = Database.getRetainers(client.currentUserId); + + RetainerListPacket retainerListPacket = new RetainerListPacket(2, retainers); + List subPackets = retainerListPacket.buildPackets(); + BasePacket basePacket = BasePacket.createPacket(subPackets, true, false); + BasePacket.encryptPacket(client.blowfish, basePacket); + client.queuePacket(basePacket); } private void sendCharacterList(ClientConnection client, SubPacket packet) diff --git a/FFXIVClassic_Lobby_Server/dataobjects/Retainer.cs b/FFXIVClassic_Lobby_Server/dataobjects/Retainer.cs index e0769a91..9980d1b7 100644 --- a/FFXIVClassic_Lobby_Server/dataobjects/Retainer.cs +++ b/FFXIVClassic_Lobby_Server/dataobjects/Retainer.cs @@ -9,7 +9,10 @@ namespace FFXIVClassic_Lobby_Server { class Retainer { - public string name = ""; - + public uint id; + public uint characterId; + public string name; + public ushort slot; + public bool doRename; } -} +} \ No newline at end of file diff --git a/FFXIVClassic_Lobby_Server/packets/CharacterListPacket.cs b/FFXIVClassic_Lobby_Server/packets/CharacterListPacket.cs index 208164e0..bf91cd83 100644 --- a/FFXIVClassic_Lobby_Server/packets/CharacterListPacket.cs +++ b/FFXIVClassic_Lobby_Server/packets/CharacterListPacket.cs @@ -41,7 +41,7 @@ namespace FFXIVClassic_Lobby_Server.packets //Write List Info binWriter.Write((UInt64)sequence); - binWriter.Write(characterList.Count - totalCount <= MAXPERPACKET ? (byte)(1) : (byte)0); + binWriter.Write(characterList.Count - totalCount <= MAXPERPACKET ? (byte)(characterList.Count) : (byte)0); //binWriter.Write((byte)1); binWriter.Write(characterList.Count - totalCount <= MAXPERPACKET ? (UInt32)(characterList.Count - totalCount) : (UInt32)MAXPERPACKET); binWriter.Write((byte)0); @@ -56,7 +56,7 @@ namespace FFXIVClassic_Lobby_Server.packets binWriter.Write((uint)0); //??? binWriter.Write((uint)chara.id); //Character Id - binWriter.Write((byte)totalCount); //Slot + binWriter.Write((byte)(totalCount)); //Slot byte options = 0; if (chara.state == 2) @@ -98,7 +98,7 @@ namespace FFXIVClassic_Lobby_Server.packets binWriter = new BinaryWriter(memStream); //Write Empty List Info - binWriter.Write((UInt64)0); + binWriter.Write((UInt64)sequence); binWriter.Write((byte)1); binWriter.Write((UInt32)0); binWriter.Write((byte)0); diff --git a/FFXIVClassic_Lobby_Server/packets/ImportListPacket.cs b/FFXIVClassic_Lobby_Server/packets/ImportListPacket.cs new file mode 100644 index 00000000..4f55e934 --- /dev/null +++ b/FFXIVClassic_Lobby_Server/packets/ImportListPacket.cs @@ -0,0 +1,101 @@ +using FFXIVClassic_Lobby_Server.dataobjects; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Lobby_Server.packets +{ + class ImportListPacket + { + public const ushort OPCODE = 0x16; + public const ushort MAXPERPACKET = 12; + + private UInt64 sequence; + private List namesList; + + public ImportListPacket(UInt64 sequence, List names) + { + this.sequence = sequence; + this.namesList = names; + } + + public List buildPackets() + { + List subPackets = new List(); + + int namesCount = 0; + int totalCount = 0; + + MemoryStream memStream = null; + BinaryWriter binWriter = null; + + foreach (String name in namesList) + { + if (totalCount == 0 || namesCount % MAXPERPACKET == 0) + { + memStream = new MemoryStream(0x210); + binWriter = new BinaryWriter(memStream); + + //Write List Info + binWriter.Write((UInt64)sequence); + binWriter.Write(namesList.Count - totalCount <= MAXPERPACKET ? (byte)(namesList.Count + 1) : (byte)0); + binWriter.Write(namesList.Count - totalCount <= MAXPERPACKET ? (UInt32)(namesList.Count - totalCount) : (UInt32)MAXPERPACKET); + binWriter.Write((byte)0); + binWriter.Write((UInt16)0); + } + + //Write Entries + binWriter.Write((uint)0); + binWriter.Write((uint)totalCount); + + if (!name.Contains(" ")) + binWriter.Write(Encoding.ASCII.GetBytes((name+" Last").PadRight(0x20, '\0'))); + else + binWriter.Write(Encoding.ASCII.GetBytes(name.PadRight(0x20, '\0'))); + + namesCount++; + totalCount++; + + //Send this chunk of world list + if (namesCount >= MAXPERPACKET) + { + byte[] data = memStream.GetBuffer(); + binWriter.Dispose(); + memStream.Dispose(); + SubPacket subpacket = new SubPacket(OPCODE, 0xe0006868, 0xe0006868, data); + subPackets.Add(subpacket); + namesCount = 0; + } + + } + + //If there is anything left that was missed or the list is empty + if (namesCount > 0 || namesList.Count == 0) + { + if (namesList.Count == 0) + { + memStream = new MemoryStream(0x210); + binWriter = new BinaryWriter(memStream); + + //Write Empty List Info + binWriter.Write((UInt64)sequence); + binWriter.Write((byte)1); + binWriter.Write((UInt32)0); + binWriter.Write((byte)0); + binWriter.Write((UInt16)0); + } + + byte[] data = memStream.GetBuffer(); + binWriter.Dispose(); + memStream.Dispose(); + SubPacket subpacket = new SubPacket(OPCODE, 0xe0006868, 0xe0006868, data); + subPackets.Add(subpacket); + } + + return subPackets; + } + } +} diff --git a/FFXIVClassic_Lobby_Server/packets/RetainerListPacket.cs b/FFXIVClassic_Lobby_Server/packets/RetainerListPacket.cs index d308df19..dbaeba90 100644 --- a/FFXIVClassic_Lobby_Server/packets/RetainerListPacket.cs +++ b/FFXIVClassic_Lobby_Server/packets/RetainerListPacket.cs @@ -11,12 +11,14 @@ namespace FFXIVClassic_Lobby_Server.packets class RetainerListPacket { public const ushort OPCODE = 0x17; - public const ushort MAXPERPACKET = 3; + public const ushort MAXPERPACKET = 9; + private UInt64 sequence; private List retainerList; - public RetainerListPacket(List retainerList) + public RetainerListPacket(UInt64 sequence, List retainerList) { + this.sequence = sequence; this.retainerList = retainerList; } @@ -30,7 +32,7 @@ namespace FFXIVClassic_Lobby_Server.packets MemoryStream memStream = null; BinaryWriter binWriter = null; - foreach (Retainer chara in retainerList) + foreach (Retainer retainer in retainerList) { if (totalCount == 0 || retainerCount % MAXPERPACKET == 0) { @@ -38,19 +40,23 @@ namespace FFXIVClassic_Lobby_Server.packets binWriter = new BinaryWriter(memStream); //Write List Info - binWriter.Write((UInt64)0); + binWriter.Write((UInt64)sequence); binWriter.Write(retainerList.Count - totalCount <= MAXPERPACKET ? (byte)(retainerList.Count + 1) : (byte)0); binWriter.Write(retainerList.Count - totalCount <= MAXPERPACKET ? (UInt32)(retainerList.Count - totalCount) : (UInt32)MAXPERPACKET); - binWriter.Write((byte)6); - binWriter.Write((UInt16)5); + binWriter.Write((byte)0); + binWriter.Write((UInt16)0); + + binWriter.Write((UInt64)0); + binWriter.Write((UInt32)0); } //Write Entries - //binWriter.Write((ushort)world.id); - //binWriter.Write((ushort)world.listPosition); - //binWriter.Write((uint)world.population); - //binWriter.Write((UInt64)0); - //binWriter.Write(Encoding.ASCII.GetBytes(world.name.PadRight(64, '\0'))); + binWriter.Write((uint)retainer.id); + binWriter.Write((uint)retainer.characterId); + binWriter.Write((ushort)retainer.slot); + binWriter.Write((ushort)(retainer.doRename ? 0x04 : 0x00)); + binWriter.Write((uint)0); + binWriter.Write(Encoding.ASCII.GetBytes(retainer.name.PadRight(0x20, '\0'))); retainerCount++; totalCount++; @@ -77,7 +83,7 @@ namespace FFXIVClassic_Lobby_Server.packets binWriter = new BinaryWriter(memStream); //Write Empty List Info - binWriter.Write((UInt64)0); + binWriter.Write((UInt64)sequence); binWriter.Write((byte)1); binWriter.Write((UInt32)0); binWriter.Write((byte)0); diff --git a/FFXIVClassic_Lobby_Server/packets/WorldListPacket.cs b/FFXIVClassic_Lobby_Server/packets/WorldListPacket.cs index 34385d4b..2794cd65 100644 --- a/FFXIVClassic_Lobby_Server/packets/WorldListPacket.cs +++ b/FFXIVClassic_Lobby_Server/packets/WorldListPacket.cs @@ -13,10 +13,12 @@ namespace FFXIVClassic_Lobby_Server.packets public const ushort OPCODE = 0x15; public const ushort MAXPERPACKET = 6; + private UInt64 sequence; private List worldList; - public WorldListPacket(List serverList) + public WorldListPacket(UInt64 sequence, List serverList) { + this.sequence = sequence; this.worldList = serverList; } @@ -38,7 +40,7 @@ namespace FFXIVClassic_Lobby_Server.packets binWriter = new BinaryWriter(memStream); //Write List Info - binWriter.Write((UInt64)0); + binWriter.Write((UInt64)sequence); binWriter.Write(worldList.Count - totalCount <= MAXPERPACKET ? (byte)(worldList.Count + 1) : (byte)0); binWriter.Write(worldList.Count - totalCount <= MAXPERPACKET ? (UInt32)(worldList.Count - totalCount) : (UInt32)MAXPERPACKET); binWriter.Write((byte)0); @@ -77,7 +79,7 @@ namespace FFXIVClassic_Lobby_Server.packets binWriter = new BinaryWriter(memStream); //Write Empty List Info - binWriter.Write((UInt64)0); + binWriter.Write((UInt64)sequence); binWriter.Write((byte)1); binWriter.Write((UInt32)0); binWriter.Write((byte)0);