diff --git a/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj b/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj
index 573a078e..de26b36a 100644
--- a/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj
+++ b/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj
@@ -62,9 +62,11 @@
+
+
diff --git a/FFXIVClassic_Lobby_Server/PacketProcessor.cs b/FFXIVClassic_Lobby_Server/PacketProcessor.cs
index d8eb4361..f989a3bf 100644
--- a/FFXIVClassic_Lobby_Server/PacketProcessor.cs
+++ b/FFXIVClassic_Lobby_Server/PacketProcessor.cs
@@ -147,7 +147,7 @@ namespace FFXIVClassic_Lobby_Server
{
Console.WriteLine("{0} => Get characters", client.currentUserId == 0 ? client.getAddress() : "User " + client.currentUserId);
- buildWorldLists(client, packet);
+ sendWorldList(client, packet);
BasePacket outgoingPacket = new BasePacket("./packets/getCharsPacket.bin");
BasePacket.encryptPacket(client.blowfish, outgoingPacket);
@@ -203,14 +203,8 @@ namespace FFXIVClassic_Lobby_Server
if (alreadyTaken)
{
- PacketStructs.ErrorPacket errorPacket = new PacketStructs.ErrorPacket();
- errorPacket.sequence = charaReq.sequence;
- errorPacket.errorId = 13005;
- errorPacket.errorCode = 0;
- errorPacket.statusCode = 0;
- byte[] data = PacketStructs.StructureToByteArray(errorPacket);
-
- SubPacket subpacket = new SubPacket(0x02, packet.header.sourceId, packet.header.targetId, data);
+ ErrorPacket errorPacket = new ErrorPacket(charaReq.sequence, 13005, 0, 0, "");
+ SubPacket subpacket = errorPacket.buildPacket();
BasePacket basePacket = BasePacket.createPacket(subpacket, true, false);
basePacket.debugPrintPacket();
BasePacket.encryptPacket(client.blowfish, basePacket);
@@ -250,58 +244,32 @@ namespace FFXIVClassic_Lobby_Server
case 0x06://Rename Retainer
break;
}
+ }
+
+ private void sendWorldList(ClientConnection client, SubPacket packet)
+ {
+ List serverList = Database.getServers();
+ WorldListPacket worldlistPacket = new WorldListPacket(serverList);
+ List subPackets = worldlistPacket.buildPackets();
+
+ BasePacket basePacket = BasePacket.createPacket(subPackets, true, false);
+ BasePacket.encryptPacket(client.blowfish, basePacket);
+ client.queuePacket(basePacket);
}
- private void buildWorldLists(ClientConnection client, SubPacket packet)
+ private void sendUnknownList(ClientConnection client, SubPacket packet)
{
- List serverList = Database.getServers();
- int serverCount = 0;
- int totalCount = 0;
- PacketStructs.WorldListPacket worldListPacket = new PacketStructs.WorldListPacket();
- uint isEndList = serverList.Count <= 6 ? (byte)(serverList.Count+1) : (byte)0;
- uint numWorlds = serverList.Count <= 6 ? (byte)serverList.Count : (byte)6;
- numWorlds <<= 8;
+ }
- worldListPacket.isEndListANDNumWorlds = (uint)(isEndList | numWorlds);
- worldListPacket.sequence = 0;
- worldListPacket.unknown1 = 0;
- worldListPacket.worlds = new PacketStructs.WorldListEntry[6];
+ private void sendRetainerList(ClientConnection client, SubPacket packet)
+ {
+
+ }
- foreach (World world in serverList)
- {
- //Insert world entry
- PacketStructs.WorldListEntry entry = new PacketStructs.WorldListEntry();
- entry.id = world.id;
- entry.listPosition = world.listPosition;
- entry.population = world.population;
- entry.name = world.name;
- worldListPacket.worlds[serverCount] = entry;
+ private void sendCharacterList(ClientConnection client, SubPacket packet)
+ {
- serverCount++;
- totalCount++;
- if (serverCount % 6 == 0 || totalCount >= serverList.Count)
- {
- //Send this chunk of world list
- byte[] data = PacketStructs.StructureToByteArray(worldListPacket);
- SubPacket subpacket = new SubPacket(0x15, 0xe0006868, 0xe0006868, data);
- BasePacket basePacket = BasePacket.createPacket(subpacket, true, false);
- BasePacket.encryptPacket(client.blowfish, basePacket);
- client.queuePacket(basePacket);
-
- //Make new worldlist if still remaining
- if (totalCount <= serverList.Count)
- {
- worldListPacket = new PacketStructs.WorldListPacket();
- isEndList = serverList.Count <= 6 ? (byte)(serverList.Count + 1) : (byte)0;
- numWorlds = serverList.Count <= 6 ? (byte)serverList.Count : (byte)6;
- numWorlds <<= 8;
- worldListPacket.isEndListANDNumWorlds = (uint)(isEndList | numWorlds);
- worldListPacket.sequence = 0;
- worldListPacket.unknown1 = 0;
- }
- }
- }
}
}
diff --git a/FFXIVClassic_Lobby_Server/packets/ErrorPacket.cs b/FFXIVClassic_Lobby_Server/packets/ErrorPacket.cs
new file mode 100644
index 00000000..949b483f
--- /dev/null
+++ b/FFXIVClassic_Lobby_Server/packets/ErrorPacket.cs
@@ -0,0 +1,47 @@
+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 ErrorPacket
+ {
+ private const ushort OPCODE = 0x02;
+
+ private UInt64 sequence;
+ private uint errorCode;
+ private uint statusCode;
+ private uint textId;
+ private string message;
+
+ public ErrorPacket(UInt64 sequence, uint errorCode, uint statusCode, uint textId, string message)
+ {
+ this.sequence = sequence;
+ this.errorCode = errorCode;
+ this.statusCode = statusCode;
+ this.textId = textId;
+ this.message = message;
+ }
+
+ public SubPacket buildPacket()
+ {
+ MemoryStream memStream = new MemoryStream(0x210);
+ BinaryWriter binWriter = new BinaryWriter(memStream);
+
+ binWriter.Write(sequence);
+ binWriter.Write(errorCode);
+ binWriter.Write(statusCode);
+ binWriter.Write(textId);
+ binWriter.Write(message);
+
+ byte[] data = memStream.GetBuffer();
+ binWriter.Dispose();
+ memStream.Dispose();
+ SubPacket subpacket = new SubPacket(OPCODE, 0xe0006868, 0xe0006868, data);
+ return subpacket;
+ }
+ }
+}
diff --git a/FFXIVClassic_Lobby_Server/packets/PacketStructs.cs b/FFXIVClassic_Lobby_Server/packets/PacketStructs.cs
index 4bafb243..76e31f4a 100644
--- a/FFXIVClassic_Lobby_Server/packets/PacketStructs.cs
+++ b/FFXIVClassic_Lobby_Server/packets/PacketStructs.cs
@@ -22,27 +22,6 @@ namespace FFXIVClassic_Lobby_Server.packets
public String session;
}
- [StructLayout(LayoutKind.Sequential)]
- public unsafe struct WorldListPacket
- {
- public UInt64 sequence;
- public uint isEndListANDNumWorlds;
- public uint unknown1;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
- public WorldListEntry[] worlds;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public unsafe struct WorldListEntry
- {
- public ushort id;
- public ushort listPosition;
- public uint population;
- public UInt64 unknown;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x40)]
- public String name;
- }
-
[StructLayout(LayoutKind.Sequential)]
public unsafe struct CharacterRequestPacket
{
@@ -92,17 +71,6 @@ namespace FFXIVClassic_Lobby_Server.packets
public String errorMessage;
}
- [StructLayout(LayoutKind.Sequential)]
- public unsafe struct ErrorPacket
- {
- public UInt64 sequence;
- public uint errorCode;
- public uint statusCode;
- public uint errorId;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x2BB)]
- public String errorMessage;
- }
-
public static unsafe CharacterRequestPacket toCharacterRequestStruct(byte[] bytes)
{
fixed (byte* pdata = &bytes[0])
diff --git a/FFXIVClassic_Lobby_Server/packets/WorldListPacket.cs b/FFXIVClassic_Lobby_Server/packets/WorldListPacket.cs
new file mode 100644
index 00000000..530f786d
--- /dev/null
+++ b/FFXIVClassic_Lobby_Server/packets/WorldListPacket.cs
@@ -0,0 +1,94 @@
+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 WorldListPacket
+ {
+ private List worldList;
+
+ public WorldListPacket(List serverList)
+ {
+ this.worldList = serverList;
+ }
+
+ public List buildPackets()
+ {
+ List subPackets = new List();
+
+ int serverCount = 0;
+ int totalCount = 0;
+
+ MemoryStream memStream = null;
+ BinaryWriter binWriter = null;
+
+ foreach (World world in worldList)
+ {
+ if (totalCount == 0 || serverCount % 6 == 0)
+ {
+ memStream = new MemoryStream(0x210);
+ binWriter = new BinaryWriter(memStream);
+
+ //Write List Info
+ binWriter.Write((UInt64)0);
+ binWriter.Write(worldList.Count - totalCount <= 6 ? (byte)(worldList.Count + 1) : (byte)0);
+ binWriter.Write(worldList.Count - totalCount <= 6 ? (UInt32)worldList.Count - totalCount : (UInt32)6);
+ binWriter.Write((byte)0);
+ binWriter.Write((UInt16)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')));
+
+ serverCount++;
+ totalCount++;
+
+ //Send this chunk of world list
+ if (serverCount >= 6)
+ {
+ byte[] data = memStream.GetBuffer();
+ binWriter.Dispose();
+ memStream.Dispose();
+ SubPacket subpacket = new SubPacket(0x15, 0xe0006868, 0xe0006868, data);
+ subPackets.Add(subpacket);
+ serverCount = 0;
+ }
+
+ }
+
+ //If there is anything left that was missed or the list is empty
+ if (serverCount > 0 || worldList.Count == 0)
+ {
+ if (worldList.Count == 0)
+ {
+ memStream = new MemoryStream(0x210);
+ binWriter = new BinaryWriter(memStream);
+
+ //Write Empty List Info
+ binWriter.Write((UInt64)0);
+ 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(0x15, 0xe0006868, 0xe0006868, data);
+ subPackets.Add(subpacket);
+ }
+
+ return subPackets;
+ }
+ }
+}