完成地图json数据的基础读取

This commit is contained in:
Longfeng Qin 2024-12-08 10:56:05 +08:00
parent 0114bbc5d4
commit 4a8c6b33d4
8 changed files with 652 additions and 140 deletions

View File

@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace PSO2SERVER.Models
{
public class CharacterAddtionStruct
public class CharacterAdditionalStruct
{
}

View File

@ -13,6 +13,9 @@ using static Org.BouncyCastle.Math.EC.ECCurve;
using System.Reflection;
using System.Linq;
using Newtonsoft.Json.Linq;
using Google.Protobuf.Compiler;
using Newtonsoft.Json;
using PSO2SERVER.Zone;
namespace PSO2SERVER
{
@ -87,6 +90,19 @@ namespace PSO2SERVER
Console.CancelKeyPress += Exit;
AppDomain.CurrentDomain.ProcessExit += Exit;
string jsonFilePath = "data\\maps\\lobby\\data.json";
// 读取 JSON 文件
string json = File.ReadAllText(jsonFilePath);
// 反序列化为 C# 对象
MapData map = JsonConvert.DeserializeObject<MapData>(json);
// 输出结果
Logger.Write($"map_object ID: {map.Mapdata.map_object.ID}");
Logger.Write($"Zones[0].Name: {map.Zones[0].Name}");
Logger.Write($"Zones[0].IsSpecialZone: {map.Zones[0].IsSpecialZone}");
try
{
for (var i = 0; i < args.Length; i++)

View File

@ -1,4 +1,5 @@
using PSO2SERVER.Models;
using PSO2SERVER.Zone;
using System;
using System.Collections.Generic;
using System.IO;
@ -11,11 +12,74 @@ namespace PSO2SERVER.Protocol.Packets
{
private readonly string _file;
/// Initial zone object.
public ObjectHeader map_object { get; set; } = new ObjectHeader();
/// Receiving player.
public ObjectHeader receiver { get; set; } = new ObjectHeader();
/// Settings for the initial zone (i.e. first zone that the player will appear in).
public ZoneSettings settings { get; set; } = new ZoneSettings();
public byte[] unk4 { get; set; } = new byte[0x0C];
public byte[] unk5 { get; set; } = new byte[0x0C];
public byte[] unk6 { get; set; } = new byte[0x0C];
public string unk7 { get; set; } = string.Empty;//Ascii
/// Settings for other zones.
public List<ZoneSettings> other_settings { get; set; } = new List<ZoneSettings>();
public List<WarpInfo> warps { get; set; } = new List<WarpInfo>();
public List<LoadLevelThing3> unk10 { get; set; } = new List<LoadLevelThing3>();
public List<LoadLevelThing4> unk11 { get; set; } = new List<LoadLevelThing4>();
public List<LoadLevelThing5> unk12 { get; set; } = new List<LoadLevelThing5>();
public List<LoadLevelThing6> unk13 { get; set; } = new List<LoadLevelThing6>();
public List<LoadLevelThing7> unk14 { get; set; } = new List<LoadLevelThing7>();
public List<LoadLevelThing8> unk15 { get; set; } = new List<LoadLevelThing8>();
public List<UnkThing1> unk16 { get; set; } = new List<UnkThing1>();
public string unk17 { get; set; } = string.Empty;//Ascii
public uint unk18 { get; set; } = 0;
public uint unk19 { get; set; } = 0;
public uint unk20 { get; set; } = 0;
// Fixed length array: C# doesn't have a direct equivalent, but we can use List<T> or byte[].
// If the length is fixed, it's better to use byte[] and document its length.
public List<byte> unk21 { get; set; } = new List<byte>(new byte[0x3C]);
public uint unk22 { get; set; } = 0;
public byte[] unk23 { get; set; } = new byte[0x10];
public byte[] unk24 { get; set; } = new byte[0x10];
public List<uint> unk25 { get; set; } = new List<uint> { };
// Fixed length array: 0x200 bytes.
public List<byte> unk26 { get; set; } = new List<byte>(new byte[0x200]);
public List<UnkThing2> unk27 { get; set; } = new List<UnkThing2> { };
public string unk28 { get; set; } = string.Empty;//Ascii
public string unk29 { get; set; } = string.Empty;//Ascii
public ulong unk30 { get; set; } = 0;
public ulong unk31 { get; set; } = 0;
public byte unk32 { get; set; } = 0;
public byte unk33 { get; set; } = 0;
public byte unk34 { get; set; } = 0;
public byte unk35 { get; set; } = 0;
public uint unk36 { get; set; } = 0;
public byte[] unk37 { get; set; } = new byte[0x14];
public ulong unk38 { get; set; } = 0;
public uint unk39 { get; set; } = 0;
public uint unk40 { get; set; } = 0;
public byte[] unk41 { get; set; } = new byte[0x12];
public ulong unk42 { get; set; } = 0;
public byte unk43 { get; set; } = 0;
public byte unk44 { get; set; } = 0;
public List<LoadLevelThing9> unk45 { get; set; } = new List<LoadLevelThing9>();
public string unk46 { get; set; } = string.Empty;//Ascii
public List<LoadLevelThing10> unk47 { get; set; } = new List<LoadLevelThing10> { };
public uint unk48 { get; set; } = 0;
public byte[] unk49 { get; set; } = new byte[0x14];
public byte[] unk50 { get; set; } = new byte[0x14];
public uint unk51 { get; set; } = 0;
public LoadingLevelPacket(string file)
{
_file = file;
}
public LoadingLevelPacket()
{
}
#region implemented abstract members of Packet
public override byte[] Build()

View File

@ -81,7 +81,7 @@ namespace PSO2SERVER.Protocol.Packets
/// <summary>
/// 未知
/// </summary>
private AsciiString unk2;
private string unk2 = "";
private Character[] players;
public PartyInitPacket(Character[] players)
@ -144,7 +144,7 @@ namespace PSO2SERVER.Protocol.Packets
writer.WriteUtf16(entries[i].unk6, 0xD863, 0xA9);
}
writer.WriteAscii("123456", 0xD863, 0xA9);
writer.WriteAscii(unk2, 0xD863, 0xA9);
//// 队伍结构数据
//for(int i = 0; i < players.Length; i++)

View File

@ -170,7 +170,7 @@
<Compile Include="Logger.cs" />
<Compile Include="Models\BattleStats.cs" />
<Compile Include="Models\BlockInfo.cs" />
<Compile Include="Models\CharacterAddtionStruct.cs" />
<Compile Include="Models\CharacterAdditionalStruct.cs" />
<Compile Include="Models\FixedTypes.cs" />
<Compile Include="Models\Flags.cs" />
<Compile Include="Models\Mission.cs" />
@ -448,6 +448,8 @@
<Compile Include="Protocol\Handlers\04-ObjectHandler\04-07-MovementHandlers.cs" />
<Compile Include="Protocol\Handlers\07-ChatHandler\07-00-ChatHandler.cs" />
<Compile Include="Zone\Map.cs" />
<Compile Include="Zone\MapJson.cs" />
<Compile Include="Zone\ZoneAdditional.cs" />
<Compile Include="Zone\ZoneManager.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

View File

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using PSO2SERVER.Models;
using PSO2SERVER.Object;
using PSO2SERVER.Protocol;
@ -225,139 +225,4 @@ namespace PSO2SERVER.Zone
}
}
public struct ZoneSettings
{
public uint WorldId;
public uint Unk1;
public uint ZoneId;
/// Map layout id.
public uint MapId;
public uint ZoneType;
public uint Seed;
public uint Args;
public uint SizeX;
public uint SizeY;
public uint Unk2;
public uint AreaIndex;
public uint SubArea;
public uint Unk3;
// 构造函数
public ZoneSettings(uint worldId, uint unk1, uint zoneId, uint mapId, uint zoneType, uint seed,
uint args, uint sizeX, uint sizeY, uint unk2, uint areaIndex, uint subArea, uint unk3)
{
WorldId = worldId;
Unk1 = unk1;
ZoneId = zoneId;
MapId = mapId;
ZoneType = zoneType;
Seed = seed;
Args = args;
SizeX = sizeX;
SizeY = sizeY;
Unk2 = unk2;
AreaIndex = areaIndex;
SubArea = subArea;
Unk3 = unk3;
}
// 重写 ToString 方法(可选)
public override string ToString()
{
return $"WorldId: {WorldId}, ZoneId: {ZoneId}, MapId: {MapId}, SizeX: {SizeX}, SizeY: {SizeY}";
}
}
public class EnemySpawn
{
public string EnemyName { get; set; }
public uint SpawnCategory { get; set; }
// 默认构造函数
public EnemySpawn()
{
EnemyName = string.Empty;
SpawnCategory = 0;
}
// 带参构造函数
public EnemySpawn(string enemyName, uint spawnCategory)
{
EnemyName = enemyName;
SpawnCategory = spawnCategory;
}
}
public class ZoneData
{
public string Name { get; set; }
public bool IsSpecialZone { get; set; }
public uint ZoneId { get; set; }
public ZoneSettings Settings { get; set; }
public PSOLocation DefaultLocation { get; set; }
public List<EnemySpawn> Enemies { get; set; }
public List<ZoneChunk> Chunks { get; set; }
// 默认构造函数
public ZoneData()
{
Name = string.Empty;
IsSpecialZone = false;
ZoneId = new uint();
Settings = new ZoneSettings();
DefaultLocation = new PSOLocation();
Enemies = new List<EnemySpawn>();
Chunks = new List<ZoneChunk>();
}
}
public class ZoneChunk
{
public uint ZoneId { get; set; }
public uint ChunkId { get; set; }
public EnemySpawnType EnemySpawnType { get; set; }
public List<PSOLocation> EnemySpawnPoints { get; set; }
// 默认构造函数
public ZoneChunk()
{
ZoneId = new uint();
ChunkId = 0;
EnemySpawnType = EnemySpawnType.Disabled;
EnemySpawnPoints = new List<PSOLocation>();
}
}
public enum EnemySpawnType
{
Disabled,
Automatic,
AutomaticWithRespawn,
Manual
}
public class AutomaticEnemySpawn
{
public uint Min { get; set; }
public uint Max { get; set; }
public AutomaticEnemySpawn() { }
public AutomaticEnemySpawn(uint min, uint max)
{
Min = min;
Max = max;
}
}
public class AutomaticWithRespawnEnemySpawn : AutomaticEnemySpawn
{
public TimeSpan RespawnTime { get; set; }
public AutomaticWithRespawnEnemySpawn() { }
public AutomaticWithRespawnEnemySpawn(uint min, uint max, TimeSpan respawnTime)
: base(min, max)
{
RespawnTime = respawnTime;
}
}
}

