暂存 角色正常读取

This commit is contained in:
Longfeng Qin 2024-09-20 11:48:27 +08:00
parent fd55de15b2
commit b25486bb46
21 changed files with 160 additions and 159 deletions

View File

@ -704,7 +704,7 @@ namespace PSO2SERVER
var fakeChar = new Character
{
CharacterId = 12345678 + new Random().Next(),
CharacterID = 12345678 + new Random().Next(),
Player = fakePlayer,
Name = playerName,
Looks = client.Character.Looks,

View File

@ -261,7 +261,7 @@ namespace PSO2SERVER.Models
[Key]
public int Id { get; set; }
public int CharacterId { get; set; }
public int CharacterID { get; set; }
public int player_id { get; set; }
public uint unk1 { get; set; }
public uint voice_type { get; set; }

View File

@ -34,8 +34,6 @@ namespace PSO2SERVER.Models
[StructLayout(LayoutKind.Explicit)]
public struct Items
{
[FieldOffset(0)]
public PSO2ItemNone None;
[FieldOffset(0)]
public PSO2ItemWeapon Weapon;
[FieldOffset(0)]
@ -46,8 +44,10 @@ namespace PSO2SERVER.Models
public PSO2ItemCamo Camo;
[FieldOffset(0)]
public PSO2ItemUnit Unit;
[FieldOffset(0)]
public byte[] Unknown;
//[FieldOffset(0)]
//public byte[] Unknown;
//[FieldOffset(0)]
//public PSO2ItemNone None;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]

View File

@ -1,25 +0,0 @@
using PSO2SERVER.Packets.PSOPackets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSO2SERVER.Packets.Handlers
{
[PacketHandlerAttr(0x03, 0x10)]
public class DoItMaybe : PacketHandler
{
#region implemented abstract members of PacketHandler
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context.User == null || context.Character == null)
return;
context.SendPacket(new LoadingScreenRemovePacket());
}
#endregion
}
}

View File

@ -0,0 +1,45 @@
using PSO2SERVER.Models;
using PSO2SERVER.Packets.PSOPackets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace PSO2SERVER.Packets.Handlers
{
[PacketHandlerAttr(0x03, 0x10)]
public class MapLoaded : PacketHandler
{
[StructLayout(LayoutKind.Sequential)]
public struct MapLoadedPacket
{
/// Loaded zone object.
public ObjectHeader MapObject;
/// Unknown data, 32 bytes.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public byte[] Unk;
// 可选构造函数
public MapLoadedPacket(ObjectHeader mapObject)
{
MapObject = mapObject;
Unk = new byte[0x20];
}
}
#region implemented abstract members of PacketHandler
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context.User == null || context.Character == null)
return;
context.SendPacket(new LoadingScreenRemovePacket());
}
#endregion
}
}

View File

