暂存 角色正常读取
This commit is contained in:
parent
fd55de15b2
commit
b25486bb46
@ -704,7 +704,7 @@ namespace PSO2SERVER
|
|||||||
|
|
||||||
var fakeChar = new Character
|
var fakeChar = new Character
|
||||||
{
|
{
|
||||||
CharacterId = 12345678 + new Random().Next(),
|
CharacterID = 12345678 + new Random().Next(),
|
||||||
Player = fakePlayer,
|
Player = fakePlayer,
|
||||||
Name = playerName,
|
Name = playerName,
|
||||||
Looks = client.Character.Looks,
|
Looks = client.Character.Looks,
|
||||||
|
@ -261,7 +261,7 @@ namespace PSO2SERVER.Models
|
|||||||
[Key]
|
[Key]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
public int CharacterId { get; set; }
|
public int CharacterID { get; set; }
|
||||||
public int player_id { get; set; }
|
public int player_id { get; set; }
|
||||||
public uint unk1 { get; set; }
|
public uint unk1 { get; set; }
|
||||||
public uint voice_type { get; set; }
|
public uint voice_type { get; set; }
|
||||||
|
@ -34,8 +34,6 @@ namespace PSO2SERVER.Models
|
|||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct Items
|
public struct Items
|
||||||
{
|
{
|
||||||
[FieldOffset(0)]
|
|
||||||
public PSO2ItemNone None;
|
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public PSO2ItemWeapon Weapon;
|
public PSO2ItemWeapon Weapon;
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
@ -46,8 +44,10 @@ namespace PSO2SERVER.Models
|
|||||||
public PSO2ItemCamo Camo;
|
public PSO2ItemCamo Camo;
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public PSO2ItemUnit Unit;
|
public PSO2ItemUnit Unit;
|
||||||
[FieldOffset(0)]
|
//[FieldOffset(0)]
|
||||||
public byte[] Unknown;
|
//public byte[] Unknown;
|
||||||
|
//[FieldOffset(0)]
|
||||||
|
//public PSO2ItemNone None;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
45
Server/Packets/Handlers/03-ServerHandler/03-10-MapLoaded.cs
Normal file
45
Server/Packets/Handlers/03-ServerHandler/03-10-MapLoaded.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace PSO2SERVER.Packets.Handlers
|
namespace PSO2SERVER.Packets.Handlers
|
||||||
{
|
{
|
||||||
[PacketHandlerAttr(0xB, 0x19)]
|
[PacketHandlerAttr(0x0B, 0x19)]
|
||||||
class QuestDifficultyRequestHandler : PacketHandler
|
class QuestDifficultyRequestHandler : 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)
|
||||||
|
@ -4,7 +4,7 @@ using PSO2SERVER.Packets.PSOPackets;
|
|||||||
|
|
||||||
namespace PSO2SERVER.Packets.Handlers
|
namespace PSO2SERVER.Packets.Handlers
|
||||||
{
|
{
|
||||||
[PacketHandlerAttr(0xE, 0xC)]
|
[PacketHandlerAttr(0x0E, 0x0C)]
|
||||||
class QuestDifficultyStartHandler : PacketHandler
|
class QuestDifficultyStartHandler : PacketHandler
|
||||||
{
|
{
|
||||||
// Go go maximum code duplication (for now)
|
// Go go maximum code duplication (for now)
|
||||||
|
@ -22,19 +22,19 @@ namespace PSO2SERVER.Packets.Handlers
|
|||||||
|
|
||||||
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.User == null)
|
||||||
|
return;
|
||||||
|
|
||||||
var reader = new PacketReader(data, position, size);
|
var reader = new PacketReader(data, position, size);
|
||||||
var pkt = reader.ReadStruct<CharacterSelectedPacket>();
|
var pkt = reader.ReadStruct<CharacterSelectedPacket>();
|
||||||
|
|
||||||
//Logger.Write("id {0}", charId);
|
//Logger.Write("id {0}", charId);
|
||||||
|
|
||||||
if (context.User == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (context.Character == null) // On character create, this is already set.
|
if (context.Character == null) // On character create, this is already set.
|
||||||
{
|
{
|
||||||
using (var db = new ServerEf())
|
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)
|
if (character == null || character.Player.PlayerId != context.User.PlayerId)
|
||||||
{
|
{
|
||||||
|
@ -4,8 +4,6 @@ using PSO2SERVER.Models;
|
|||||||
using PSO2SERVER.Packets.PSOPackets;
|
using PSO2SERVER.Packets.PSOPackets;
|
||||||
using PSO2SERVER.Database;
|
using PSO2SERVER.Database;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace PSO2SERVER.Packets.Handlers
|
namespace PSO2SERVER.Packets.Handlers
|
||||||
{
|
{
|
||||||
@ -20,30 +18,27 @@ namespace PSO2SERVER.Packets.Handlers
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
PacketWriter w = new PacketWriter();
|
|
||||||
|
|
||||||
var reader = new PacketReader(data, position, size);
|
var reader = new PacketReader(data, position, size);
|
||||||
var info = string.Format("[<--] 接收到的数据 (hex): ");
|
var info = string.Format("[<--] 接收到的数据 (hex): ");
|
||||||
Logger.WriteHex(info, data);
|
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
|
var newCharacter = new Character
|
||||||
{
|
{
|
||||||
unk1 = setting.unk1,
|
|
||||||
voice_type = setting.voice_type,
|
|
||||||
unk2 = setting.unk2,
|
|
||||||
voice_pitch = setting.voice_pitch,
|
|
||||||
Name = name,
|
Name = name,
|
||||||
Looks = looks,
|
|
||||||
unk3 = unk3,
|
|
||||||
Jobs = jobs,
|
Jobs = jobs,
|
||||||
|
Looks = looks,
|
||||||
Player = context.User
|
Player = context.User
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,16 +50,14 @@ namespace PSO2SERVER.Packets.Handlers
|
|||||||
if (existingCharacters.Count > 0)
|
if (existingCharacters.Count > 0)
|
||||||
{
|
{
|
||||||
// Increment ID if characters already exist
|
// Increment ID if characters already exist
|
||||||
newCharacter.CharacterId = existingCharacters.Max(c => c.CharacterId) + 1;
|
newCharacter.CharacterID = existingCharacters.Max(c => c.CharacterID) + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Start with ID 1 if no characters exist
|
// 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);
|
//Logger.Write("newCharacter.CharacterId {0} {1}", newCharacter.CharacterId, context.User.PlayerId);
|
||||||
|
|
||||||
db.Characters.Add(newCharacter);
|
db.Characters.Add(newCharacter);
|
||||||
|
@ -22,7 +22,7 @@ namespace PSO2SERVER.Packets.Handlers
|
|||||||
{
|
{
|
||||||
|
|
||||||
foreach (var character in db.Characters)
|
foreach (var character in db.Characters)
|
||||||
if (character.CharacterId == id)
|
if (character.CharacterID == id)
|
||||||
{
|
{
|
||||||
db.Characters.Remove(character);
|
db.Characters.Remove(character);
|
||||||
db.ChangeTracker.DetectChanges();
|
db.ChangeTracker.DetectChanges();
|
||||||
|
@ -22,11 +22,11 @@ namespace PSO2SERVER.Packets.Handlers
|
|||||||
|
|
||||||
foreach (var client in ServerApp.Instance.Server.Clients)
|
foreach (var client in ServerApp.Instance.Server.Clients)
|
||||||
{
|
{
|
||||||
if (client.Character.CharacterId == id)
|
if (client.Character.CharacterID == id)
|
||||||
{
|
{
|
||||||
var infoPacket = new GuildInfoPacket(context.Character);
|
var infoPacket = new GuildInfoPacket(context.Character);
|
||||||
context.SendPacket(infoPacket);
|
context.SendPacket(infoPacket);
|
||||||
Logger.Write("[NFO] Sent guild info to " + client.Character.CharacterId);
|
Logger.Write("[NFO] Sent guild info to " + client.Character.CharacterID);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,35 +27,60 @@ namespace PSO2SERVER.Packets.Handlers
|
|||||||
|
|
||||||
public static void LoadPacketHandlers()
|
public static void LoadPacketHandlers()
|
||||||
{
|
{
|
||||||
var handlers = (from t in Assembly.GetExecutingAssembly().GetTypes()
|
try
|
||||||
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} ."
|
var handlers = (from t in Assembly.GetExecutingAssembly().GetTypes()
|
||||||
, handler.Type
|
where t.IsClass && t.Namespace == "PSO2SERVER.Packets.Handlers" &&
|
||||||
, handler.Subtype
|
t.IsSubclassOf(typeof(PacketHandler))
|
||||||
, handler.HandlerType.Name
|
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);
|
ushort packetTypeUShort = Helper.PacketTypeToUShort(handler.Type, handler.Subtype);
|
||||||
if (!Handlers.ContainsKey(packetTypeUShort))
|
if (!Handlers.ContainsKey(packetTypeUShort))
|
||||||
{
|
{
|
||||||
Handlers.Add(packetTypeUShort, (PacketHandler)Activator.CreateInstance(handler.HandlerType));
|
// 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>
|
/// <summary>
|
||||||
|
@ -38,43 +38,36 @@ namespace PSO2SERVER.Packets.PSOPackets
|
|||||||
var writer = new PacketWriter();
|
var writer = new PacketWriter();
|
||||||
|
|
||||||
// Player header
|
// Player header
|
||||||
writer.WritePlayerHeader((uint) _character.Player.PlayerId);
|
writer.WritePlayerHeader((uint)_character.Player.PlayerId);
|
||||||
|
|
||||||
// Spawn position
|
// Spawn position
|
||||||
writer.Write(Position);
|
writer.Write(Position);
|
||||||
|
|
||||||
writer.Write((ushort) 0); // padding?
|
writer.Write((ushort)0); // padding?
|
||||||
writer.WriteFixedLengthASCII("Character", 32);
|
writer.WriteFixedLengthASCII("Character", 32);
|
||||||
writer.Write((ushort) 1); // 0x44
|
writer.Write((ushort)1); // 0x44
|
||||||
writer.Write((ushort) 0); // 0x46
|
writer.Write((ushort)0); // 0x46
|
||||||
writer.Write((uint) 602); // 0x48
|
writer.Write((uint)602); // 0x48
|
||||||
writer.Write((uint) 1); // 0x4C
|
writer.Write((uint)1); // 0x4C
|
||||||
writer.Write((uint) 53); // 0x50
|
writer.Write((uint)53); // 0x50
|
||||||
writer.Write((uint) 0); // 0x54
|
writer.Write((uint)0); // 0x54
|
||||||
|
writer.Write((uint)(IsItMe ? 47 : 39)); // 0x58
|
||||||
writer.Write((uint) (IsItMe ? 0x2F : 0x27)); // 0x58
|
writer.Write((ushort)559); // 0x5C
|
||||||
writer.Write((ushort) 0); // 0x5C
|
writer.Write((ushort)306); // 0x5E
|
||||||
writer.Write((ushort) 0); // 0x5E
|
writer.Write((uint)_character.Player.PlayerId); // player ID copy
|
||||||
|
writer.Write((uint)0); // "char array ugggghhhhh" according to PolarisLegacy
|
||||||
writer.Write((uint)_character.CharacterId);
|
writer.Write((uint)0); // "voiceParam_unknown4"
|
||||||
writer.Write((uint)_character.player_id);
|
writer.Write((uint)0); // "voiceParam_unknown8"
|
||||||
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.WriteFixedLengthUtf16(_character.Name, 16);
|
writer.WriteFixedLengthUtf16(_character.Name, 16);
|
||||||
writer.Write((uint)0); // 0x90
|
writer.Write((uint)0); // 0x90
|
||||||
writer.WriteStruct(_character.Looks);
|
writer.WriteStruct(_character.Looks);
|
||||||
writer.WriteStruct(_character.Jobs);
|
writer.WriteStruct(_character.Jobs);
|
||||||
writer.WriteFixedLengthUtf16("", 32); // title?
|
writer.WriteFixedLengthUtf16("", 32); // title?
|
||||||
|
writer.Write((uint)0); // 0x204
|
||||||
writer.Write((uint) 0); // 0x204
|
writer.Write((uint)0); // gmflag?
|
||||||
writer.Write((uint) 0); // gmflag?
|
|
||||||
writer.WriteFixedLengthUtf16(_character.Player.Nickname, 16); // nickname, maybe not 16 chars?
|
writer.WriteFixedLengthUtf16(_character.Player.Nickname, 16); // nickname, maybe not 16 chars?
|
||||||
for (var i = 0; i < 64; i++)
|
for (var i = 0; i < 64; i++)
|
||||||
writer.Write((byte) 0);
|
writer.Write((byte)0);
|
||||||
|
|
||||||
return writer.ToArray();
|
return writer.ToArray();
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ using PSO2SERVER.Models;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Remoting.Contexts;
|
using System.Runtime.Remoting.Contexts;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@ -26,43 +27,6 @@ namespace PSO2SERVER.Packets.PSOPackets
|
|||||||
|
|
||||||
private int _PlayerId;
|
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)
|
public CharacterListPacket(int PlayerId)
|
||||||
{
|
{
|
||||||
_PlayerId = PlayerId;
|
_PlayerId = PlayerId;
|
||||||
@ -78,7 +42,7 @@ namespace PSO2SERVER.Packets.PSOPackets
|
|||||||
{
|
{
|
||||||
var chars = db.Characters
|
var chars = db.Characters
|
||||||
.Where(w => w.Player.PlayerId == _PlayerId)
|
.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);
|
.Select(s => s);
|
||||||
|
|
||||||
writer.Write((uint)chars.Count()); // Number of characters
|
writer.Write((uint)chars.Count()); // Number of characters
|
||||||
@ -88,19 +52,20 @@ namespace PSO2SERVER.Packets.PSOPackets
|
|||||||
|
|
||||||
foreach (var ch in chars)
|
foreach (var ch in chars)
|
||||||
{
|
{
|
||||||
writer.Write(ch.CharacterId);
|
writer.Write((uint)ch.CharacterID);
|
||||||
writer.Write(ch.player_id);
|
writer.Write((uint)_PlayerId);
|
||||||
writer.Write(ch.unk1);
|
|
||||||
writer.Write(ch.voice_type);
|
for (var i = 0; i < 0x10; i++)
|
||||||
writer.Write(ch.unk2);
|
writer.Write((byte)0);
|
||||||
writer.Write(ch.voice_pitch);
|
|
||||||
writer.WriteFixedLengthUtf16(ch.Name, 16);
|
writer.WriteFixedLengthUtf16(ch.Name, 16);
|
||||||
writer.Write((uint)0);
|
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);
|
writer.WriteStruct(ch.Jobs);
|
||||||
|
|
||||||
for (var i = 0; i < 0x90; i++)
|
for (var i = 0; i < 0xFC; i++)
|
||||||
writer.Write((byte)0);
|
writer.Write((byte)3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ namespace PSO2SERVER.Packets.PSOPackets
|
|||||||
writer.Write((byte) 0);
|
writer.Write((byte) 0);
|
||||||
|
|
||||||
// Character ID
|
// Character ID
|
||||||
writer.Write((uint) _character.CharacterId);
|
writer.Write((uint) _character.CharacterID);
|
||||||
|
|
||||||
// Padding?
|
// Padding?
|
||||||
for (var i = 0; i < 4; i++)
|
for (var i = 0; i < 4; i++)
|
||||||
|
@ -162,5 +162,10 @@ namespace PSO2SERVER.Packets
|
|||||||
Write(b);
|
Write(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void WriteFixedLengthUtf16(int i, int v)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -172,7 +172,7 @@
|
|||||||
<Compile Include="Object\ObjectManager.cs" />
|
<Compile Include="Object\ObjectManager.cs" />
|
||||||
<Compile Include="Packets\Handlers\03-ServerHandler\03-03-InitialLoad.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-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-16-CampshipTeleportDown.cs" />
|
||||||
<Compile Include="Packets\Handlers\03-ServerHandler\03-3B-TeleportCafeToLobby.cs" />
|
<Compile Include="Packets\Handlers\03-ServerHandler\03-3B-TeleportCafeToLobby.cs" />
|
||||||
<Compile Include="Packets\Handlers\03-ServerHandler\03-3C-TeleportLobbyToCafe.cs" />
|
<Compile Include="Packets\Handlers\03-ServerHandler\03-3C-TeleportLobbyToCafe.cs" />
|
||||||
|
BIN
数据对比/角色/extra.bin
Normal file
BIN
数据对比/角色/extra.bin
Normal file
Binary file not shown.
Binary file not shown.
BIN
数据对比/角色/job-2-人类-猎人.bin
Normal file
BIN
数据对比/角色/job-2-人类-猎人.bin
Normal file
Binary file not shown.
BIN
数据对比/角色/look-2-人类-猎人.bin
Normal file
BIN
数据对比/角色/look-2-人类-猎人.bin
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user