修正角色列表数据包 但是未修正角色生成

This commit is contained in:
Longfeng Qin 2024-09-17 22:47:58 +08:00
parent 86cbf43914
commit 5a151be0da
15 changed files with 87 additions and 117 deletions

View File

@ -55,13 +55,13 @@ namespace PSO2SERVER
{
if ((_readBufferSize + size) > _readBuffer.Length)
{
Logger.WriteError("[接收] 接收到 {0} 字节大于预设buf长度", size);
Logger.WriteError("[<--] 接收到 {0} 字节大于预设buf长度", size);
// Buffer overrun
// TODO: Drop the connection when this occurs?
return;
}
//Logger.Write("[接收] 接收到 {0} 字节", size);
//Logger.Write("[<--] 接收到 {0} 字节", size);
Array.Copy(data, 0, _readBuffer, _readBufferSize, size);
@ -139,11 +139,11 @@ namespace PSO2SERVER
sendName = $"0x{typeA:X2} - 0x{typeB:X2}";
}
Logger.Write($"[接收] 数据包 {sendName} (Flags {(PacketFlags)flags1}) ({blob.Length} 字节)");
Logger.Write($"[-->] {sendName} (Flags {(PacketFlags)flags1}) ({blob.Length} 字节)");
if (Logger.VerbosePackets)
{
var info = string.Format("[接收] 0x{0:X2} - 0x{1:X2} 数据包:", typeA, typeB);
var info = string.Format("[-->] 0x{0:X2} - 0x{1:X2} 数据包:", typeA, typeB);
Logger.WriteHex(info, blob);
}
@ -163,22 +163,30 @@ namespace PSO2SERVER
public void SendPacket(byte typeA, byte typeB, byte flags, byte[] data, string name = null)
{
var packet = new byte[8 + data.Length];
if (data == null)
{
throw new ArgumentNullException(nameof(data), "Data array cannot be null.");
}
// TODO: Use BinaryWriter here maybe?
var dataLen = (uint)data.Length + 8;
packet[0] = (byte)(dataLen & 0xFF);
packet[1] = (byte)((dataLen >> 8) & 0xFF);
packet[2] = (byte)((dataLen >> 16) & 0xFF);
packet[3] = (byte)((dataLen >> 24) & 0xFF);
packet[4] = typeA;
packet[5] = typeB;
packet[6] = flags;
packet[7] = 0;
using (var memoryStream = new MemoryStream())
using (var binaryWriter = new BinaryWriter(memoryStream))
{
// 写入数据长度总长度为头部4字节 + typeA(1) + typeB(1) + flags(1) + 额外字节的长度))
uint dataLen = (uint)data.Length + 8;
binaryWriter.Write(dataLen); // 自动处理为小端序
Array.Copy(data, 0, packet, 8, data.Length);
// 写入类型A、类型B和标志
binaryWriter.Write(typeA);
binaryWriter.Write(typeB);
binaryWriter.Write(flags);
binaryWriter.Write((byte)0); // 额外的字节
SendPacket(packet, name);
// 写入数据
binaryWriter.Write(data);
// 调用实际发送数据的方法
SendPacket(memoryStream.ToArray(), name);
}
}
public void SendPacket(Packet packet)
@ -200,7 +208,7 @@ namespace PSO2SERVER
{
packetName = $"0x{typeA:X2} - 0x{typeB:X2}";
}
Logger.Write($"[发送] 数据包 {packetName} (Flags {(PacketFlags)flags1}) ({size + 8} 字节)");
Logger.Write($"[<--] {packetName} (Flags {(PacketFlags)flags1}) ({size + 8} 字节)");
var packet = new byte[size];
Array.Copy(data, position, packet, 0, size);
@ -210,7 +218,7 @@ namespace PSO2SERVER
for (var i = 0; i < size; i++)
dataTrimmed[i] = data[i];
var info = string.Format("[发送] 0x{0:X2} - 0x{1:X2} 数据包:", typeA, typeB);
var info = string.Format("[<--] 0x{0:X2} - 0x{1:X2} 数据包:", typeA, typeB);
Logger.WriteHex(info, dataTrimmed);
}
@ -220,7 +228,7 @@ namespace PSO2SERVER
handler.HandlePacket(this, flags1, packet, 0, size);
else
{
Logger.WriteWarning("[未解析] 0x{0:X2} - 0x{1:X2} (未解析数据包) (Flags {2}) ({3} 字节)", typeA,
Logger.WriteWarning("[<--未解析] 0x{0:X2} - 0x{1:X2} (UNK) (Flags {2}) ({3} 字节)", typeA,
typeB, (PacketFlags)flags1, size);
LogUnkClientPacket(typeA, typeB, flags1, flags2, packet);
}

View File

@ -72,8 +72,8 @@ namespace PSO2SERVER.Models
[StructLayout(LayoutKind.Sequential)]
public unsafe struct CharParam
{
public uint character_id;
public uint player_id;
public int character_id;
public int player_id;
public uint unk1;
public uint voice_type;
public ushort unk2;
@ -122,29 +122,13 @@ namespace PSO2SERVER.Models
[StructLayout(LayoutKind.Sequential)]
public unsafe struct JobParam
{
//public fixed byte unknown_0[4];
public ClassType mainClass;
public ClassType subClass;
public fixed byte uknown_6[2];
public ushort unk2;
public ClassTypeField enabledClasses;
public fixed byte uknown_8[2];
//public byte padding0;
public ushort unk3;
public Entries entries; //TODO: Make this a fixed array
public fixed ushort unk_maxlevel[15];
//public ushort unknown_48, unknown_4A;
//public uint unknown_4C;
//public ushort unknown_50, unknown_52;
//public uint unknown_54;
//public ushort unknown_58, unknown_5A;
//public uint unknown_5C;
//public ushort unknown_60, unknown_62;
//public uint unknown_64;
//public uint unknown_68;
//public ushort unknown_6C, unknown_6E;
//public fixed int unknown_70[4];
}
public enum RunAnimation : ushort
@ -202,7 +186,6 @@ namespace PSO2SERVER.Models
public RunAnimation running_animation;
public Race race;
public Gender gender;
//public fixed byte padding[4];
public ushort Muscule;
public Figure Body;
public Figure Arms;
@ -229,20 +212,6 @@ namespace PSO2SERVER.Models
public AccessoryData Acc2Location;
public AccessoryData Acc3Location;
public AccessoryData Acc4Location;
//public ushort height;
//public fixed byte charData[80]; // Figure Data, needs more work
//public ushort accessoryData1;
//public ushort accessoryData2;
//public ushort accessoryData3;
//public ushort accessoryData4;
public HSVColor UnkColor;
public HSVColor CostumeColor;
public HSVColor MainColor;
@ -286,27 +255,6 @@ namespace PSO2SERVER.Models
public fixed byte Unk8[0x08];
public SkinColor SkinColorType;
public sbyte EyebrowThickness;
//public int modelID;
//public ushort mainParts;
//public ushort bodyPaint;
//public ushort emblem;
//public ushort eyePattern;
//public ushort eyelashes;
//public ushort eyebrows;
//public ushort face;
//public ushort facePaint1;
//public ushort hairstyle;
//public ushort accessory1;
//public ushort accessory2;
//public ushort accessory3;
//public ushort facePaint2;
//public ushort arms;
//public ushort legs;
//public ushort accessory4;
//public ushort costume;
//public Race race;
//public Gender gender;
}
// Probably more info than this
@ -314,25 +262,11 @@ namespace PSO2SERVER.Models
public int Id { get; set; }
public int CharacterId { get; set; }
public virtual Player Player { get; set; }
public byte[] CharSetBinary
{
get
{
PacketWriter w = new PacketWriter();
w.WriteStruct(CharSet);
return w.ToArray();
}
set
{
CharSet = Helper.ByteArrayToStructure<CharParam>(value);
}
}
public CharParam CharSet { get; set; }
public int player_id { get; set; }
public uint unk1 { get; set; }
public uint voice_type { get; set; }
public ushort unk2 { get; set; }
public short voice_pitch { get; set; }
public string Name { get; set; }
@ -354,6 +288,8 @@ namespace PSO2SERVER.Models
public LooksParam Looks { get; set; }
public uint unk3 { get; set; }
public byte[] JobsBinary
{
get
@ -371,6 +307,10 @@ namespace PSO2SERVER.Models
}
public JobParam Jobs { get; set; }
public string unk4 { get; set; }
public virtual Player Player { get; set; }
}

