diff --git a/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj b/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj
index 203bf2dc..e30d33c2 100644
--- a/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj
+++ b/FFXIVClassic_Lobby_Server/FFXIVClassic_Lobby_Server.csproj
@@ -55,6 +55,7 @@
+
diff --git a/FFXIVClassic_Lobby_Server/PacketProcessor.cs b/FFXIVClassic_Lobby_Server/PacketProcessor.cs
index d94f1471..6ed7b0ed 100644
--- a/FFXIVClassic_Lobby_Server/PacketProcessor.cs
+++ b/FFXIVClassic_Lobby_Server/PacketProcessor.cs
@@ -80,7 +80,7 @@ namespace FFXIVClassic_Lobby_Server
BasePacket.decryptPacket(client.blowfish, ref packet);
- packet.debugPrintPacket();
+ //packet.debugPrintPacket();
List subPackets = packet.getSubpackets();
foreach (SubPacket subpacket in subPackets)
@@ -157,11 +157,7 @@ namespace FFXIVClassic_Lobby_Server
sendWorldList(client, packet);
sendImportList(client, packet);
sendRetainerList(client, packet);
- sendCharacterList(client, packet);
- /*BasePacket outgoingPacket = new BasePacket("./packets/getChars_GOOD.bin");
- outgoingPacket.debugPrintPacket();
- BasePacket.encryptPacket(client.blowfish, outgoingPacket);
- client.queuePacket(outgoingPacket);*/
+ sendCharacterList(client, packet);
}
@@ -177,7 +173,7 @@ namespace FFXIVClassic_Lobby_Server
Log.info(String.Format("{0} => Select character id {1}", client.currentUserId == 0 ? client.getAddress() : "User " + client.currentUserId, characterId));
- String serverIp = "141.117.162.99";
+ String serverIp = "141.117.161.40";
ushort port = 54992;
BitConverter.GetBytes(port);
BasePacket outgoingPacket = new BasePacket("./packets/selectChar.bin");
@@ -309,8 +305,7 @@ namespace FFXIVClassic_Lobby_Server
}
CharaCreatorPacket charaCreator = new CharaCreatorPacket(charaReq.sequence, code, pid, cid, 1, name, worldName);
- BasePacket charaCreatorPacket = BasePacket.createPacket(charaCreator.buildPacket(), true, false);
- charaCreatorPacket.debugPrintPacket();
+ BasePacket charaCreatorPacket = BasePacket.createPacket(charaCreator.buildPacket(), true, false);
BasePacket.encryptPacket(client.blowfish, charaCreatorPacket);
client.queuePacket(charaCreatorPacket);
diff --git a/FFXIVClassic_Lobby_Server/common/Bitfield.cs b/FFXIVClassic_Lobby_Server/common/Bitfield.cs
new file mode 100644
index 00000000..d4e885a0
--- /dev/null
+++ b/FFXIVClassic_Lobby_Server/common/Bitfield.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FFXIVClassic_Lobby_Server.common
+{
+ [global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
+ sealed class BitfieldLengthAttribute : Attribute
+ {
+ uint length;
+
+ public BitfieldLengthAttribute(uint length)
+ {
+ this.length = length;
+ }
+
+ public uint Length { get { return length; } }
+ }
+
+ static class PrimitiveConversion
+ {
+ public static UInt32 ToUInt32(T t) where T : struct
+ {
+ UInt32 r = 0;
+ int offset = 0;
+
+ // For every field suitably attributed with a BitfieldLength
+ foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
+ {
+ object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
+ if (attrs.Length == 1)
+ {
+ uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length;
+
+ // Calculate a bitmask of the desired length
+ uint mask = 0;
+ for (int i = 0; i < fieldLength; i++)
+ mask |= (UInt32)1 << i;
+
+ r |= ((UInt32)f.GetValue(t) & mask) << offset;
+
+ offset += (int)fieldLength;
+ }
+ }
+
+ return r;
+ }
+
+ public static long ToLong(T t) where T : struct
+ {
+ long r = 0;
+ int offset = 0;
+
+ // For every field suitably attributed with a BitfieldLength
+ foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
+ {
+ object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
+ if (attrs.Length == 1)
+ {
+ uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length;
+
+ // Calculate a bitmask of the desired length
+ long mask = 0;
+ for (int i = 0; i < fieldLength; i++)
+ mask |= 1 << i;
+
+ r |= ((UInt32)f.GetValue(t) & mask) << offset;
+
+ offset += (int)fieldLength;
+ }
+ }
+
+ return r;
+ }
+ }
+}
\ No newline at end of file
diff --git a/FFXIVClassic_Lobby_Server/dataobjects/CharaInfo.cs b/FFXIVClassic_Lobby_Server/dataobjects/CharaInfo.cs
index 1ebb52e2..5609d829 100644
--- a/FFXIVClassic_Lobby_Server/dataobjects/CharaInfo.cs
+++ b/FFXIVClassic_Lobby_Server/dataobjects/CharaInfo.cs
@@ -21,10 +21,36 @@ namespace FFXIVClassic_Lobby_Server.dataobjects
public ushort eyeColor = 0;
public ushort characteristicsColor = 0;
+ 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 uint faceType = 0;
- public uint faceEyebrow = 0;
+ public uint faceEyebrows = 0;
public uint faceEyeShape = 0;
- public uint faceEyeSize = 0;
+ public uint faceIrisSize = 0;
public uint faceNose = 0;
public uint faceMouth = 0;
public uint faceFeatures = 0;
@@ -75,8 +101,8 @@ namespace FFXIVClassic_Lobby_Server.dataobjects
reader.ReadUInt32();
- info.faceEyebrow = reader.ReadByte();
- info.faceEyeSize = reader.ReadByte();
+ info.faceEyebrows = reader.ReadByte();
+ info.faceIrisSize = reader.ReadByte();
info.faceEyeShape = reader.ReadByte();
info.faceNose = reader.ReadByte();
info.faceFeatures = reader.ReadByte();
@@ -119,6 +145,20 @@ namespace FFXIVClassic_Lobby_Server.dataobjects
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
+ //Build faceinfo for later
+ 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;
+
+
string location1 = "prv0Inn01\0";
string location2 = "defaultTerritory\0";
@@ -132,7 +172,10 @@ namespace FFXIVClassic_Lobby_Server.dataobjects
writer.Write((UInt32)size);
uint colorVal = skinColor | (uint)(hairColor << 10) | (uint)(eyeColor << 20);
writer.Write((UInt32)colorVal);
- writer.Write((UInt32)0x14d00100); //FACE, Figure this out!
+
+ var bitfield = PrimitiveConversion.ToUInt32(faceInfo);
+
+ writer.Write((UInt32)bitfield); //FACE, Figure this out!
uint hairVal = hairHighlightColor | (uint)(hairStyle << 10) | (uint)(characteristicsColor << 20);
writer.Write((UInt32)hairVal);
writer.Write((UInt32)voice);