205
Server/Zone/MapJson.cs Normal file
View File

@ -0,0 +1,205 @@
using Newtonsoft.Json;
using Org.BouncyCastle.Asn1.Pkcs;
using PSO2SERVER.Protocol.Packets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSO2SERVER.Zone
{
public class MapData
{
[JsonProperty("map_data")]
public LoadingLevelPacket Mapdata { get; set; }
[JsonProperty("objects")]
public List<ObjectData> Objects { get; set; }
[JsonProperty("events")]
public List<EventData> Events { get; set; }
[JsonProperty("npcs")]
public List<NPCData> Npcs { get; set; }
[JsonProperty("transporters")]
public List<TransporterData> Transporters { get; set; }
[JsonProperty("luas")]
public Dictionary<string, string> Luas { get; set; }
[JsonProperty("init_map")]
public uint InitMap { get; set; }//ZoneId
[JsonProperty("zones")]
public List<ZoneData> Zones { get; set; }
// 默认构造函数
public MapData()
{
// 使用默认值初始化字段
Mapdata = new LoadingLevelPacket();
Objects = new List<ObjectData>();
Events = new List<EventData>();
Npcs = new List<NPCData>();
Transporters = new List<TransporterData>();
Luas = new Dictionary<string, string>();
InitMap = new uint();
Zones = new List<ZoneData>();
}
}
public class ObjectData
{
public uint zone_id { get; set; }
public bool is_active { get; set; }
public ObjectSpawnPacket data { get; set; }
public string lua_data { get; set; }
}
public class ZoneData
{
public string Name { get; set; }
public bool IsSpecialZone { get; set; }
public uint ZoneId { get; set; }
public ZoneSettings Settings { get; set; }
public PSOLocation DefaultLocation { get; set; }
public List<EnemySpawn> Enemies { get; set; }
public List<ZoneChunk> Chunks { get; set; }
// 默认构造函数
public ZoneData()
{
Name = string.Empty;
IsSpecialZone = false;
ZoneId = new uint();
Settings = new ZoneSettings();
DefaultLocation = new PSOLocation();
Enemies = new List<EnemySpawn>();
Chunks = new List<ZoneChunk>();
}
}
public class ZoneChunk
{
public uint ZoneId { get; set; }
public uint ChunkId { get; set; }
public EnemySpawnType EnemySpawnType { get; set; }
public List<PSOLocation> EnemySpawnPoints { get; set; }
// 默认构造函数
public ZoneChunk()
{
ZoneId = new uint();
ChunkId = 0;
EnemySpawnType = new Disabled();
EnemySpawnPoints = new List<PSOLocation>();
}
}
public abstract class EnemySpawnType
{
// 基类方法,用来获取默认值
public static EnemySpawnType Default => new Disabled();
}
public class Disabled : EnemySpawnType { }
public class Automatic : EnemySpawnType
{
public uint Min { get; set; }
public uint Max { get; set; }
public Automatic(uint min, uint max)
{
Min = min;
Max = max;
}
}
public class AutomaticWithRespawn : EnemySpawnType
{
public uint Min { get; set; }
public uint Max { get; set; }
public TimeSpan RespawnTime { get; set; }
public AutomaticWithRespawn(uint min, uint max, TimeSpan respawnTime)
{
Min = min;
Max = max;
RespawnTime = respawnTime;
}
}
public class Manual : EnemySpawnType { }
public class EventData
{
public uint zone_id { get; set; }
public bool is_active { get; set; }
public EventSpawnPacket data { get; set; }
public string lua_data { get; set; }
}
public class NPCData
{
public uint zone_id { get; set; }
public bool is_active { get; set; }
public NPCSpawnPacket data { get; set; }
public string lua_data { get; set; }
}
public class TransporterData
{
public uint zone_id { get; set; }
public bool is_active { get; set; }
public TransporterSpawnPacket data { get; set; }
public string lua_data { get; set; }
}
public class EnemySpawn
{
public string EnemyName { get; set; }
public uint SpawnCategory { get; set; }
// 默认构造函数
public EnemySpawn()
{
EnemyName = string.Empty;
SpawnCategory = 0;
}
// 带参构造函数
public EnemySpawn(string enemyName, uint spawnCategory)
{
EnemyName = enemyName;
SpawnCategory = spawnCategory;
}
}
public class AutomaticEnemySpawn
{
public uint Min { get; set; }
public uint Max { get; set; }
public AutomaticEnemySpawn() { }
public AutomaticEnemySpawn(uint min, uint max)
{
Min = min;
Max = max;
}
}
public class AutomaticWithRespawnEnemySpawn : AutomaticEnemySpawn
{
public TimeSpan RespawnTime { get; set; }
public AutomaticWithRespawnEnemySpawn() { }
public AutomaticWithRespawnEnemySpawn(uint min, uint max, TimeSpan respawnTime)
: base(min, max)
{
RespawnTime = respawnTime;
}
}
}