View File

@ -9,7 +9,7 @@ namespace PSO2SERVER.Packets.Handlers
// {
// public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
// {
// //var info = string.Format("[接收] 接收到的数据 (hex): ");
// //var info = string.Format("[<--] 接收到的数据 (hex): ");
// //Logger.WriteHex(info, data);
// }
// }

View File

@ -13,7 +13,7 @@ namespace PSO2SERVER.Packets.Handlers
// /// (0x03, 0x00) Map Transfer.
// public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
// {
// //var info = string.Format("[接收] 接收到的数据 (hex): ");
// //var info = string.Format("[<--] 接收到的数据 (hex): ");
// //Logger.WriteHex(info, data);
// }
//}

View File

@ -12,7 +12,7 @@ namespace PSO2SERVER.Packets.Handlers
//{
// public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
// {
// //var info = string.Format("[接收] 接收到的数据 (hex): ");
// //var info = string.Format("[<--] 接收到的数据 (hex): ");
// //Logger.WriteHex(info, data);
// }
//}

View File

@ -23,7 +23,15 @@ namespace PSO2SERVER.Packets.Handlers
context.SendPacket(0x1E, 0xC, 0x0, BitConverter.GetBytes(101));
Map dstMap = ZoneManager.Instance.MapFromInstance("cafe", "lobby");
dstMap.SpawnClient(context, dstMap.GetDefaultLocation());
if(dstMap != null)
{
dstMap.SpawnClient(context, dstMap.GetDefaultLocation());
}
else
{
Logger.WriteError("cafe 区域不存在");
return;
}
}
}

View File

