部分修正

This commit is contained in:
Longfeng Qin 2024-09-22 11:14:48 +08:00
parent d4528a6dcc
commit 61c58a5114
10 changed files with 562 additions and 35 deletions

View File

@ -257,16 +257,20 @@ namespace PSO2SERVER
, _server.StartTime.ToShortTimeString().Replace('/', '-').Replace(':', '-')
);
using (var stream = File.OpenWrite(filename))
try
{
if (fromClient)
using (var stream = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.None))
{
stream.WriteByte(typeA);
stream.WriteByte(typeB);
stream.WriteByte(flags1);
stream.WriteByte(flags2);
if (fromClient)
{
stream.Write(new byte[] { typeA, typeB, flags1, flags2 }, 0, 4);
}
stream.Write(packet, 0, packet.Length);
}
stream.Write(packet, 0, packet.Length);
}
catch (Exception ex)
{
Console.WriteLine($"记录数据包时出错: {ex.Message}");
}
}
@ -290,13 +294,17 @@ namespace PSO2SERVER
, _server.StartTime.ToShortTimeString().Replace('/', '-').Replace(':', '-')
);
using (var stream = File.OpenWrite(filename))
try
{
stream.WriteByte(typeA);
stream.WriteByte(typeB);
stream.WriteByte(flags1);
stream.WriteByte(flags2);
stream.Write(packet, 0, packet.Length);
using (var stream = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.None))
{
stream.Write(new byte[] { typeA, typeB, flags1, flags2 }, 0, 4);
stream.Write(packet, 0, packet.Length);
}
}
catch (Exception ex)
{
Console.WriteLine($"记录未知数据包时出错: {ex.Message}");
}
}
}

View File

@ -3,6 +3,8 @@ using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using PSO2SERVER.Packets;
namespace PSO2SERVER.Models
{
@ -43,5 +45,20 @@ namespace PSO2SERVER.Models
ObjectType = type;
MapID = mapid;
}
public void ReadFromStream(PacketReader reader)
{
ID = reader.ReadUInt32();
padding = reader.ReadUInt32(); // 读取填充
ObjectType = (ObjectType)reader.ReadUInt16();
MapID = reader.ReadUInt16();
}
public void WriteToStream(PacketWriter writer)
{
writer.Write(ID);
writer.Write(padding); // 写入填充
writer.Write((UInt16)ObjectType);
writer.Write(MapID);
}
}
}

237
Server/Models/PSOPalette.cs Normal file
View File

