暂存部分修正

This commit is contained in:
Longfeng Qin 2024-12-10 13:33:57 +08:00
parent da015f100b
commit 892b6bfce7
16 changed files with 439 additions and 302 deletions

45
Server/Json/ClassJson.cs Normal file
View File

@ -0,0 +1,45 @@
using Newtonsoft.Json;
using PSO2SERVER.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSO2SERVER.Json
{
public class ClassDefaultData
{
public List<DefaultClassesData> defaultClassesDatas = new List<DefaultClassesData>();
}
public class DefaultClassesData
{
[JsonProperty("class")]
public string ClassNames = string.Empty;
[JsonProperty("data")]
public DefaultClassData Data { get; set; } = new DefaultClassData();
}
public class DefaultClassData
{
[JsonProperty("items")]
public List<DefaultItem> Items { get; set; } = new List<DefaultItem>();
[JsonProperty("subpalettes")]
[JsonConverter(typeof(FixedListConverter<SubPalette>))]
public FixedList<SubPalette> Subpalettes { get; set; } = new FixedList<SubPalette>(6);
}
public class DefaultItem
{
[JsonProperty("item_data")]
public PSO2Items Item_data { get; set; } = new PSO2Items();
[JsonProperty("weapon_palette_data")]
public WeaponPalette Weapon_palette_data { get; set; } = new WeaponPalette();
[JsonProperty("weapon_palette_id")]
public byte Weapon_palette_id { get; set; } = new byte();
[JsonProperty("unit_equiped_id")]
public byte Unit_equiped_id { get; set; } = new byte();
}
}

View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSO2SERVER.Models
{
public struct ItemName
{
public ItemId id;
public string en_name;
public string jp_name;
public string en_desc;
public string jp_desc;
}
public struct ItemParameters
{
public List<byte> pc_attrs;
public List<byte> vita_attrs;
public ItemAttributesPC attrs;
public List<ItemName> names;
}
public struct StorageInventory
{
public uint total_space;
public byte storage_id;
public bool is_enabled;
public bool is_purchased;
public byte storage_type;
public List<PSO2Items> items;
}
public struct AccountStorages
{
public ulong Storage_meseta;
public StorageInventory Default;
public StorageInventory Premium;
public StorageInventory Extend1;
}
/// Player equiped item.
public struct EquipedItem
{
public PSO2Items item;
public uint unk;
}
internal class Inventory
{
}
}

View File

@ -60,6 +60,32 @@ namespace PSO2SERVER.Models
return pkt.ToArray();
}
}
// 从字节流转换为结构体
public static PSO2Items FromByteArray(byte[] byteArray)
{
using (var reader = new PacketReader(byteArray))
{
PSO2Items items = new PSO2Items
{
uuid = reader.ReadUInt64(),
id = reader.ReadStruct<ItemId>(),
data = reader.ReadStruct<Items>()
};
return items;
}
}
public ulong GetGUID()
{
return uuid;
}
public void SetGUID(ulong guid)
{
uuid = guid;
}
}
[StructLayout(LayoutKind.Sequential)]
@ -248,83 +274,8 @@ namespace PSO2SERVER.Models
Light,
Dark
}
public class PSO2Item
{
public const int Size = 0x38;
MemoryStream stream;
//TODO
public ItemTypes type = ItemTypes.Consumable;
public byte[] data = new byte[Size];
public override string ToString()
{
return string.Format("Data: {0:X}", BitConverter.ToString(data)).Replace('-', ' ');
}
public PSO2Item(byte[] data)
{
SetData(data);
}
public byte[] GetData()
{
return data;
}
public void SetData(byte[] data)
{
this.data = data;
stream = new MemoryStream(data, true);
}
public long GetGUID()
{
byte[] guid = new byte[sizeof(long)];
stream.Seek(0, SeekOrigin.Begin);
stream.Read(guid, 0, sizeof(long));
return BitConverter.ToInt64(guid, 0);
}
public void SetGUID(long guid)
{
stream.Seek(0, SeekOrigin.Begin);
stream.Write(BitConverter.GetBytes(guid), 0, 8);
}
public int[] GetID()
{
byte[] ID = new byte[sizeof(int)];
byte[] subID = new byte[sizeof(int)];
stream.Seek(0, SeekOrigin.Begin);
stream.Read(ID, 0x08, sizeof(int));
stream.Read(subID, 0x0C, sizeof(int));
return new int[] { BitConverter.ToInt32(ID, 0), BitConverter.ToInt32(subID, 0) };
}
public void SetID(int ID, int subID)
{
stream.Seek(0, SeekOrigin.Begin);
stream.Write(BitConverter.GetBytes(ID), 0x08, sizeof(int));
stream.Write(BitConverter.GetBytes(subID), 0x0C, sizeof(int));
}
// ...
}
/// Player equiped item.
public struct EquipedItem
{
public PSO2Items item;
public uint unk;
}
}
public static class AffixUtils
{
public static ushort[] ReadPackedAffixes(Stream reader)

View File

@ -119,5 +119,11 @@ namespace PSO2SERVER.Models
{
return new ObjectHeader(objHeaderStruct.ID, objHeaderStruct.ObjectType, objHeaderStruct.MapID);
}
// ToString 方法,用来返回 ObjectHeader 的字符串表示
public override string ToString()
{
return $"ObjectHeader [ID={ID}, Padding={Padding}, ObjectType={ObjectType}, MapID={MapID}]";
}
}
}