@ -14,7 +14,7 @@ namespace PSO2SERVER.Packets.Handlers
{
if (context.Character == null)
return;
var info = string.Format("[接收] 接收到的数据 (hex): ");
var info = string.Format("[<--] 接收到的数据 (hex): ");
Logger.WriteHex(info, data);
var reader = new PacketReader(data, position, size);

View File

@ -9,7 +9,7 @@ namespace PSO2SERVER.Packets.Handlers
//{
// public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
// {
// //var info = string.Format("[接收] 接收到的数据 (hex): ");
// //var info = string.Format("[<--] 接收到的数据 (hex): ");
// //Logger.WriteHex(info, data);
// }
//}

View File

@ -9,7 +9,7 @@ namespace PSO2SERVER.Packets.Handlers
// {
// public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
// {
// //var info = string.Format("[接收] 接收到的数据 (hex): ");
// //var info = string.Format("[<--] 接收到的数据 (hex): ");
// //Logger.WriteHex(info, data);
// }
// }

View File

@ -16,7 +16,7 @@ namespace PSO2SERVER.Packets.Handlers
{
var reader = new PacketReader(data, position, size);
//var info = string.Format("[接收] 接收到的数据 (hex): ");
//var info = string.Format("[<--] 接收到的数据 (hex): ");
//Logger.WriteHex(info, data);
reader.BaseStream.Seek(0x2C, SeekOrigin.Current);

View File

@ -8,12 +8,22 @@ namespace PSO2SERVER.Packets.Handlers
[PacketHandlerAttr(0x11, 0x04)]
public class StartGame : PacketHandler
{
public struct StartGamePacket
{
/// <summary>
/// Selected character ID.
/// </summary>
public uint CharId;
public uint Unk1;
public uint Unk2;
}
#region implemented abstract members of PacketHandler
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
var reader = new PacketReader(data, position, size);
var charId = reader.ReadUInt32();
var pkt = reader.ReadStruct<StartGamePacket>();
//Logger.Write("id {0}", charId);
@ -24,13 +34,13 @@ namespace PSO2SERVER.Packets.Handlers
{
using (var db = new ServerEf())
{
var character = db.Characters.Where(c => c.CharacterId == charId).First();
var character = db.Characters.Where(c => c.CharacterId == pkt.CharId).First();
if (character == null || character.Player.PlayerId != context.User.PlayerId)
{
Logger.WriteError("数据库中未找到 {0} 角色ID {1} ({2})"
, context.User.Username
, charId
, pkt.CharId
, context.User.PlayerId
);
context.Socket.Close();

View File

@ -20,7 +20,7 @@ namespace PSO2SERVER.Packets.Handlers
return;
var reader = new PacketReader(data, position, size);
//var info = string.Format("[接收] 接收到的数据 (hex): ");
//var info = string.Format("[<--] 接收到的数据 (hex): ");
//Logger.WriteHex(info, data);
var setting = reader.ReadStruct<Character.CharParam>();
//reader.ReadBytes(12); // 12 unknown bytes
@ -37,7 +37,6 @@ namespace PSO2SERVER.Packets.Handlers
//Logger.WriteInternal("[CHR] {0} 创建了名为 {1} 的新角色.", context.User.Username, name);
var newCharacter = new Character
{
CharSet = setting,
Name = name,
Jobs = jobs,
Looks = looks,
@ -60,6 +59,12 @@ namespace PSO2SERVER.Packets.Handlers
newCharacter.CharacterId = 1;
}
newCharacter.player_id = context.User.PlayerId;
newCharacter.unk1 = setting.unk1;
newCharacter.voice_type = setting.voice_type;
newCharacter.unk2 = setting.unk2;
newCharacter.voice_pitch = setting.voice_pitch;
//Logger.Write("newCharacter.CharacterId {0} {1}", newCharacter.CharacterId, context.User.PlayerId);
db.Characters.Add(newCharacter);

View File

@ -26,7 +26,7 @@ namespace PSO2SERVER.Packets.Handlers
Array.Reverse(cryptedBlob);
// Print the contents of cryptedBlob in hexadecimal format
//var info = string.Format("[接收] 接收到的数据 (hex): ");
//var info = string.Format("[<--] 接收到的数据 (hex): ");
//Logger.WriteHex(info, cryptedBlob);
//// Convert cryptedBlob to a hexadecimal string

View File

@ -50,19 +50,18 @@ namespace PSO2SERVER.Packets.PSOPackets
foreach (var ch in chars)
{
writer.Write((uint)ch.CharacterId);
writer.Write((uint)_PlayerId);
for (var i = 0; i < 0x10; i++)
writer.Write((byte)0);
writer.Write(ch.CharacterId);
writer.Write(ch.player_id);
writer.Write(ch.unk1);
writer.Write(ch.voice_type);
writer.Write(ch.unk2);
writer.Write(ch.voice_pitch);
writer.WriteFixedLengthUtf16(ch.Name, 16);
writer.Write((uint)0);
writer.WriteStruct(ch.Looks); // Note: 第4集之前创造的外观似乎不再有效了
writer.WriteStruct(ch.Jobs);
for (var i = 0; i < 0xFC; i++)
for (var i = 0; i < 0x90; i++)
writer.Write((byte)0);
}
}