Reimplemented server list using BInaryWriter.

This commit is contained in:
Filip Maj 2015-09-03 22:20:53 -04:00
parent a65e81273b
commit e7e267bd44
5 changed files with 165 additions and 86 deletions

View File

@ -62,9 +62,11 @@
<Compile Include="dataobjects\World.cs" /> <Compile Include="dataobjects\World.cs" />
<Compile Include="PacketProcessor.cs" /> <Compile Include="PacketProcessor.cs" />
<Compile Include="packets\BasePacket.cs" /> <Compile Include="packets\BasePacket.cs" />
<Compile Include="packets\ErrorPacket.cs" />
<Compile Include="packets\HardCoded_Packets.cs" /> <Compile Include="packets\HardCoded_Packets.cs" />
<Compile Include="packets\PacketStructs.cs" /> <Compile Include="packets\PacketStructs.cs" />
<Compile Include="packets\SubPacket.cs" /> <Compile Include="packets\SubPacket.cs" />
<Compile Include="packets\WorldListPacket.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Server.cs" /> <Compile Include="Server.cs" />

View File

@ -147,7 +147,7 @@ namespace FFXIVClassic_Lobby_Server
{ {
Console.WriteLine("{0} => Get characters", client.currentUserId == 0 ? client.getAddress() : "User " + client.currentUserId); 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 outgoingPacket = new BasePacket("./packets/getCharsPacket.bin");
BasePacket.encryptPacket(client.blowfish, outgoingPacket); BasePacket.encryptPacket(client.blowfish, outgoingPacket);
@ -203,14 +203,8 @@ namespace FFXIVClassic_Lobby_Server
if (alreadyTaken) if (alreadyTaken)
{ {
PacketStructs.ErrorPacket errorPacket = new PacketStructs.ErrorPacket(); ErrorPacket errorPacket = new ErrorPacket(charaReq.sequence, 13005, 0, 0, "");
errorPacket.sequence = charaReq.sequence; SubPacket subpacket = errorPacket.buildPacket();
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);
BasePacket basePacket = BasePacket.createPacket(subpacket, true, false); BasePacket basePacket = BasePacket.createPacket(subpacket, true, false);
basePacket.debugPrintPacket(); basePacket.debugPrintPacket();
BasePacket.encryptPacket(client.blowfish, basePacket); BasePacket.encryptPacket(client.blowfish, basePacket);
@ -252,56 +246,30 @@ namespace FFXIVClassic_Lobby_Server
} }
} }
private void buildWorldLists(ClientConnection client, SubPacket packet) private void sendWorldList(ClientConnection client, SubPacket packet)
{ {
List<World> serverList = Database.getServers(); List<World> serverList = Database.getServers();
WorldListPacket worldlistPacket = new WorldListPacket(serverList);
List<SubPacket> subPackets = worldlistPacket.buildPackets();
int serverCount = 0; BasePacket basePacket = BasePacket.createPacket(subPackets, true, false);
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];
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;
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); BasePacket.encryptPacket(client.blowfish, basePacket);
client.queuePacket(basePacket); client.queuePacket(basePacket);
}
//Make new worldlist if still remaining private void sendUnknownList(ClientConnection client, SubPacket packet)
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;
}
} }
private void sendRetainerList(ClientConnection client, SubPacket packet)
{
} }
private void sendCharacterList(ClientConnection client, SubPacket packet)
{
} }
} }

View File

@ -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;
}
}
}

View File

@ -22,27 +22,6 @@ namespace FFXIVClassic_Lobby_Server.packets
public String session; 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)] [StructLayout(LayoutKind.Sequential)]
public unsafe struct CharacterRequestPacket public unsafe struct CharacterRequestPacket
{ {
@ -92,17 +71,6 @@ namespace FFXIVClassic_Lobby_Server.packets
public String errorMessage; 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) public static unsafe CharacterRequestPacket toCharacterRequestStruct(byte[] bytes)
{ {
fixed (byte* pdata = &bytes[0]) fixed (byte* pdata = &bytes[0])

View File

@ -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<World> worldList;
public WorldListPacket(List<World> serverList)
{
this.worldList = serverList;
}
public List<SubPacket> buildPackets()
{
List<SubPacket> subPackets = new List<SubPacket>();
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;
}
}
}