View File

@ -1,4 +1,6 @@
using PSO2SERVER.Protocol;
using Newtonsoft.Json;
using PSO2SERVER.Json;
using PSO2SERVER.Protocol;
using System;
using System.Collections.Generic;
using System.IO;
@ -9,6 +11,137 @@ using static PSO2SERVER.Models.PSOPalette;
namespace PSO2SERVER.Models
{
public class SubPalette
{
[JsonProperty("items")]
[JsonConverter(typeof(FixedListConverter<PalettePA>))]
// Items in the subpalette.
public FixedList<PalettePA> Items { get; set; } = new FixedList<PalettePA>(0x0C);
// 从字节流中读取数据
public void ReadFromStream(PacketReader reader)
{
// 假设 Items 长度固定为 12
for (int i = 0; i < Items.Length; i++)
{
// 读取每个 PalettePA
var palettePA = new PalettePA();
palettePA.ReadFromStream(reader);
Items.Add(palettePA); // 将读取的数据存储到 FixedList 中
}
}
// 写入数据到字节流
public void WriteToStream(PacketWriter writer)
{
// 遍历 FixedList将每个 PalettePA 写入字节流
foreach (var item in Items)
{
item.WriteToStream(writer);
}
}
}
public class PalettePA
{
[JsonProperty("id")]
/// PA ID.
public byte ID { get; set; } = 0;
[JsonProperty("category")]
/// PA category.
public byte Category { get; set; } = 0;
[JsonProperty("unk")]
public byte Unk { get; set; } = 0;
[JsonProperty("level")]
/// PA level.
public byte Level { get; set; } = 0;
public PalettePA()
{
}
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 class 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; } = new uint[3];
public uint PetId { get; set; }
public PalettePA[] Skills { get; set; } = new PalettePA[6];
public WeaponPalette()
{
}
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);
}
}
}
public class PSOPalette
{
public struct Palette
@ -36,13 +169,13 @@ namespace PSO2SERVER.Models
// 初始化 Palettes
for (int i = 0; i < palette.Palettes.Length; i++)
{
palette.Palettes[i] = WeaponPalette.Create();
palette.Palettes[i] = new WeaponPalette();
}
// 初始化 Subpalettes根据需要可以进行自定义初始化
for (int i = 0; i < palette.Subpalettes.Length; i++)
{
palette.Subpalettes[i] = SubPalette.Create(); // 这里可以根据需要进行初始化
palette.Subpalettes[i] = new SubPalette(); // 这里可以根据需要进行初始化
}
return palette;
@ -95,143 +228,6 @@ namespace PSO2SERVER.Models
}
}
}
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

