暂存部分修正
This commit is contained in:
parent
da015f100b
commit
892b6bfce7
45
Server/Json/ClassJson.cs
Normal file
45
Server/Json/ClassJson.cs
Normal 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();
|
||||
}
|
||||
|
||||
}
|
54
Server/Models/Inventory.cs
Normal file
54
Server/Models/Inventory.cs
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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!
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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" />
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user