@ -0,0 +1,237 @@
using PSO2SERVER.Packets;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static PSO2SERVER.Models.PSOPalette;
namespace PSO2SERVER.Models
{
public class PSOPalette
{
public struct Palette
{
public uint CurPalette;
public uint CurSubpalette;
public uint CurBook;
public WeaponPalette[] Palettes;
public SubPalette[] Subpalettes;
public List<uint> DefaultPas;
// 构造函数
public static Palette Create()
{
Palette palette = new Palette
{
CurPalette = 0,
CurSubpalette = 0,
CurBook = 0,
Palettes = new WeaponPalette[6],
Subpalettes = new SubPalette[6],
DefaultPas = new List<uint>()
};
// 初始化 Palettes
for (int i = 0; i < palette.Palettes.Length; i++)
{
palette.Palettes[i] = WeaponPalette.Create();
}
// 初始化 Subpalettes根据需要可以进行自定义初始化
for (int i = 0; i < palette.Subpalettes.Length; i++)
{
palette.Subpalettes[i] = SubPalette.Create(); // 这里可以根据需要进行初始化
}
return palette;
}
public void ReadFromStream(PacketReader reader)
{
CurPalette = reader.ReadUInt32();
CurSubpalette = reader.ReadUInt32();
CurBook = reader.ReadUInt32();
for (int i = 0; i < Palettes.Length; i++)
{
Palettes[i].ReadFromStream(reader);
}
for (int i = 0; i < Subpalettes.Length; i++)
{
Subpalettes[i].ReadFromStream(reader);
}
int defaultPasCount = reader.ReadInt32(); // 假设先读入数量
DefaultPas.Clear();
for (int i = 0; i < defaultPasCount; i++)
{
DefaultPas.Add(reader.ReadUInt32());
}
}
public void WriteToStream(PacketWriter writer)
{
writer.Write(CurPalette);
writer.Write(CurSubpalette);
writer.Write(CurBook);
for (int i = 0; i < Palettes.Length; i++)
{
Palettes[i].WriteToStream(writer);
}
for (int i = 0; i < Subpalettes.Length; i++)
{
Subpalettes[i].WriteToStream(writer);
}
writer.Write(DefaultPas.Count);
foreach (var value in DefaultPas)
{
writer.Write(value);
}
}
}
public struct PalettePA
{
/// PA ID.
public byte ID { get; set; }
/// PA category.
public byte Category { get; set; }
public byte Unk { get; set; }
/// PA level.
public byte Level { get; set; }
public PalettePA(byte id, byte category, byte unk, byte level)
{
ID = id;
Category = category;
Unk = unk;
Level = level;
}
public void ReadFromStream(PacketReader reader)
{
ID = reader.ReadByte();
Category = reader.ReadByte();
Unk = reader.ReadByte();
Level = reader.ReadByte();
}
public void WriteToStream(PacketWriter writer)
{
writer.Write(ID);
writer.Write(Category);
writer.Write(Unk);
writer.Write(Level);
}
}
public struct SubPalette
{
// // 创建 SubPalette 实例
// var subPalette = SubPalette.Create();
//// 从流中读取数据
//using (var reader = new PacketReader(yourStream))
//{
// subPalette.ReadFromStream(reader);
//}
//// 将数据写入流
//using (var writer = new PacketWriter(yourStream))
//{
// subPalette.WriteToStream(writer);
//}
/// Items in the subpalette.
public PalettePA[] Items { get; set; }
// 初始化数组
public static SubPalette Create()
{
return new SubPalette { Items = new PalettePA[12] };
}
public void ReadFromStream(PacketReader reader)
{
for (int i = 0; i < Items.Length; i++)
{
var palettePA = new PalettePA();
palettePA.ReadFromStream(reader);
Items[i] = palettePA;
}
}
public void WriteToStream(PacketWriter writer)
{
foreach (var item in Items)
{
item.WriteToStream(writer);
}
}
}
public struct WeaponPalette
{
public ulong Uuid { get; set; }
public uint Unk1 { get; set; }
public PalettePA Unk2 { get; set; }
public PalettePA Unk3 { get; set; }
public PalettePA Unk4 { get; set; }
public uint[] Unk { get; set; } // 初始化时需指定长度
public uint PetId { get; set; }
public PalettePA[] Skills { get; set; } // 初始化时需指定长度
public static WeaponPalette Create()
{
return new WeaponPalette
{
Unk = new uint[3],
Skills = new PalettePA[6]
};
}
public void ReadFromStream(PacketReader reader)
{
Uuid = reader.ReadUInt64();
Unk1 = reader.ReadUInt32();
Unk2 = new PalettePA();
Unk2.ReadFromStream(reader);
Unk3 = new PalettePA();
Unk3.ReadFromStream(reader);
Unk4 = new PalettePA();
Unk4.ReadFromStream(reader);
for (int i = 0; i < Unk.Length; i++)
{
Unk[i] = reader.ReadUInt32();
}
PetId = reader.ReadUInt32();
for (int i = 0; i < Skills.Length; i++)
{
Skills[i] = new PalettePA();
Skills[i].ReadFromStream(reader);
}
}
public void WriteToStream(PacketWriter writer)
{
writer.Write(Uuid);
writer.Write(Unk1);
Unk2.WriteToStream(writer);
Unk3.WriteToStream(writer);
Unk4.WriteToStream(writer);
foreach (var value in Unk)
{
writer.Write(value);
}
writer.Write(PetId);
foreach (var skill in Skills)
{
skill.WriteToStream(writer);
}
}
}
}
}

View File

@ -10,7 +10,7 @@ using System.Collections.Generic;
namespace PSO2SERVER.Packets.Handlers
{
[PacketHandlerAttr(0x11, 0x00)]
public class Login : PacketHandler
public class SegaIDLogin : PacketHandler
{
public uint Unk1 { get; set; }
public uint Unk2 { get; set; }
@ -167,7 +167,7 @@ namespace PSO2SERVER.Packets.Handlers
//mystery.Write((uint)100);
//context.SendPacket(0x11, 0x49, 0, mystery.ToArray());
// Login response packet
// SegaIDLogin response packet
if (user == null)
{
@ -210,9 +210,4 @@ namespace PSO2SERVER.Packets.Handlers
Japanese = 0,
English = 1
}
public class SegaIDLoginPacket
{
}
}

View File

@ -0,0 +1,20 @@
using System;
using PSO2SERVER.Models;
using PSO2SERVER.Packets.PSOPackets;
namespace PSO2SERVER.Packets.Handlers
{
[PacketHandlerAttr(0x21, 0x02)]
class FullPaletteInfoRequest : PacketHandler
{
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
var info = string.Format("[<--] 接收到的数据 (hex): {0} 字节", data.Length);
Logger.WriteHex(info, data);
var Palette = PSOPalette.Palette.Create();
context.SendPacket(new FullPaletteInfoPacket(Palette));
}
}
}

View File