@ -12,31 +12,43 @@ namespace PSO2SERVER.Protocol.Handlers
[PacketHandlerAttr(0x03, 0x10)]
public class MapLoaded : PacketHandler
{
[StructLayout(LayoutKind.Sequential)]
public struct MapLoadedPacket
public unsafe struct MapLoadedPacket
{
/// Loaded zone object.
public ObjectHeader MapObject;
public ObjectHeader.ObjHeaderStruct MapObject;
/// Unknown data, 32 bytes.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public byte[] Unk;
// 可选构造函数
public MapLoadedPacket(ObjectHeader mapObject)
{
MapObject = mapObject;
Unk = new byte[0x20];
}
public fixed byte Unk[0x20];
}
#region implemented abstract members of PacketHandler
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context._account == null || context.Character == null)
if (context._account == null)
return;
var reader = new PacketReader(data, position, size);
var pkt = reader.ReadStruct<MapLoadedPacket>();
Logger.Write($"MapObject {pkt.MapObject.ToString()}");
//TODO 这里才是完整的让角色在地图生成的地方
context.SendPacket(new LobbyMonitorPacket(1));
if(context.Character == null)
{
Logger.WriteError("Character should be loaded here");
return;
}
// Unlock Controls
context.SendPacket(new UnlockControlsPacket()); // Inital spawn only, move this!

View File

@ -20,7 +20,8 @@ namespace PSO2SERVER.Protocol.Handlers
public uint unk2;
public uint unk3;
}
///[<--] 0x03 - 0x35 (TeleportLobbyToCasino) (Flags None) (20 字节)
/// unk1 0 unk2 0 unk3 16
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context._account == null)

View File