@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace PSO2SERVER.Packets.Handlers
{
[PacketHandlerAttr(0xB, 0x19)]
[PacketHandlerAttr(0x0B, 0x19)]
class QuestDifficultyRequestHandler : PacketHandler
{
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)

View File

@ -4,7 +4,7 @@ using PSO2SERVER.Packets.PSOPackets;
namespace PSO2SERVER.Packets.Handlers
{
[PacketHandlerAttr(0xE, 0xC)]
[PacketHandlerAttr(0x0E, 0x0C)]
class QuestDifficultyStartHandler : PacketHandler
{
// Go go maximum code duplication (for now)

View File

@ -22,19 +22,19 @@ namespace PSO2SERVER.Packets.Handlers
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context.User == null)
return;
var reader = new PacketReader(data, position, size);
var pkt = reader.ReadStruct<CharacterSelectedPacket>();
//Logger.Write("id {0}", charId);
if (context.User == null)
return;
if (context.Character == null) // On character create, this is already set.
{
using (var db = new ServerEf())
{
var character = db.Characters.Where(c => c.CharacterId == pkt.CharId).First();
var character = db.Characters.Where(c => c.CharacterID == pkt.CharId).First();
if (character == null || character.Player.PlayerId != context.User.PlayerId)
{

View File

@ -4,8 +4,6 @@ using PSO2SERVER.Models;
using PSO2SERVER.Packets.PSOPackets;
using PSO2SERVER.Database;
using System.Linq;
using System;
using System.Runtime.InteropServices;
namespace PSO2SERVER.Packets.Handlers
{
@ -20,30 +18,27 @@ namespace PSO2SERVER.Packets.Handlers
return;
PacketWriter w = new PacketWriter();
var reader = new PacketReader(data, position, size);
var info = string.Format("[<--] 接收到的数据 (hex): ");
Logger.WriteHex(info, data);
var setting = reader.ReadStruct<Character.CharParam>();
var name = reader.ReadFixedLengthUtf16(16);//玩家名称 宽字符
var looks = reader.ReadStruct<Character.LooksParam>();
var unk3 = reader.ReadUInt32();
var jobs = reader.ReadStruct<Character.JobParam>();
w.WriteStruct(jobs);
Logger.WriteHex(info, w.ToArray());
//Logger.WriteInternal("[CHR] {0} 创建了名为 {1} 的新角色.", context.User.Username, name);
reader.ReadBytes(12); // 12 unknown bytes
reader.ReadByte(); // VoiceType
reader.ReadBytes(5); // 5 unknown bytes
reader.ReadUInt16(); // VoiceData
var name = reader.ReadFixedLengthUtf16(16);
reader.BaseStream.Seek(0x4, SeekOrigin.Current); // Padding
var looks = reader.ReadStruct<Character.LooksParam>();
var jobs = reader.ReadStruct<Character.JobParam>();
Logger.WriteInternal("[CHR] {0} 创建了名为 {1} 的新角色.", context.User.Username, name);
var newCharacter = new Character
{
unk1 = setting.unk1,
voice_type = setting.voice_type,
unk2 = setting.unk2,
voice_pitch = setting.voice_pitch,
Name = name,
Looks = looks,
unk3 = unk3,
Jobs = jobs,
Looks = looks,
Player = context.User
};
@ -55,16 +50,14 @@ namespace PSO2SERVER.Packets.Handlers
if (existingCharacters.Count > 0)
{
// Increment ID if characters already exist
newCharacter.CharacterId = existingCharacters.Max(c => c.CharacterId) + 1;
newCharacter.CharacterID = existingCharacters.Max(c => c.CharacterID) + 1;
}
else
{
// Start with ID 1 if no characters exist
newCharacter.CharacterId = 1;
newCharacter.CharacterID = 1;
}
newCharacter.player_id = context.User.PlayerId;
//Logger.Write("newCharacter.CharacterId {0} {1}", newCharacter.CharacterId, context.User.PlayerId);
db.Characters.Add(newCharacter);

View File

@ -22,7 +22,7 @@ namespace PSO2SERVER.Packets.Handlers
{
foreach (var character in db.Characters)
if (character.CharacterId == id)
if (character.CharacterID == id)
{
db.Characters.Remove(character);
db.ChangeTracker.DetectChanges();

View File

@ -22,11 +22,11 @@ namespace PSO2SERVER.Packets.Handlers
foreach (var client in ServerApp.Instance.Server.Clients)
{
if (client.Character.CharacterId == id)
if (client.Character.CharacterID == id)
{
var infoPacket = new GuildInfoPacket(context.Character);
context.SendPacket(infoPacket);
Logger.Write("[NFO] Sent guild info to " + client.Character.CharacterId);
Logger.Write("[NFO] Sent guild info to " + client.Character.CharacterID);
break;
}
}

View File

@ -27,35 +27,60 @@ namespace PSO2SERVER.Packets.Handlers
public static void LoadPacketHandlers()
{
var handlers = (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass && t.Namespace == "PSO2SERVER.Packets.Handlers" &&
t.IsSubclassOf(typeof(PacketHandler))
let attrs = (PacketHandlerAttr[])t.GetCustomAttributes(typeof(PacketHandlerAttr), false)
where attrs.Length > 0
select new
{
attrs[0].Type,
attrs[0].Subtype,
HandlerType = t
}).ToList();
// Sort handlers by Type and Subtype
handlers = handlers.OrderBy(h => h.Type).ThenBy(h => h.Subtype).ToList();
foreach (var handler in handlers)
try
{
Logger.WriteInternal("[数据] 数据包 0x{0:X2} - 0x{1:X2} 处理已载入 {2} ."
, handler.Type
, handler.Subtype
, handler.HandlerType.Name
var handlers = (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass && t.Namespace == "PSO2SERVER.Packets.Handlers" &&
t.IsSubclassOf(typeof(PacketHandler))
let attrs = (PacketHandlerAttr[])t.GetCustomAttributes(typeof(PacketHandlerAttr), false)
where attrs.Length > 0
select new
{
attrs[0].Type,
attrs[0].Subtype,
HandlerType = t
}).ToList();
// Sort handlers by Type and Subtype
handlers = handlers.OrderBy(h => h.Type).ThenBy(h => h.Subtype).ToList();
foreach (var handler in handlers)
{
Logger.WriteInternal("[数据] 数据包 0x{0:X2} - 0x{1:X2} 处理已载入 {2}.",
handler.Type,
handler.Subtype,
handler.HandlerType.Name
);
ushort packetTypeUShort = Helper.PacketTypeToUShort(handler.Type, handler.Subtype);
if (!Handlers.ContainsKey(packetTypeUShort))
{
Handlers.Add(packetTypeUShort, (PacketHandler)Activator.CreateInstance(handler.HandlerType));
ushort packetTypeUShort = Helper.PacketTypeToUShort(handler.Type, handler.Subtype);
if (!Handlers.ContainsKey(packetTypeUShort))
{
// Create instance and add to dictionary
var handlerInstance = (PacketHandler)Activator.CreateInstance(handler.HandlerType);
Handlers.Add(packetTypeUShort, handlerInstance);
}
else
{
Logger.WriteInternal("[警告] 数据包 0x{0:X2} - 0x{1:X2} 已存在处理器 {2}.",
handler.Type,
handler.Subtype,
handler.HandlerType.Name
);
}
}
}
catch (ReflectionTypeLoadException ex)
{
// Log the exception details
foreach (var loaderException in ex.LoaderExceptions)
{
Logger.WriteInternal("[错误] 加载类型时出现异常: {0}", loaderException.Message);
}
}
catch (Exception ex)
{
Logger.WriteInternal("[错误] 发生异常: {0}", ex.Message);
}
}
/// <summary>

View File

@ -38,43 +38,36 @@ namespace PSO2SERVER.Packets.PSOPackets
var writer = new PacketWriter();
// Player header
writer.WritePlayerHeader((uint) _character.Player.PlayerId);
writer.WritePlayerHeader((uint)_character.Player.PlayerId);
// Spawn position
writer.Write(Position);
writer.Write((ushort) 0); // padding?
writer.Write((ushort)0); // padding?
writer.WriteFixedLengthASCII("Character", 32);
writer.Write((ushort) 1); // 0x44
writer.Write((ushort) 0); // 0x46
writer.Write((uint) 602); // 0x48
writer.Write((uint) 1); // 0x4C
writer.Write((uint) 53); // 0x50
writer.Write((uint) 0); // 0x54
writer.Write((uint) (IsItMe ? 0x2F : 0x27)); // 0x58
writer.Write((ushort) 0); // 0x5C
writer.Write((ushort) 0); // 0x5E
writer.Write((uint)_character.CharacterId);
writer.Write((uint)_character.player_id);
writer.Write(_character.voice_type);
writer.Write((uint)_character.voice_pitch);
//writer.Write((uint)_character.CharacterId); // player ID copy
//writer.Write((uint)0); // "char array ugggghhhhh" according to PolarisLegacy
//writer.Write((uint)0); // "voiceParam_unknown4"
//writer.Write((uint)0); // "voiceParam_unknown8"
writer.Write((ushort)1); // 0x44
writer.Write((ushort)0); // 0x46
writer.Write((uint)602); // 0x48
writer.Write((uint)1); // 0x4C
writer.Write((uint)53); // 0x50
writer.Write((uint)0); // 0x54
writer.Write((uint)(IsItMe ? 47 : 39)); // 0x58
writer.Write((ushort)559); // 0x5C
writer.Write((ushort)306); // 0x5E
writer.Write((uint)_character.Player.PlayerId); // player ID copy
writer.Write((uint)0); // "char array ugggghhhhh" according to PolarisLegacy
writer.Write((uint)0); // "voiceParam_unknown4"
writer.Write((uint)0); // "voiceParam_unknown8"
writer.WriteFixedLengthUtf16(_character.Name, 16);
writer.Write((uint)0); // 0x90
writer.WriteStruct(_character.Looks);
writer.WriteStruct(_character.Jobs);
writer.WriteFixedLengthUtf16("", 32); // title?
writer.Write((uint) 0); // 0x204
writer.Write((uint) 0); // gmflag?
writer.Write((uint)0); // 0x204
writer.Write((uint)0); // gmflag?
writer.WriteFixedLengthUtf16(_character.Player.Nickname, 16); // nickname, maybe not 16 chars?
for (var i = 0; i < 64; i++)
writer.Write((byte) 0);
writer.Write((byte)0);
return writer.ToArray();
}

View File

@ -3,6 +3,7 @@ using PSO2SERVER.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Contexts;
using System.Text;
@ -26,43 +27,6 @@ namespace PSO2SERVER.Packets.PSOPackets
private int _PlayerId;
/// <summary>
/// Available characters.
/// </summary>
public Character[] Characters { get; set; }
//public Item[][] EquippedItems { get; set; } = new Item[10][];
/// <summary>
/// Character play times.
/// </summary>
public uint[] PlayTimes { get; set; } = new uint[30];
/// <summary>
/// Character deletion flags (flag, deletion timestamp).
/// </summary>
public (uint Flag, uint Timestamp)[] DeletionFlags { get; set; } = new (uint, uint)[30];
/// <summary>
/// Character ship transfer flags.
/// </summary>
public (uint Flag, uint Transfer)[] TransferFlags { get; set; } = new (uint, uint)[30];
/// <summary>
/// Account accessory flag (?).
/// </summary>
public ushort AccountAccessory { get; set; }
/// <summary>
/// Login survey flag.
/// </summary>
public uint LoginSurvey { get; set; }
/// <summary>
/// Ad flag (on global 12 star unit ad).
/// </summary>
public uint Ad { get; set; }
public CharacterListPacket(int PlayerId)
{
_PlayerId = PlayerId;
@ -78,7 +42,7 @@ namespace PSO2SERVER.Packets.PSOPackets
{
var chars = db.Characters
.Where(w => w.Player.PlayerId == _PlayerId)
.OrderBy(o => o.CharacterId) // TODO: Order by last played
.OrderBy(o => o.CharacterID) // TODO: Order by last played
.Select(s => s);
writer.Write((uint)chars.Count()); // Number of characters
@ -88,19 +52,20 @@ namespace PSO2SERVER.Packets.PSOPackets
foreach (var ch in chars)
{
writer.Write(ch.CharacterId);
writer.Write(ch.player_id);
writer.Write(ch.unk1);
writer.Write(ch.voice_type);
writer.Write(ch.unk2);
writer.Write(ch.voice_pitch);
writer.Write((uint)ch.CharacterID);
writer.Write((uint)_PlayerId);
for (var i = 0; i < 0x10; i++)
writer.Write((byte)0);
writer.WriteFixedLengthUtf16(ch.Name, 16);
writer.Write((uint)0);
writer.WriteStruct(ch.Looks);
writer.WriteStruct(ch.Looks); // Note: Pre-Episode 4 created looks doesn't seem to work anymore
writer.WriteStruct(ch.Jobs);
for (var i = 0; i < 0x90; i++)
writer.Write((byte)0);
for (var i = 0; i < 0xFC; i++)
writer.Write((byte)3);
}
}

View File

@ -24,7 +24,7 @@ namespace PSO2SERVER.Packets.PSOPackets
writer.Write((byte) 0);
// Character ID
writer.Write((uint) _character.CharacterId);
writer.Write((uint) _character.CharacterID);
// Padding?
for (var i = 0; i < 4; i++)

View File

@ -162,5 +162,10 @@ namespace PSO2SERVER.Packets
Write(b);
}
}
internal void WriteFixedLengthUtf16(int i, int v)
{
throw new NotImplementedException();
}
}
}

View File

@ -172,7 +172,7 @@
<Compile Include="Object\ObjectManager.cs" />
<Compile Include="Packets\Handlers\03-ServerHandler\03-03-InitialLoad.cs" />
<Compile Include="Packets\Handlers\03-ServerHandler\03-0C-PingResponse.cs" />
<Compile Include="Packets\Handlers\03-ServerHandler\03-10-DoItMaybe.cs" />
<Compile Include="Packets\Handlers\03-ServerHandler\03-10-MapLoaded.cs" />
<Compile Include="Packets\Handlers\03-ServerHandler\03-16-CampshipTeleportDown.cs" />
<Compile Include="Packets\Handlers\03-ServerHandler\03-3B-TeleportCafeToLobby.cs" />
<Compile Include="Packets\Handlers\03-ServerHandler\03-3C-TeleportLobbyToCafe.cs" />

Binary file not shown.

Binary file not shown.

Binary file not shown.