@ -1,30 +1,237 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Mysqlx;
using PSO2SERVER.Models;
namespace PSO2SERVER.Packets.PSOPackets
{
class LoginDataPacket : Packet
{
private string blockName, error;
private uint userid;
public enum LoginStatus : UInt32
{
/// <summary>
/// Login was successful.
/// </summary>
Success = 0,
/// <summary>
/// Login failed.
/// </summary>
Failure = 1,
/// <summary>
/// Undefined status.
/// </summary>
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)
{
this.blockName = blockName;
this.error = error;
this.userid = 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)((userid == 0) ? 1 : 0)); // Status flag: 0=success, 1=error
resp.WriteUtf16(error, 0x8BA4, 0xB6);
resp.Write((uint)Status); // Status flag: 0=success, 1=error
resp.WriteUtf16(Error, 0x8BA4, 0xB6);
if (userid == 0)
if (Player.ID == 0)
{
for (var i = 0; i < 0xEC; i++)
resp.Write((byte)0);
@ -33,8 +240,8 @@ namespace PSO2SERVER.Packets.PSOPackets
// TODO: Explore this data! Some if it seems really important. (May contain level cap setting + more)
resp.WriteStruct(new ObjectHeader(userid, ObjectType.Player));
resp.WriteFixedLengthUtf16(blockName, 0x20); // This is right
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

View File

@ -20,9 +20,9 @@ namespace PSO2SERVER.Packets.PSOPackets
}
private readonly string _message;
private string _unk;
//private string _unk;
private readonly MessageType _type;
private uint _msg_num;
//private uint _msg_num;
public SystemMessagePacket(string message, MessageType type)
{

View File

@ -1,16 +1,20 @@
using PSO2SERVER.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using static PSO2SERVER.Models.PSOPalette;
namespace PSO2SERVER.Packets.PSOPackets
{
public class FullPaletteInfoPacket : Packet
{
private Palette Palette = Palette.Create();
public FullPaletteInfoPacket()
public FullPaletteInfoPacket(Palette palette)
{
this.Palette = palette;
}
#region implemented abstract members of Packet
@ -18,6 +22,12 @@ namespace PSO2SERVER.Packets.PSOPackets
public override byte[] Build()
{
var pkt = new PacketWriter();
Palette.WriteToStream(pkt);
byte[] byteArray = pkt.ToArray();
var info = string.Format("[-->] 发送的数据 (hex): {0} 字节", byteArray.Length);
Logger.WriteHex(info, byteArray);
return pkt.ToArray();
}

View File

@ -1,6 +1,7 @@
using PSO2SERVER.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
@ -8,10 +9,40 @@ namespace PSO2SERVER.Packets.PSOPackets
{
public class NewDefaultPAsPacket : Packet
{
public uint[] Default { get; set; } = new uint[0x1A0]; // 默认大小为0x1A0
public const int FixedLength = 0x1A0; // 416 bytes
public const int SeekAfter = 0x240; // 576 bytes
public List<uint> Default { get; set; }
public NewDefaultPAsPacket()
{
Default = new List<uint>(FixedLength / sizeof(uint)); // 初始化为 0x1A0 / 4
}
public void ReadFromStream(PacketReader reader)
{
// 读取 Default
for (int i = 0; i < Default.Capacity; i++)
{
Default.Add(reader.ReadUInt32());
}
// 跳过填充
reader.BaseStream.Seek(SeekAfter - FixedLength, SeekOrigin.Current);
}
public void WriteToStream(PacketWriter writer)
{
// 写入 Default
foreach (var value in Default)
{
writer.Write(value);
}
// 填充到 0x240
long paddingSize = SeekAfter - FixedLength;
writer.BaseStream.Seek(paddingSize, SeekOrigin.Current);
}
#region implemented abstract members of Packet

View File

@ -169,6 +169,7 @@
<Compile Include="Models\PSO2Item.cs" />
<Compile Include="Models\PSOData.cs" />
<Compile Include="Models\PSOObject.cs" />
<Compile Include="Models\PSOPalette.cs" />
<Compile Include="Models\Quest.cs" />
<Compile Include="Network\PortChecker.cs" />
<Compile Include="Object\ObjectManager.cs" />
@ -212,6 +213,7 @@
<Compile Include="Packets\Handlers\19-UnkHandler\19-1C-Unk191CPacketHandler.cs" />
<Compile Include="Packets\Handlers\19-UnkHandler\19-06-UNK - 复制.cs" />
<Compile Include="Packets\Handlers\19-UnkHandler\19-04-UNK.cs" />
<Compile Include="Packets\Handlers\21-PaletteHandler\21-02-FullPaletteInfoRequest.cs" />
<Compile Include="Packets\Handlers\23-FlagHandler\23-02-SetFlagHandler.cs" />
<Compile Include="Packets\Handlers\2B-SettingHandler\2B-01-SavePlayerSettings.cs" />
<Compile Include="Packets\Handlers\2B-SettingHandler\2B-00-SettingsRequest.cs" />
@ -378,7 +380,7 @@
<Compile Include="Server.cs" />
<Compile Include="Packets\Handlers\PacketHandler.cs" />
<Compile Include="Packets\Handlers\11-ClientHandler\11-0B-KeyExchange.cs" />
<Compile Include="Packets\Handlers\11-ClientHandler\11-00-Login.cs" />
<Compile Include="Packets\Handlers\11-ClientHandler\11-00-SegaIDLogin.cs" />
<Compile Include="Models\Character.cs" />
<Compile Include="Packets\Handlers\11-ClientHandler\11-54-CreateCharacterTwo.cs" />
<Compile Include="Packets\PacketWriter.cs" />