@ -13,25 +13,65 @@ namespace PSO2SERVER.Protocol.Handlers
[PacketHandlerAttr(0x04, 0x14)]
public class ObjectInteract : PacketHandler
{
public class InteractPacket
{
// Fields
public byte[] Unk1 { get; set; } // [u8; 0xC]
public ObjectHeader Object1 { get; set; }
public byte[] Unk2 { get; set; } // [u8; 0x4]
public ObjectHeader Object3 { get; set; }
public byte[] Object4 { get; set; } // [u8; 0x10]
public string Action { get; set; } // AsciiString
// Constructor
public InteractPacket()
{
Unk1 = new byte[0x0C]; // Initialize arrays with appropriate sizes
Unk2 = new byte[0x04];
Object4 = new byte[0x10];
Action = string.Empty;
}
// Deserialize constructor (for example purposes, if needed)
public InteractPacket(byte[] unk1, ObjectHeader object1, byte[] unk2, ObjectHeader object3, byte[] object4, string action)
{
Unk1 = unk1;
Object1 = object1;
Unk2 = unk2;
Object3 = object3;
Object4 = object4;
Action = action;
}
}
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
PacketReader reader = new PacketReader(data);
reader.ReadBytes(12); // Padding MAYBE???????????
ObjectHeader srcObject = reader.ReadObjectHeader();
byte[] someBytes = reader.ReadBytes(4); // Dunno what this is yet.
ObjectHeader dstObject = reader.ReadObjectHeader(); // Could be wrong
reader.ReadBytes(16); // Not sure what this is yet
string command = reader.ReadAscii(0xD711, 0xCA);
PSOObject srcObj;
if(srcObject.ObjectType == ObjectType.Object)
var reader = new PacketReader(data, position, size);
var pkt = new InteractPacket
{
srcObj = ObjectManager.Instance.getObjectByID(context.CurrentZone.Name, srcObject.ID);
Unk1 = reader.ReadBytes(0x0C),
Object1 = reader.ReadObjectHeader(),
Unk2 = reader.ReadBytes(4),
Object3 = reader.ReadObjectHeader(),
Object4 = reader.ReadBytes(0x10),
Action = reader.ReadAscii(0xD711, 0xCA)
};
Logger.Write($"PKT:Object1 {pkt.Object1.ToString()} Object3 {pkt.Object3.ToString()} Action {pkt.Action}");
PSOObject srcObj;
if(pkt.Object1.ObjectType == ObjectType.Object)
{
srcObj = ObjectManager.Instance.getObjectByID(context.CurrentZone.Name, pkt.Object1.ID);
}
else if(srcObject.ObjectType == ObjectType.Player)
else if(pkt.Object1.ObjectType == ObjectType.Player)
{
srcObj = new PSOObject
{
Header = srcObject,
Header = pkt.Object1,
Name = "Accounts"
};
}
@ -43,13 +83,13 @@ namespace PSO2SERVER.Protocol.Handlers
//Logger.WriteInternal("[OBJ] {0} (ID {1}) <{2}> --> Ent {3} (ID {4})", srcObj.name, srcObj.Header.ID, command, (ObjectType)dstObject.ObjectType, dstObject.ID);
// TODO: Delete this code and do this COMPLETELY correctly!!!
if (command == "Transfer" && context.CurrentZone.Name == "lobby")
if (pkt.Action == "Transfer" && context.CurrentZone.Name == "lobby")
{
// Try and get the teleport definition for the object...
using (var db = new ServerEf())
{
db.Configuration.AutoDetectChangesEnabled = true;
var teleporterEndpoint = db.Teleports.Find("lobby", (int)srcObject.ID);
var teleporterEndpoint = db.Teleports.Find("lobby", (int)pkt.Object1.ID);
if (teleporterEndpoint == null)
{
@ -57,7 +97,7 @@ namespace PSO2SERVER.Protocol.Handlers
// Teleport Accounts to default point
context.SendPacket(new TeleportTransferPacket(srcObj, new PSOLocation(0f, 1f, 0f, -0.000031f, -0.417969f, 0.000031f, 134.375f)));
// Unhide player
context.SendPacket(new ObjectActionPacket(dstObject, srcObject, new ObjectHeader(), new ObjectHeader(), "Forwarded"));
context.SendPacket(new ObjectActionPacket(pkt.Object3, pkt.Object1, new ObjectHeader(), new ObjectHeader(), "Forwarded"));
}
else
{
@ -74,12 +114,12 @@ namespace PSO2SERVER.Protocol.Handlers
// Teleport Accounts
context.SendPacket(new TeleportTransferPacket(srcObj, endpointLocation));
// Unhide player
context.SendPacket(new ObjectActionPacket(dstObject, srcObject, new ObjectHeader(), new ObjectHeader(), "Forwarded"));
context.SendPacket(new ObjectActionPacket(pkt.Object3, pkt.Object1, new ObjectHeader(), new ObjectHeader(), "Forwarded"));
}
}
}
if (command == "READY")
if (pkt.Action == "READY")
{
context.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)context._account.AccountId, ObjectType.Player), srcObj.Header, srcObj.Header,
new ObjectHeader(), "FavsNeutral"));
@ -87,7 +127,7 @@ namespace PSO2SERVER.Protocol.Handlers
new ObjectHeader(), "AP")); // Short for Appear, Thanks Zapero!
}
if (command == "Sit")
if (pkt.Action == "Sit")
{
foreach (var client in Server.Instance.Clients)
{
@ -95,7 +135,7 @@ namespace PSO2SERVER.Protocol.Handlers
continue;
client.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)client._account.AccountId, ObjectType.Player), srcObj.Header,
new ObjectHeader(dstObject.ID, ObjectType.Player), new ObjectHeader(), "SitSuccess"));
new ObjectHeader(pkt.Object3.ID, ObjectType.Player), new ObjectHeader(), "SitSuccess"));
}
}
}

View File

