暂存部分修正

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(); 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)] [StructLayout(LayoutKind.Sequential)]
@ -248,83 +274,8 @@ namespace PSO2SERVER.Models
Light, Light,
Dark 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 class AffixUtils
{ {
public static ushort[] ReadPackedAffixes(Stream reader) public static ushort[] ReadPackedAffixes(Stream reader)

View File

@ -119,5 +119,11 @@ namespace PSO2SERVER.Models
{ {
return new ObjectHeader(objHeaderStruct.ID, objHeaderStruct.ObjectType, objHeaderStruct.MapID); 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;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -9,6 +11,137 @@ using static PSO2SERVER.Models.PSOPalette;
namespace PSO2SERVER.Models 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 class PSOPalette
{ {
public struct Palette public struct Palette
@ -36,13 +169,13 @@ namespace PSO2SERVER.Models
// 初始化 Palettes // 初始化 Palettes
for (int i = 0; i < palette.Palettes.Length; i++) for (int i = 0; i < palette.Palettes.Length; i++)
{ {
palette.Palettes[i] = WeaponPalette.Create(); palette.Palettes[i] = new WeaponPalette();
} }
// 初始化 Subpalettes根据需要可以进行自定义初始化 // 初始化 Subpalettes根据需要可以进行自定义初始化
for (int i = 0; i < palette.Subpalettes.Length; i++) for (int i = 0; i < palette.Subpalettes.Length; i++)
{ {
palette.Subpalettes[i] = SubPalette.Create(); // 这里可以根据需要进行初始化 palette.Subpalettes[i] = new SubPalette(); // 这里可以根据需要进行初始化
} }
return palette; 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)] [PacketHandlerAttr(0x03, 0x10)]
public class MapLoaded : PacketHandler public class MapLoaded : PacketHandler
{ {
[StructLayout(LayoutKind.Sequential)] public unsafe struct MapLoadedPacket
public struct MapLoadedPacket
{ {
/// Loaded zone object. /// Loaded zone object.
public ObjectHeader MapObject; public ObjectHeader.ObjHeaderStruct MapObject;
/// Unknown data, 32 bytes. /// Unknown data, 32 bytes.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] public fixed byte Unk[0x20];
public byte[] Unk;
// 可选构造函数
public MapLoadedPacket(ObjectHeader mapObject)
{
MapObject = mapObject;
Unk = new byte[0x20];
}
} }
#region implemented abstract members of PacketHandler #region implemented abstract members of PacketHandler
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size) 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; 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 // Unlock Controls
context.SendPacket(new UnlockControlsPacket()); // Inital spawn only, move this! context.SendPacket(new UnlockControlsPacket()); // Inital spawn only, move this!

View File

@ -20,7 +20,8 @@ namespace PSO2SERVER.Protocol.Handlers
public uint unk2; public uint unk2;
public uint unk3; 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) public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{ {
if (context._account == null) if (context._account == null)

View File

@ -13,25 +13,65 @@ namespace PSO2SERVER.Protocol.Handlers
[PacketHandlerAttr(0x04, 0x14)] [PacketHandlerAttr(0x04, 0x14)]
public class ObjectInteract : PacketHandler 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) public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{ {
PacketReader reader = new PacketReader(data); var reader = new PacketReader(data, position, size);
reader.ReadBytes(12); // Padding MAYBE??????????? var pkt = new InteractPacket
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)
{ {
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 srcObj = new PSOObject
{ {
Header = srcObject, Header = pkt.Object1,
Name = "Accounts" 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); //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!!! // 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... // Try and get the teleport definition for the object...
using (var db = new ServerEf()) using (var db = new ServerEf())
{ {
db.Configuration.AutoDetectChangesEnabled = true; 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) if (teleporterEndpoint == null)
{ {
@ -57,7 +97,7 @@ namespace PSO2SERVER.Protocol.Handlers
// Teleport Accounts to default point // Teleport Accounts to default point
context.SendPacket(new TeleportTransferPacket(srcObj, new PSOLocation(0f, 1f, 0f, -0.000031f, -0.417969f, 0.000031f, 134.375f))); context.SendPacket(new TeleportTransferPacket(srcObj, new PSOLocation(0f, 1f, 0f, -0.000031f, -0.417969f, 0.000031f, 134.375f)));
// Unhide player // 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 else
{ {
@ -74,12 +114,12 @@ namespace PSO2SERVER.Protocol.Handlers
// Teleport Accounts // Teleport Accounts
context.SendPacket(new TeleportTransferPacket(srcObj, endpointLocation)); context.SendPacket(new TeleportTransferPacket(srcObj, endpointLocation));
// Unhide player // 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, context.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)context._account.AccountId, ObjectType.Player), srcObj.Header, srcObj.Header,
new ObjectHeader(), "FavsNeutral")); new ObjectHeader(), "FavsNeutral"));
@ -87,7 +127,7 @@ namespace PSO2SERVER.Protocol.Handlers
new ObjectHeader(), "AP")); // Short for Appear, Thanks Zapero! new ObjectHeader(), "AP")); // Short for Appear, Thanks Zapero!
} }
if (command == "Sit") if (pkt.Action == "Sit")
{ {
foreach (var client in Server.Instance.Clients) foreach (var client in Server.Instance.Clients)
{ {
@ -95,7 +135,7 @@ namespace PSO2SERVER.Protocol.Handlers
continue; continue;
client.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)client._account.AccountId, ObjectType.Player), srcObj.Header, 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 PSO2SERVER.Zone;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -10,34 +11,16 @@ namespace PSO2SERVER.Protocol.Packets
{ {
public class MapTransferPacket : Packet public class MapTransferPacket : Packet
{ {
//private readonly Map _map;
//private readonly int _playerid;
public ObjectHeader map { get; set; } = new ObjectHeader(); public ObjectHeader map { get; set; } = new ObjectHeader();
public ObjectHeader target { get; set; } = new ObjectHeader(); public ObjectHeader target { get; set; } = new ObjectHeader();
public ZoneSettings _zonesettings { get; set; } = new ZoneSettings(); public ZoneSettings _zonesettings { get; set; } = new ZoneSettings();
public MapTransferPacket(Map map, int PlayerId) public MapTransferPacket(ZoneData zone, uint mapid, uint PlayerId)
{ {
//_map = map; //_map = map;
this.map = new ObjectHeader((uint)map.MapID, ObjectType.Map); map = new ObjectHeader(mapid, ObjectType.Map);
target = new ObjectHeader((uint)PlayerId, ObjectType.Player); target = new ObjectHeader(PlayerId, ObjectType.Player);
_zonesettings = new ZoneSettings _zonesettings = zone.Settings;
{
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,
};
} }
#region implemented abstract members of Packet #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 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 #region implemented abstract members of Packet
@ -18,6 +20,7 @@ namespace PSO2SERVER.Protocol.Packets
public override byte[] Build() public override byte[] Build()
{ {
var pkt = new PacketWriter(); var pkt = new PacketWriter();
pkt.Write(Video_id);
return pkt.ToArray(); return pkt.ToArray();
} }

View File

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

View File

@ -9,40 +9,38 @@ namespace PSO2SERVER.Protocol.Packets
{ {
public class NewDefaultPAsPacket : Packet public class NewDefaultPAsPacket : Packet
{ {
public const int FixedLength = 0x1A0; // 416 bytes
public const int SeekAfter = 0x240; // 576 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) public void ReadFromStream(PacketReader reader)
{ {
// 跳过填充
reader.BaseStream.Seek(SeekAfter, SeekOrigin.Current);
// 读取 Default // 读取 Default
for (int i = 0; i < Default.Capacity; i++) for (int i = 0; i < Default.Capacity; i++)
{ {
Default.Add(reader.ReadUInt32()); Default.Add(reader.ReadUInt32());
} }
// 跳过填充
reader.BaseStream.Seek(SeekAfter - FixedLength, SeekOrigin.Current);
} }
public void WriteToStream(PacketWriter writer) public void WriteToStream(PacketWriter writer)
{ {
// 写入前面的填充(如果需要,可以根据协议实际填充字节)
writer.BaseStream.Seek(SeekAfter, SeekOrigin.Current);
// 写入 Default // 写入 Default
foreach (var value in Default) foreach (var value in Default)
{ {
writer.Write(value); writer.Write(value);
} }
// 填充到 0x240
long paddingSize = SeekAfter - FixedLength;
writer.BaseStream.Seek(paddingSize, SeekOrigin.Current);
} }
#region implemented abstract members of Packet #region implemented abstract members of Packet
@ -50,10 +48,7 @@ namespace PSO2SERVER.Protocol.Packets
public override byte[] Build() public override byte[] Build()
{ {
var writer = new PacketWriter(); var writer = new PacketWriter();
foreach (var value in Default) WriteToStream(writer);
{
writer.Write(value);
}
return writer.ToArray(); return writer.ToArray();
} }

View File

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

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Newtonsoft.Json; using Newtonsoft.Json;
using PSO2SERVER.Json;
using PSO2SERVER.Models; using PSO2SERVER.Models;
using PSO2SERVER.Object; using PSO2SERVER.Object;
using PSO2SERVER.Protocol; using PSO2SERVER.Protocol;
@ -52,6 +53,8 @@ namespace PSO2SERVER.Zone
public string InstanceName { get; set; } public string InstanceName { get; set; }
public List<MapData> mapDatas { get; set; }
public Map(string name, int id, int variant, MapType type, MapFlags flags) public Map(string name, int id, int variant, MapType type, MapFlags flags)
{ {
Name = name; Name = name;
@ -112,12 +115,14 @@ namespace PSO2SERVER.Zone
} }
else else
{ {
var _map = new Map("", MapID, VariantID, Type, Flags); //var _map = new Map("", MapID, VariantID, Type, Flags);
_map.GenerationArgs.seed = GenerationArgs.seed; //_map.GenerationArgs.seed = GenerationArgs.seed;
_map.GenerationArgs.xsize = GenerationArgs.xsize; //_map.GenerationArgs.xsize = GenerationArgs.xsize;
_map.GenerationArgs.ysize = GenerationArgs.ysize; //_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) 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, 0x05, 0x02, 0x06, 0x02, 0x07, 0x02, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
PSO2Item item = new PSO2Item(itemData); PSO2Items item = PSO2Items.FromByteArray(itemData);
long guid = item.GetGUID(); ulong guid = item.GetGUID();
long newguid = 0x0123456789ABCDEF; ulong newguid = 0x0123456789ABCDEF;
Assert.AreEqual(guid, 0x03FF2E79609940DA); Assert.AreEqual(guid, 0x03FF2E79609940DA);