View File

@ -0,0 +1,360 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSO2SERVER.Zone
{
public struct ZoneSettings
{
public uint WorldId;
public uint Unk1;
public uint ZoneId;
/// Map layout id.
public uint MapId;
public uint ZoneType;
public uint Seed;
public uint Args;
public uint SizeX;
public uint SizeY;
public uint Unk2;
public uint AreaIndex;
public uint SubArea;
public uint Unk3;
// 构造函数
public ZoneSettings(uint worldId, uint unk1, uint zoneId, uint mapId, uint zoneType, uint seed,
uint args, uint sizeX, uint sizeY, uint unk2, uint areaIndex, uint subArea, uint unk3)
{
WorldId = worldId;
Unk1 = unk1;
ZoneId = zoneId;
MapId = mapId;
ZoneType = zoneType;
Seed = seed;
Args = args;
SizeX = sizeX;
SizeY = sizeY;
Unk2 = unk2;
AreaIndex = areaIndex;
SubArea = subArea;
Unk3 = unk3;
}
// 重写 ToString 方法(可选)
public override string ToString()
{
return $"WorldId: {WorldId}, ZoneId: {ZoneId}, MapId: {MapId}, SizeX: {SizeX}, SizeY: {SizeY}";
}
}
public struct WarpInfo
{
public uint unk1;
public uint zone_id;
public uint door_id;
public uint dest_zone;
public uint backdoor_id;
}
public struct LoadLevelThing3
{
public uint Unk1;
public uint Unk2;
}
public struct LoadLevelThing4
{
public uint Unk1;
public uint Unk2;
public uint Unk3;
public uint Unk4;
public uint Unk5;
public uint Unk6;
public uint Unk7;
public uint Unk8;
public uint Unk9;
public uint Unk10;
public uint Unk11;
public uint Unk12;
public uint Unk13;
public uint Unk14;
public uint Unk15;
public uint Unk16;
public uint Unk17;
public uint Unk18;
public uint Unk19;
public uint Unk20;
public uint Unk21;
public uint Unk22;
public uint Unk23;
public uint Unk24;
public uint Unk25;
public uint Unk26;
public uint Unk27;
public uint Unk28;
public uint Unk29;
public uint Unk30;
public uint Unk31;
public uint Unk32;
public uint Unk33;
public uint Unk34;
}
public struct LoadLevelThing6
{
public uint Unk1;
public uint Unk2;
public uint Unk3;
public uint Unk4;
public uint Unk5;
public uint Unk6;
public uint Unk7;
public uint Unk8;
public uint Unk9;
public uint Unk10;
public uint Unk11;
public uint Unk12;
public uint Unk13;
public uint Unk14;
public uint Unk15;
public uint Unk16;
public uint Unk17;
public uint Unk18;
public uint Unk19;
public uint Unk20;
public uint Unk21;
public uint Unk22;
public uint Unk23;
public uint Unk24;
public uint Unk25;
public uint Unk26;
public uint Unk27;
public uint Unk28;
public uint Unk29;
public uint Unk30;
public uint Unk31;
public uint Unk32;
public uint Unk33;
public uint Unk34;
public uint Unk35;
public uint Unk36;
public uint Unk37;
public uint Unk38;
public uint Unk39;
public uint Unk40;
}
public struct LoadLevelThing5
{
public uint Unk1;
public uint Unk2;
public uint Unk3;
public uint Unk4;
public uint Unk5;
public uint Unk6;
public uint Unk7;
public uint Unk8;
public uint Unk9;
public uint Unk10;
public uint Unk11;
public uint Unk12;
public uint Unk13;
public uint Unk14;
public uint Unk15;
public uint Unk16;
public uint Unk17;
public uint Unk18;
public uint Unk19;
public uint Unk20;
public uint Unk21;
public uint Unk22;
public uint Unk23;
public uint Unk24;
public uint Unk25;
public uint Unk26;
public uint Unk27;
public uint Unk28;
public uint Unk29;
public uint Unk30;
public uint Unk31;
public uint Unk32;
public uint Unk33;
public uint Unk34;
public uint Unk35;
public uint Unk36;
public uint Unk37;
public uint Unk38;
public uint Unk39;
public uint Unk40;
public uint Unk41;
public uint Unk42;
public uint Unk43;
public uint Unk44;
public uint Unk45;
public uint Unk46;
public uint Unk47;
public uint Unk48;
public uint Unk49;
public uint Unk50;
public uint Unk51;
public uint Unk52;
public uint Unk53;
public uint Unk54;
public uint Unk55;
public uint Unk56;
}
public struct LoadLevelThing7
{
public uint Unk1;
public uint Unk2;
public uint Unk3;
public uint Unk4;
public uint Unk5;
public uint Unk6;
public uint Unk7;
public uint Unk8;
public uint Unk9;
public uint Unk10;
public uint Unk11;
public uint Unk12;
public uint Unk13;
public uint Unk14;
public uint Unk15;
public uint Unk16;
public uint Unk17;
public uint Unk18;
public uint Unk19;
public uint Unk20;
public uint Unk21;
public uint Unk22;
public uint Unk23;
public uint Unk24;
public uint Unk25;
public uint Unk26;
public uint Unk27;
public uint Unk28;
public uint Unk29;
public uint Unk30;
public uint Unk31;
public uint Unk32;
public uint Unk33;
public uint Unk34;
public uint Unk35;
public uint Unk36;
public uint Unk37;
public uint Unk38;
public uint Unk39;
public uint Unk40;
public uint Unk41;
public uint Unk42;
public uint Unk43;
public uint Unk44;
public uint Unk45;
public uint Unk46;
public uint Unk47;
public uint Unk48;
public uint Unk49;
public uint Unk50;
public uint Unk51;
public uint Unk52;
public uint Unk53;
public uint Unk54;
public uint Unk55;
public uint Unk56;
public uint Unk57;
public uint Unk58;
public uint Unk59;
public uint Unk60;
}
public struct LoadLevelThing8
{
public uint Unk1;
public uint Unk2;
public uint Unk3;
public uint Unk4;
public uint Unk5;
public uint Unk6;
public uint Unk7;
public uint Unk8;
public uint Unk9;
public uint Unk10;
public uint Unk11;
public uint Unk12;
public uint Unk13;
public uint Unk14;
public uint Unk15;
public uint Unk16;
public uint Unk17;
public uint Unk18;
public uint Unk19;
public uint Unk20;
public uint Unk21;
public uint Unk22;
public uint Unk23;
public uint Unk24;
public uint Unk25;
public uint Unk26;
public uint Unk27;
public uint Unk28;
public uint Unk29;
public uint Unk30;
public uint Unk31;
public uint Unk32;
public uint Unk33;
public uint Unk34;
public uint Unk35;
public uint Unk36;
public uint Unk37;
public uint Unk38;
public uint Unk39;
public uint Unk40;
public uint Unk41;
}
public struct LoadLevelThing9
{
public uint Unk1;
public uint Unk2;
}
public struct LoadLevelThing10
{
public uint Unk1;
public uint Unk2;
public uint Unk3;
public uint Unk4;
public uint Unk5;
public uint Unk6;
public uint Unk7;
public uint Unk8;
public uint Unk9;
public uint Unk10;
public uint Unk11;
public uint Unk12;
public uint Unk13;
}
public struct UnkThing1
{
public uint Unk1;
public uint Unk2;
public uint Unk3;
public uint Unk4;
public uint Unk5;
public uint Unk6;
public uint Unk7;
public uint Unk8;
public uint Unk9;
public uint Unk10;
}
public struct UnkThing2
{
public uint Unk1;
public uint Unk2;
}
}