@ -1,4 +1,5 @@
using PSO2SERVER.Models;
using PSO2SERVER.Json;
using PSO2SERVER.Models;
using PSO2SERVER.Zone;
using System;
using System.Collections.Generic;
@ -10,34 +11,16 @@ namespace PSO2SERVER.Protocol.Packets
{
public class MapTransferPacket : Packet
{
//private readonly Map _map;
//private readonly int _playerid;
public ObjectHeader map { get; set; } = new ObjectHeader();
public ObjectHeader target { get; set; } = new ObjectHeader();
public ZoneSettings _zonesettings { get; set; } = new ZoneSettings();
public MapTransferPacket(Map map, int PlayerId)
public MapTransferPacket(ZoneData zone, uint mapid, uint PlayerId)
{
//_map = map;
this.map = new ObjectHeader((uint)map.MapID, ObjectType.Map);
target = new ObjectHeader((uint)PlayerId, ObjectType.Player);
_zonesettings = new ZoneSettings
{
WorldId = 1,
Unk1 = 0,
ZoneId = ~(uint)map.Type,
MapId = (uint)map.MapID,
ZoneType = 0,
Seed = map.GenerationArgs.seed,
Args = (uint)map.VariantID,
SizeX = map.GenerationArgs.xsize,
SizeY = map.GenerationArgs.ysize,
Unk2 = 1,
AreaIndex = 1,
SubArea = 0xFFFFFFFF,
Unk3 = 0x301,
};
map = new ObjectHeader(mapid, ObjectType.Map);
target = new ObjectHeader(PlayerId, ObjectType.Player);
_zonesettings = zone.Settings;
}
#region implemented abstract members of Packet

View File

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using PSO2SERVER.Models;
namespace PSO2SERVER.Protocol.Packets
{
public class LoadPlayerInventoryPacket : Packet
{
/// Player object.
public ObjectHeader ObjectHeader { get; set; } = new ObjectHeader();
/// Character's name.
public string Name { get; set; } = string.Empty;
/// Meseta currently held.
public ulong Meseta { get; set; } = 0;
/// Max inventory capacity.
public uint Maxcapacity { get; set; } = 0;
public List<PSO2Items> Items { get; set; }= new List<PSO2Items>();
public LoadPlayerInventoryPacket(uint account_id, Client client)
{
ObjectHeader = new ObjectHeader(account_id, ObjectType.Player);
Name = client.Character.Name;
}
#region implemented abstract members of Packet
public override byte[] Build()
{
var pkt = new PacketWriter();
pkt.WriteObjectHeader(ObjectHeader);
pkt.Write(Name);
return pkt.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x0F, 0x0D, PacketFlags.PACKED);
}
#endregion
}
}

View File

@ -8,9 +8,11 @@ namespace PSO2SERVER.Protocol.Packets
{
public class LobbyMonitorPacket : Packet
{
public uint Video_id { get; set; } = 0;
public LobbyMonitorPacket()
public LobbyMonitorPacket(uint video_id)
{
Video_id = video_id;
}
#region implemented abstract members of Packet
@ -18,6 +20,7 @@ namespace PSO2SERVER.Protocol.Packets
public override byte[] Build()
{
var pkt = new PacketWriter();
pkt.Write(Video_id);
return pkt.ToArray();
}

View File

@ -22,13 +22,13 @@ namespace PSO2SERVER.Protocol.Packets
// 初始化 Palettes
for (int i = 0; i < Palettes.Length; i++)
{
Palettes[i] = WeaponPalette.Create();
Palettes[i] = new WeaponPalette();
}
// 初始化 Subpalettes根据需要可以进行自定义初始化
for (int i = 0; i < Subpalettes.Length; i++)
{
Subpalettes[i] = SubPalette.Create(); // 这里可以根据需要进行初始化
Subpalettes[i] = new SubPalette(); // 这里可以根据需要进行初始化
}
}
@ -42,13 +42,13 @@ namespace PSO2SERVER.Protocol.Packets
// 初始化 Palettes
for (int i = 0; i < Palettes.Length; i++)
{
pkt.WriteStruct(Palettes[i]);
Palettes[i].WriteToStream(pkt);
}
// 初始化 Subpalettes根据需要可以进行自定义初始化
for (int i = 0; i < Subpalettes.Length; i++)
{
pkt.WriteStruct(Subpalettes[i]);
Subpalettes[i].WriteToStream(pkt);
}
//// Enable flag

View File

@ -9,40 +9,38 @@ namespace PSO2SERVER.Protocol.Packets
{
public class NewDefaultPAsPacket : Packet
{
public const int FixedLength = 0x1A0; // 416 bytes
public const int SeekAfter = 0x240; // 576 bytes
public List<uint> Default { get; set; }
public FixedList<uint> Default { get; set; } = new FixedList<uint>(0x1A0);
public NewDefaultPAsPacket()
public NewDefaultPAsPacket(List<uint> Default)
{
Default = new List<uint>(FixedLength / sizeof(uint)); // 初始化为 0x1A0 / 4
foreach (var item in Default)
{
this.Default.Add(item);
}
}
public void ReadFromStream(PacketReader reader)
{
// 跳过填充
reader.BaseStream.Seek(SeekAfter, SeekOrigin.Current);
// 读取 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)
{
// 写入前面的填充(如果需要,可以根据协议实际填充字节)
writer.BaseStream.Seek(SeekAfter, SeekOrigin.Current);
// 写入 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
@ -50,10 +48,7 @@ namespace PSO2SERVER.Protocol.Packets
public override byte[] Build()
{
var writer = new PacketWriter();
foreach (var value in Default)
{
writer.Write(value);
}
WriteToStream(writer);
return writer.ToArray();
}

View File

@ -301,6 +301,7 @@
<Compile Include="Config.cs" />
<Compile Include="ConsoleSystem.cs" />
<Compile Include="Crypto\KeyLoader.cs" />
<Compile Include="Json\ClassJson.cs" />
<Compile Include="Json\JsonConverteres.cs" />
<Compile Include="Json\JsonTest.cs" />
<Compile Include="Json\JsonRead.cs" />
@ -311,6 +312,7 @@
<Compile Include="Models\CharacterAdditionalStruct.cs" />
<Compile Include="Models\FixedTypes.cs" />
<Compile Include="Models\Flags.cs" />
<Compile Include="Models\Inventory.cs" />
<Compile Include="Models\ItemAttributes.cs" />
<Compile Include="Models\Mission.cs" />
<Compile Include="Models\NetInterface.cs" />
@ -401,6 +403,7 @@
<Compile Include="Protocol\Handlers\4D-ClassicMissionPassHandler\4D-00-MissionPassInfoRequest.cs" />
<Compile Include="Protocol\Packets\04-ObjectRelatedPacket\04-75-ActionEndPacket.cs" />
<Compile Include="Protocol\Packets\0B-QuestPacket\0B-1B-QuestCategoryStopperPacket.cs" />
<Compile Include="Protocol\Packets\0F-ItemPacket\0F-0D-LoadPlayerInventoryPacket.cs" />
<Compile Include="Protocol\Packets\11-ClientPacket\11-0A-Unk110A.cs" />
<Compile Include="Protocol\Packets\19-LobbyPacket\19-08-SendSystemMessagePacket.cs" />
<Compile Include="Protocol\Packets\1E-UnkPacket\1E-0C-Unk1E0CPacket.cs" />

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using PSO2SERVER.Json;
using PSO2SERVER.Models;
using PSO2SERVER.Object;
using PSO2SERVER.Protocol;
@ -52,6 +53,8 @@ namespace PSO2SERVER.Zone
public string InstanceName { get; set; }
public List<MapData> mapDatas { get; set; }
public Map(string name, int id, int variant, MapType type, MapFlags flags)
{
Name = name;
@ -112,12 +115,14 @@ namespace PSO2SERVER.Zone
}
else
{
var _map = new Map("", MapID, VariantID, Type, Flags);
_map.GenerationArgs.seed = GenerationArgs.seed;
_map.GenerationArgs.xsize = GenerationArgs.xsize;
_map.GenerationArgs.ysize = GenerationArgs.ysize;
//var _map = new Map("", MapID, VariantID, Type, Flags);
//_map.GenerationArgs.seed = GenerationArgs.seed;
//_map.GenerationArgs.xsize = GenerationArgs.xsize;
//_map.GenerationArgs.ysize = GenerationArgs.ysize;
c.SendPacket(new MapTransferPacket(_map, c._account.AccountId));
ZoneData zoneData = new ZoneData();
c.SendPacket(new MapTransferPacket(zoneData, (uint)MapID, (uint)c._account.AccountId));
}
if (c.CurrentZone != null)

View File

@ -146,9 +146,9 @@ namespace ServerTest
0x05, 0x02, 0x06, 0x02, 0x07, 0x02, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
PSO2Item item = new PSO2Item(itemData);
long guid = item.GetGUID();
long newguid = 0x0123456789ABCDEF;
PSO2Items item = PSO2Items.FromByteArray(itemData);
ulong guid = item.GetGUID();
ulong newguid = 0x0123456789ABCDEF;
Assert.AreEqual(guid, 0x03FF2E79609940DA);