using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using Mysqlx; using PSO2SERVER.Models; namespace PSO2SERVER.Protocol.Packets { class LoginDataPacket : Packet { public enum LoginStatus : UInt32 { /// /// Login was successful. /// Success = 0, /// /// Login failed. /// Failure = 1, /// /// Undefined status. /// Undefined = 0xFFFFFFFF } public LoginStatus Status; public string Error; public ObjectHeader Player; public string BlockName; public float Unk1; public uint Unk2; public uint LevelCap; public uint LevelCap2; public uint Unk5; public float Unk6; public float Unk7; public uint Unk8; public float Unk9; public float Unk10; public uint Unk11; public float Unk12; public uint Unk13; public float[] Unk14; // Length: 10 public float[] Unk15; // Length: 21 public float Unk16; public float Unk17; public float[] Unk18; // Length: 9 public uint[] Unk19; // Length: 2 public uint Unk20; public uint Unk21; public float[] Unk22; // Length: 3 public uint Unk23; public float Unk24; public float Unk25; public uint Unk26; public byte[] Unk27; // Length: 12 public string Unk28; public uint Unk29; public string Unk30; public uint Unk31; private string ReadFixedString(PacketReader reader, int length) { byte[] bytes = reader.ReadBytes(length); return Encoding.UTF8.GetString(bytes).TrimEnd('\0'); } public void ReadFromStream(PacketReader reader) { Status = (LoginStatus)reader.ReadInt32(); Error = ReadFixedString(reader, 32); // 0x20 = 32 Player.ReadFromStream(reader); BlockName = ReadFixedString(reader, 32); Unk1 = reader.ReadSingle(); Unk2 = reader.ReadUInt32(); LevelCap = reader.ReadUInt32(); LevelCap2 = reader.ReadUInt32(); Unk5 = reader.ReadUInt32(); Unk6 = reader.ReadSingle(); Unk7 = reader.ReadSingle(); Unk8 = reader.ReadUInt32(); Unk9 = reader.ReadSingle(); Unk10 = reader.ReadSingle(); Unk11 = reader.ReadUInt32(); Unk12 = reader.ReadSingle(); Unk13 = reader.ReadUInt32(); Unk14 = new float[10]; for (int i = 0; i < Unk14.Length; i++) { Unk14[i] = reader.ReadSingle(); } Unk15 = new float[21]; for (int i = 0; i < Unk15.Length; i++) { Unk15[i] = reader.ReadSingle(); } Unk16 = reader.ReadSingle(); Unk17 = reader.ReadSingle(); Unk18 = new float[9]; for (int i = 0; i < Unk18.Length; i++) { Unk18[i] = reader.ReadSingle(); } Unk19 = new uint[2]; for (int i = 0; i < Unk19.Length; i++) { Unk19[i] = reader.ReadUInt32(); } Unk20 = reader.ReadUInt32(); Unk21 = reader.ReadUInt32(); Unk22 = new float[3]; for (int i = 0; i < Unk22.Length; i++) { Unk22[i] = reader.ReadSingle(); } Unk23 = reader.ReadUInt32(); Unk24 = reader.ReadSingle(); Unk25 = reader.ReadSingle(); Unk26 = reader.ReadUInt32(); Unk27 = reader.ReadBytes(12); Unk28 = ReadFixedString(reader, 32); Unk29 = reader.ReadUInt32(); Unk30 = ReadFixedString(reader, 32); Unk31 = reader.ReadUInt32(); } private void WriteFixedString(PacketWriter writer, string str, int length) { byte[] bytes = new byte[length]; byte[] strBytes = Encoding.UTF8.GetBytes(str); Array.Copy(strBytes, bytes, Math.Min(strBytes.Length, length)); writer.Write(bytes); } public void WriteToStream(PacketWriter writer) { writer.Write((int)Status); writer.WriteUtf16(Error, 0x8BA4, 0xB6); if (Player.ID == 0) { for (var i = 0; i < 0xEC; i++) writer.Write((byte)0); } else { //WriteFixedString(writer, Error, 32); Player.WriteToStream(writer); WriteFixedString(writer, BlockName, 32); writer.Write(Unk1); writer.Write(Unk2); writer.Write(LevelCap); writer.Write(LevelCap2); writer.Write(Unk5); writer.Write(Unk6); writer.Write(Unk7); writer.Write(Unk8); writer.Write(Unk9); writer.Write(Unk10); writer.Write(Unk11); writer.Write(Unk12); writer.Write(Unk13); foreach (var val in Unk14) { writer.Write(val); } foreach (var val in Unk15) { writer.Write(val); } writer.Write(Unk16); writer.Write(Unk17); foreach (var val in Unk18) { writer.Write(val); } foreach (var val in Unk19) { writer.Write(val); } writer.Write(Unk20); writer.Write(Unk21); foreach (var val in Unk22) { writer.Write(val); } writer.Write(Unk23); writer.Write(Unk24); writer.Write(Unk25); writer.Write(Unk26); writer.Write(Unk27); WriteFixedString(writer, Unk28, 32); writer.Write(Unk29); WriteFixedString(writer, Unk30, 32); writer.Write(Unk31); } } public LoginDataPacket(string blockName, string error, uint userid) { Status = (userid == 0) ? LoginStatus.Failure : LoginStatus.Success; Error = error; Player.ID = userid; Player.ObjectType = ObjectType.Player; BlockName = blockName; } public override byte[] Build() { var resp = new PacketWriter(); resp.Write((uint)Status); // Status flag: 0=success, 1=error resp.WriteUtf16(Error, 0x8BA4, 0xB6); if (Player.ID == 0) { for (var i = 0; i < 0xEC; i++) resp.Write((byte)0); return resp.ToArray(); } // TODO: Explore this data! Some if it seems really important. (May contain level cap setting + more) resp.WriteStruct(Player); resp.WriteFixedLengthUtf16(BlockName, 0x20); // This is right // Set things to "default" values; Dunno these purposes yet. resp.Write(0x42700000); //0 resp.Write(7); //4 resp.Write(0xA); //8 - Level Cap! resp.Write(1); //C resp.Write(0x41200000); //10 resp.Write(0x40A00000); //14 resp.Write(11); //18 resp.Write(0x3F800000); //1C (1 as a float) resp.Write(0x42960000); //20 resp.Write(40); //24 resp.Write(0x41200000); //28 resp.Write(1); //2C? resp.Write(1120403456); //30 //WHAT for (int i = 0; i < 10; i++) { resp.Write(1065353216); } //ARE for (int i = 0; i < 21; i++) { resp.Write(1120403456); } //THESE? resp.Write(0x91A2B); //B0 resp.Write(0x91A2B); //B4 resp.WriteBytes(0, 12); return resp.ToArray(); } public override PacketHeader GetHeader() { return new PacketHeader(0x11, 0x01, PacketFlags.PACKED); } } }