From b147a7ee04c8ca78c349a66b250007e6c772fe4d Mon Sep 17 00:00:00 2001 From: Longfeng Qin Date: Wed, 11 Dec 2024 04:10:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=83=A8=E5=88=86=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/Logger.cs | 22 ++++++ Server/Models/ItemsAdditional.cs | 8 +-- Server/Models/PSO2Item.cs | 67 ++++++++++++++----- .../04-ObjectHandler/04-14-ObjectInteract.cs | 2 +- .../0F-1C-GetItemDescription.cs | 27 ++++++++ Server/Server.csproj | 1 + ServerTest/Test.cs | 2 +- 7 files changed, 105 insertions(+), 24 deletions(-) create mode 100644 Server/Protocol/Handlers/0F-ItemHandler/0F-1C-GetItemDescription.cs diff --git a/Server/Logger.cs b/Server/Logger.cs index 0818b27..14fbc1c 100644 --- a/Server/Logger.cs +++ b/Server/Logger.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Reflection; using System.Runtime.InteropServices; using PSO2SERVER.Protocol.Packets; @@ -29,6 +30,27 @@ namespace PSO2SERVER WriteFile(text, args); } + public static void WriteObj(object obj) + { + if (obj == null) + { + WriteError("无法分析空的对象."); + return; + } + + Type objType = obj.GetType(); + Write($"当前分析对象: {objType.FullName}"); + + // Use reflection to get all public fields of the object + var fields = objType.GetFields(BindingFlags.Public | BindingFlags.Instance); + + foreach (var field in fields) + { + var value = field.GetValue(obj); + Write($"{field.Name}: {value}"); + } + } + public static void WriteSend(string text, params object[] args) { AddLine(ConsoleColor.Green, string.Format(text, args)); diff --git a/Server/Models/ItemsAdditional.cs b/Server/Models/ItemsAdditional.cs index e396737..919b6b1 100644 --- a/Server/Models/ItemsAdditional.cs +++ b/Server/Models/ItemsAdditional.cs @@ -6,15 +6,15 @@ using System.Threading.Tasks; namespace PSO2SERVER.Models { - public enum ItemTypes + public enum ItemTypes : ushort { - NoItem, + NoItem = 0, Weapon, Clothing, Consumable, - Camo, + Unknown, Unit, - Unknown + Camo = 10, } [Flags] diff --git a/Server/Models/PSO2Item.cs b/Server/Models/PSO2Item.cs index 5dfcf93..961b9e7 100644 --- a/Server/Models/PSO2Item.cs +++ b/Server/Models/PSO2Item.cs @@ -26,7 +26,7 @@ namespace PSO2SERVER.Models } [StructLayout(LayoutKind.Explicit)] - public struct Items + public unsafe struct Items { [FieldOffset(0)] public PSO2ItemWeapon Weapon; @@ -38,10 +38,10 @@ namespace PSO2SERVER.Models public PSO2ItemCamo Camo; [FieldOffset(0)] public PSO2ItemUnit Unit; - //[FieldOffset(0)] - //public byte[] Unknown; - //[FieldOffset(0)] - //public PSO2ItemNone None; + [FieldOffset(0)] + public fixed byte Unknown[0x28]; + [FieldOffset(0)] + public fixed byte Noitem[0x28]; } [StructLayout(LayoutKind.Sequential)] @@ -89,28 +89,28 @@ namespace PSO2SERVER.Models } - [StructLayout(LayoutKind.Sequential)] - public unsafe struct PSO2ItemNone - { - } - [StructLayout(LayoutKind.Sequential)] public unsafe struct PSO2ItemWeapon { + /// Item flags. public byte flags; + /// Item element. public byte element; + /// Item force. public byte force; public byte grind; public byte grindPercent; - public byte unknown1; - public short unknown2; - public fixed short affixes[8]; + public byte unk1; + public ushort unk2; + /// Item affix IDs. + public fixed ushort affixes[8]; + /// Item potential. public uint potential; public byte extend; - public byte unknown3; - public ushort unknown4; - public uint unknown5; - public uint unknown6; + public byte unk4; + public ushort unk5; + public uint unk6; + public uint unk7; } [StructLayout(LayoutKind.Sequential)] @@ -414,4 +414,35 @@ namespace PSO2SERVER.Models public uint StorageId { get; set; } } -} + public static class AffixUtils + { + public static ushort[] ReadPackedAffixes(Stream reader) + { + byte[] packed = new byte[12]; + reader.Read(packed, 0, packed.Length); + + ushort[] affixes = new ushort[8]; + for (int i = 0; i < 4; i++) + { + affixes[i * 2] = BitConverter.ToUInt16(new byte[] { packed[i * 3], (byte)((packed[i * 3 + 2] & 0xF0) >> 4) }, 0); + affixes[i * 2 + 1] = BitConverter.ToUInt16(new byte[] { packed[i * 3 + 1], (byte)(packed[i * 3 + 2] & 0xF) }, 0); + } + return affixes; + } + + public static void WritePackedAffixes(ushort[] affixes, Stream writer) + { + byte[] packed = new byte[12]; + for (int i = 0; i < 4; i++) + { + byte[] affix1 = BitConverter.GetBytes(affixes[i * 2]); + byte[] affix2 = BitConverter.GetBytes(affixes[i * 2 + 1]); + + packed[i * 3] = affix1[0]; + packed[i * 3 + 1] = affix2[0]; + packed[i * 3 + 2] = (byte)((affix1[1] << 4) | (affix2[1] & 0xF)); + } + writer.Write(packed, 0, packed.Length); + } + } +} \ No newline at end of file diff --git a/Server/Protocol/Handlers/04-ObjectHandler/04-14-ObjectInteract.cs b/Server/Protocol/Handlers/04-ObjectHandler/04-14-ObjectInteract.cs index 4a7186b..9ef549a 100644 --- a/Server/Protocol/Handlers/04-ObjectHandler/04-14-ObjectInteract.cs +++ b/Server/Protocol/Handlers/04-ObjectHandler/04-14-ObjectInteract.cs @@ -58,7 +58,7 @@ namespace PSO2SERVER.Protocol.Handlers }; - Logger.Write($"PKT:Object1 {pkt.Object1.ToString()} Object3 {pkt.Object3.ToString()} Action {pkt.Action}"); + //Logger.Write($"PKT:Object1 {pkt.Object1.ToString()} Object3 {pkt.Object3.ToString()} Action {pkt.Action}"); diff --git a/Server/Protocol/Handlers/0F-ItemHandler/0F-1C-GetItemDescription.cs b/Server/Protocol/Handlers/0F-ItemHandler/0F-1C-GetItemDescription.cs new file mode 100644 index 0000000..edf903c --- /dev/null +++ b/Server/Protocol/Handlers/0F-ItemHandler/0F-1C-GetItemDescription.cs @@ -0,0 +1,27 @@ +using System; +using PSO2SERVER.Models; +using PSO2SERVER.Protocol.Packets; + +namespace PSO2SERVER.Protocol.Handlers +{ + [PacketHandlerAttr(0x0F, 0x1C)] + public class GetItemDescription : PacketHandler + { + public struct GetItemDescriptionPacket + { + /// Item ID which description is requested. + public ItemId Item { get; set; } + } + + 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 reader = new PacketReader(data, position, size); + var pkt = reader.ReadStruct(); + + Logger.WriteObj(pkt.Item); + } + } +} diff --git a/Server/Server.csproj b/Server/Server.csproj index b6d897c..2104d07 100644 --- a/Server/Server.csproj +++ b/Server/Server.csproj @@ -340,6 +340,7 @@ + diff --git a/ServerTest/Test.cs b/ServerTest/Test.cs index 0f75f59..fc546ad 100644 --- a/ServerTest/Test.cs +++ b/ServerTest/Test.cs @@ -35,7 +35,7 @@ namespace ServerTest foreach (var p in PacketHandlers.GetLoadedHandlers()) { Assert.IsNotNull(p); - Assert.IsInstanceOf(typeof(PacketHandler), p, "Loaded PacketHandler is not a Packet Handler!"); + Assert.IsInstanceOf(typeof(PacketHandler), p, "加载的PacketHandler不是一个包处理程序!"); } } }