修正角色数据读取位置
新增几个数据包
This commit is contained in:
parent
a0c9a9651a
commit
9368309049
@ -17,6 +17,43 @@ namespace PSO2SERVER
|
||||
{
|
||||
public class Client
|
||||
{
|
||||
public Client()
|
||||
{
|
||||
IsClosed = false;
|
||||
|
||||
_readBuffer = new byte[1024 * 64];
|
||||
_readBufferSize = 0;
|
||||
|
||||
InputArc4 = null;
|
||||
OutputArc4 = null;
|
||||
|
||||
Palette = new PSOPalette();
|
||||
battle_stats = new PlayerStats();
|
||||
|
||||
SendPacket(new ServerHelloPacket(0x03, 100, 68833280));
|
||||
}
|
||||
|
||||
public Client(Server server, SocketClient socket)
|
||||
{
|
||||
IsClosed = false;
|
||||
_server = server;
|
||||
Socket = socket;
|
||||
|
||||
socket.DataReceived += HandleDataReceived;
|
||||
socket.ConnectionLost += HandleConnectionLost;
|
||||
|
||||
_readBuffer = new byte[1024 * 64];
|
||||
_readBufferSize = 0;
|
||||
|
||||
InputArc4 = null;
|
||||
OutputArc4 = null;
|
||||
|
||||
Palette = new PSOPalette();
|
||||
battle_stats = new PlayerStats();
|
||||
|
||||
SendPacket(new ServerHelloPacket(0x03, 100, 68833280));
|
||||
}
|
||||
|
||||
public enum PacketType : byte
|
||||
{
|
||||
/// NGS packet.
|
||||
@ -40,24 +77,6 @@ namespace PSO2SERVER
|
||||
//private int _packetId;
|
||||
private uint _readBufferSize;
|
||||
|
||||
public Client(Server server, SocketClient socket)
|
||||
{
|
||||
IsClosed = false;
|
||||
_server = server;
|
||||
Socket = socket;
|
||||
|
||||
socket.DataReceived += HandleDataReceived;
|
||||
socket.ConnectionLost += HandleConnectionLost;
|
||||
|
||||
_readBuffer = new byte[1024 * 64];
|
||||
_readBufferSize = 0;
|
||||
|
||||
InputArc4 = null;
|
||||
OutputArc4 = null;
|
||||
|
||||
SendPacket(new ServerHelloPacket(0x03, 100, 68833280));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Server
|
||||
/// </summary>
|
||||
@ -72,8 +91,9 @@ namespace PSO2SERVER
|
||||
public Character Character { get; set; }
|
||||
public uint MovementTimestamp { get; internal set; }
|
||||
public Flags _flags { get; set; }
|
||||
public PSOPalette Palette { get; set; } = new PSOPalette();
|
||||
public PlayerStats battle_stats { get; set; } = new PlayerStats();
|
||||
public PSOPalette Palette { get; set; }
|
||||
public PlayerStats battle_stats { get; set; }
|
||||
public UserState UserState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Party
|
||||
|
@ -711,8 +711,13 @@ namespace PSO2SERVER
|
||||
Jobs = client.Character.Jobs
|
||||
};
|
||||
|
||||
var fakeclient = new Client
|
||||
{
|
||||
_account = fakePlayer,
|
||||
Character = fakeChar,
|
||||
};
|
||||
|
||||
var fakePacket = new CharacterSpawnPacket(fakeChar, new PSOLocation(0f, 1f, 0f, 0f, x, y, z), false, false)
|
||||
var fakePacket = new CharacterSpawnPacket(fakeclient, new PSOLocation(0f, 1f, 0f, 0f, x, y, z), false, false)
|
||||
{
|
||||
};
|
||||
client.SendPacket(fakePacket);
|
||||
|
@ -32,8 +32,7 @@ namespace PSO2SERVER.Models
|
||||
|
||||
public enum ClassType : byte
|
||||
{
|
||||
Unknown = 0xFF,
|
||||
Hunter = 0,
|
||||
Hunter,
|
||||
Ranger,
|
||||
Force,
|
||||
Fighter,
|
||||
@ -48,6 +47,8 @@ namespace PSO2SERVER.Models
|
||||
Phantom,
|
||||
Etole,
|
||||
Luster,
|
||||
|
||||
Unknown = 0xFF,
|
||||
}
|
||||
|
||||
// 每个枚举成员的值是通过位移操作计算的:
|
||||
|
@ -18,6 +18,8 @@ namespace PSO2SERVER.Models
|
||||
private List<byte> flags = new List<byte>();
|
||||
private List<uint> paramsList = new List<uint>();
|
||||
|
||||
public Flags() { flags = new List<byte>(); paramsList = new List<uint>(); }
|
||||
|
||||
public void Set(int id, byte val)
|
||||
{
|
||||
int index = id / 8;
|
||||
|
@ -149,7 +149,12 @@ namespace PSO2SERVER.Models
|
||||
public FixedList<SubPalette> Subpalettes { get; set; } = new FixedList<SubPalette>(6, new SubPalette());
|
||||
public List<uint> DefaultPas { get; set; } = new List<uint>();
|
||||
|
||||
public PSOPalette() { }
|
||||
public PSOPalette()
|
||||
{
|
||||
Palettes = new FixedList<WeaponPalette>(6, new WeaponPalette());
|
||||
Subpalettes = new FixedList<SubPalette>(6, new SubPalette());
|
||||
DefaultPas = new List<uint>();
|
||||
}
|
||||
|
||||
public void ReadFromStream(PacketReader reader)
|
||||
{
|
||||
|
@ -238,4 +238,53 @@ namespace PSO2SERVER.Models
|
||||
Pad2 = pad2 ?? new byte[3]; // 默认值为3字节数组
|
||||
}
|
||||
}
|
||||
|
||||
public enum UserState
|
||||
{
|
||||
LoggingIn, // User is logging in, nothing is set up.
|
||||
NewUsername, // User is logged in, but no username was set, only user id is set.
|
||||
CharacterSelect, // User is logged in, account stuff is set up, but no character info.
|
||||
PreInGame, // User has selected the character, but map and party aren't set up yet.
|
||||
InGame // User is in the game, character, map, party are set up.
|
||||
}
|
||||
|
||||
public static class UserStateExtensions
|
||||
{
|
||||
// 处理不同状态的逻辑
|
||||
public static string GetStateMessage(this UserState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case UserState.LoggingIn:
|
||||
return "User is logging in...";
|
||||
case UserState.NewUsername:
|
||||
return "User needs to set a username.";
|
||||
case UserState.CharacterSelect:
|
||||
return "User is selecting a character.";
|
||||
case UserState.PreInGame:
|
||||
return "User is preparing to enter the game.";
|
||||
case UserState.InGame:
|
||||
return "User is in the game!";
|
||||
default:
|
||||
return "Unknown state.";
|
||||
}
|
||||
}
|
||||
|
||||
// 比较两个状态,判断当前状态是否在另一个状态之前
|
||||
public static bool IsBefore(this UserState currentState, UserState otherState)
|
||||
{
|
||||
return currentState < otherState;
|
||||
}
|
||||
|
||||
// 比较两个状态,判断当前状态是否在另一个状态之后
|
||||
public static bool IsAfter(this UserState currentState, UserState otherState)
|
||||
{
|
||||
return currentState > otherState;
|
||||
}
|
||||
|
||||
public static void ToLogger(this UserState state)
|
||||
{
|
||||
Logger.Write(GetStateMessage(state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,15 @@ namespace PSO2SERVER.Network
|
||||
private readonly SocketServer _server;
|
||||
private int _writePosition = 0;
|
||||
|
||||
public SocketClient()
|
||||
{
|
||||
_server = new SocketServer(0);
|
||||
Socket = new TcpClient();
|
||||
|
||||
_readBuffer = new byte[1024 * 16];
|
||||
_writeBuffer = new byte[1024 * 1024]; // too high? too low? not sure
|
||||
}
|
||||
|
||||
public SocketClient(SocketServer server, TcpClient socket)
|
||||
{
|
||||
_server = server;
|
||||
|
@ -10,14 +10,6 @@ namespace PSO2SERVER.Party
|
||||
{
|
||||
public class Party
|
||||
{
|
||||
public enum PartyColor : byte
|
||||
{
|
||||
Red,
|
||||
Green,
|
||||
Yellow,
|
||||
Blue,
|
||||
}
|
||||
|
||||
public string name;
|
||||
private List<Client> members;
|
||||
private Client host;
|
||||
@ -25,28 +17,28 @@ namespace PSO2SERVER.Party
|
||||
public PartySettingsPacket partySetting;
|
||||
public string questname;
|
||||
|
||||
public Party(string name, Client host)
|
||||
public Party(string name, Client Leader)
|
||||
{
|
||||
this.name = name;
|
||||
this.host = host;
|
||||
this.host = Leader;
|
||||
members = new List<Client>();
|
||||
currentQuest = new PartyQuest();
|
||||
partySetting = new PartySettingsPacket();
|
||||
questname = string.Empty;
|
||||
addClientToParty(host);
|
||||
addClientToParty(Leader);
|
||||
}
|
||||
|
||||
public void addClientToParty(Client c)
|
||||
{
|
||||
members.Add(c);
|
||||
if (members.Count < 1)
|
||||
{
|
||||
c.SendPacket(new PartyInitPacket(new Character[1] { c.Character }));
|
||||
c.SendPacket(new PartyInitPacket(members));
|
||||
}
|
||||
else
|
||||
{
|
||||
// ???
|
||||
}
|
||||
members.Add(c);
|
||||
c.currentParty = this;
|
||||
}
|
||||
|
||||
@ -83,6 +75,78 @@ namespace PSO2SERVER.Party
|
||||
}
|
||||
}
|
||||
|
||||
public enum PartyColor : byte
|
||||
{
|
||||
Red,
|
||||
Green,
|
||||
Yellow,
|
||||
Blue,
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public unsafe struct PartyEntry
|
||||
{
|
||||
/// 玩家对象的头部信息(包含ID、类型、区域ID等)。
|
||||
public ObjectHeader id;
|
||||
|
||||
/// 玩家昵称。
|
||||
public string nickname;
|
||||
|
||||
/// 玩家角色名称。
|
||||
public string char_name;
|
||||
|
||||
/// 主职业的等级。
|
||||
public byte level;
|
||||
|
||||
/// 副职业的等级。
|
||||
public byte sublevel;
|
||||
|
||||
/// 玩家主职业类型(`ClassType` 枚举类型)。
|
||||
public ClassType mainClass;
|
||||
|
||||
/// 玩家副职业类型(`ClassType` 枚举类型)。
|
||||
public ClassType subClass;
|
||||
|
||||
/// 玩家在队伍中的颜色标识。
|
||||
public PartyColor color;
|
||||
|
||||
/// 7字节的未知数据(通常是填充或者未定义用途)。
|
||||
public fixed byte unk1[7];
|
||||
|
||||
/// 一个未知的 uint 类型数据,具体用途不明。
|
||||
public uint unk2;
|
||||
|
||||
/// 玩家HP(体力)的三个数值。具体原因为什么有三个值目前不明。
|
||||
public fixed uint hp[3];
|
||||
|
||||
/// 玩家所在的地图ID。
|
||||
public ushort mapid;
|
||||
|
||||
/// 另一个未知的 ushort 类型数据。
|
||||
public ushort unk3;
|
||||
|
||||
/// 12字节的未知数据。
|
||||
public fixed byte unk4[0x0C];
|
||||
|
||||
/// 3个未知的 uint 数组数据。
|
||||
public fixed uint unk5[0x03];
|
||||
|
||||
/// 未知的字符串,可能是其他信息(如玩家状态或其他描述信息)。
|
||||
public string unk6;
|
||||
|
||||
// PSO VITA(PlayStation Vita)相关字段,已注释掉,可能与Vita版本相关。
|
||||
public string unk10;
|
||||
|
||||
// 玩家角色的 ASCII 字符串相关数据,已注释掉。
|
||||
public string unk7; // ASCII 字符串
|
||||
|
||||
// 玩家语言设置(`ShortLanguage` 枚举类型),已注释掉。
|
||||
public ShortLanguage lang;
|
||||
|
||||
// 3字节的未知数据,已注释掉。
|
||||
public fixed byte unk9[3];
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public unsafe struct PartyInfo
|
||||
{
|
||||
|
23
Server/Protocol/Handlers/07-ChatHandler/07-37-UNK.cs
Normal file
23
Server/Protocol/Handlers/07-ChatHandler/07-37-UNK.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using PSO2SERVER.Models;
|
||||
using PSO2SERVER.Protocol.Packets;
|
||||
|
||||
namespace PSO2SERVER.Protocol.Handlers
|
||||
{
|
||||
[PacketHandlerAttr(0x07, 0x37)]
|
||||
public class _07_37_UNK : PacketHandler
|
||||
{
|
||||
public uint unk { get; set; } = 0;
|
||||
|
||||
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
|
||||
{
|
||||
var info = string.Format("[<--] 接收到的数据 (hex): {0} 字节", data.Length);
|
||||
Logger.WriteHex(info, data);
|
||||
|
||||
var reader = new PacketReader(data, position, size);
|
||||
unk = reader.ReadUInt32();
|
||||
|
||||
Logger.WriteObj(unk);
|
||||
}
|
||||
}
|
||||
}
|
@ -38,7 +38,7 @@ namespace PSO2SERVER.Protocol.Handlers
|
||||
{
|
||||
var character = db.Characters.FirstOrDefault(c => c.CharacterID == charId && c.AccountID == context._account.AccountId);
|
||||
|
||||
if (character == null || character.Account == null || character.Account.AccountId != context._account.AccountId)
|
||||
if (character == null)
|
||||
{
|
||||
Logger.WriteError("数据库中未找到 {0} 角色ID {1} ({2})"
|
||||
, context._account.Username
|
||||
|
@ -94,7 +94,7 @@ namespace PSO2SERVER.Protocol.Handlers
|
||||
using (var db = new ServerEf())
|
||||
{
|
||||
// Check if any characters exist for this player
|
||||
var existingCharacters = db.Characters.Where(c => c.Account.AccountId == context._account.AccountId).ToList();
|
||||
var existingCharacters = db.Characters.Where(c => c.AccountID == context._account.AccountId).ToList();
|
||||
if (existingCharacters.Count > 0)
|
||||
{
|
||||
// Increment ID if characters already exist
|
||||
|
@ -24,7 +24,7 @@ namespace PSO2SERVER.Protocol.Handlers
|
||||
{
|
||||
if (client.Character.CharacterID == id)
|
||||
{
|
||||
var infoPacket = new GuildInfoPacket(context.Character);
|
||||
var infoPacket = new GuildInfoPacket(context);
|
||||
context.SendPacket(infoPacket);
|
||||
Logger.Write("[NFO] Sent guild info to " + client.Character.CharacterID);
|
||||
break;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using MySqlX.XDevAPI;
|
||||
using Newtonsoft.Json;
|
||||
using PSO2SERVER.Database;
|
||||
using PSO2SERVER.Models;
|
||||
using PSO2SERVER.Zone;
|
||||
@ -58,22 +59,26 @@ namespace PSO2SERVER.Protocol.Packets
|
||||
//#[SeekAfter(0x60)]
|
||||
public byte[] Unk12 { get; set; } = new byte[0x40];
|
||||
|
||||
public readonly Client _client;
|
||||
|
||||
public CharacterSpawnPacket()
|
||||
{
|
||||
}
|
||||
|
||||
public CharacterSpawnPacket(Character character, PSOLocation locatiion)
|
||||
public CharacterSpawnPacket(Client c, PSOLocation locatiion)
|
||||
{
|
||||
ObjHeader = new ObjectHeader((uint)character.Account.AccountId, ObjectType.Player);
|
||||
_client = c;
|
||||
ObjHeader = new ObjectHeader((uint)c._account.AccountId, ObjectType.Player);
|
||||
ObjPosition = locatiion;
|
||||
Character = character;
|
||||
Character = c.Character;
|
||||
}
|
||||
|
||||
public CharacterSpawnPacket(Character character, PSOLocation locatiion, bool isme, bool isgm)
|
||||
public CharacterSpawnPacket(Client c, PSOLocation locatiion, bool isme, bool isgm)
|
||||
{
|
||||
ObjHeader = new ObjectHeader((uint)character.Account.AccountId, ObjectType.Player);
|
||||
_client = c;
|
||||
ObjHeader = new ObjectHeader((uint)c._account.AccountId, ObjectType.Player);
|
||||
ObjPosition = locatiion;
|
||||
Character = character;
|
||||
Character = c.Character;
|
||||
SpawnType = isme ? CharacterSpawnType.Myself : CharacterSpawnType.Other;
|
||||
GmFlag = isgm ? (uint)1 : 0;
|
||||
}
|
||||
@ -102,7 +107,7 @@ namespace PSO2SERVER.Protocol.Packets
|
||||
pkt.Write(Character.BuildCharacterByteArray());
|
||||
pkt.Write(Unk11);
|
||||
pkt.Write(GmFlag);
|
||||
pkt.WriteFixedLengthUtf16(Character.Account.Nickname, 0x10);
|
||||
pkt.WriteFixedLengthUtf16(_client._account.Nickname, 0x10);
|
||||
pkt.BaseStream.Seek(0x60, SeekOrigin.Current);
|
||||
pkt.Write(Unk12);
|
||||
|
||||
|
@ -1,75 +1,12 @@
|
||||
using PSO2SERVER.Database;
|
||||
using PSO2SERVER.Models;
|
||||
using static PSO2SERVER.Models.CharacterStruct;
|
||||
using static PSO2SERVER.Party.Party;
|
||||
using PSO2SERVER.Party;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PSO2SERVER.Protocol.Packets
|
||||
{
|
||||
class PartyInitPacket : Packet
|
||||
public class PartyInitPacket : Packet
|
||||
{
|
||||
public unsafe struct PartyEntry
|
||||
{
|
||||
/// 玩家对象的头部信息(包含ID、类型、区域ID等)。
|
||||
public ObjectHeader id;
|
||||
|
||||
/// 玩家昵称。
|
||||
public string nickname;
|
||||
|
||||
/// 玩家角色名称。
|
||||
public string char_name;
|
||||
|
||||
/// 主职业的等级。
|
||||
public byte level;
|
||||
|
||||
/// 副职业的等级。
|
||||
public byte sublevel;
|
||||
|
||||
/// 玩家主职业类型(`ClassType` 枚举类型)。
|
||||
public ClassType mainClass;
|
||||
|
||||
/// 玩家副职业类型(`ClassType` 枚举类型)。
|
||||
public ClassType subClass;
|
||||
|
||||
/// 玩家在队伍中的颜色标识。
|
||||
public PartyColor color;
|
||||
|
||||
/// 7字节的未知数据(通常是填充或者未定义用途)。
|
||||
public fixed byte unk1[7];
|
||||
|
||||
/// 一个未知的 uint 类型数据,具体用途不明。
|
||||
public uint unk2;
|
||||
|
||||
/// 玩家HP(体力)的三个数值。具体原因为什么有三个值目前不明。
|
||||
public fixed uint hp[3];
|
||||
|
||||
/// 玩家所在的地图ID。
|
||||
public ushort mapid;
|
||||
|
||||
/// 另一个未知的 ushort 类型数据。
|
||||
public ushort unk3;
|
||||
|
||||
/// 12字节的未知数据。
|
||||
public fixed byte unk4[0x0C];
|
||||
|
||||
/// 3个未知的 uint 数组数据。
|
||||
public fixed uint unk5[3];
|
||||
|
||||
/// 未知的字符串,可能是其他信息(如玩家状态或其他描述信息)。
|
||||
public string unk6;
|
||||
|
||||
/// PSO VITA(PlayStation Vita)相关字段,已注释掉,可能与Vita版本相关。
|
||||
/// public string unk10;
|
||||
|
||||
/// 玩家角色的 ASCII 字符串相关数据,已注释掉。
|
||||
/// public AsciiString unk7; // ASCII 字符串
|
||||
|
||||
/// 玩家语言设置(`ShortLanguage` 枚举类型),已注释掉。
|
||||
/// public ShortLanguage lang;
|
||||
|
||||
/// 3字节的未知数据,已注释掉。
|
||||
/// public fixed byte unk9[3];
|
||||
}
|
||||
|
||||
/// 队伍实例.
|
||||
private ObjectHeader party_object;
|
||||
/// 队伍队长实例.
|
||||
@ -81,37 +18,39 @@ namespace PSO2SERVER.Protocol.Packets
|
||||
/// <summary>
|
||||
/// 未知
|
||||
/// </summary>
|
||||
private string unk2 = "";
|
||||
private string unk2 = string.Empty;
|
||||
|
||||
private Character[] players;
|
||||
public PartyInitPacket(Character[] players)
|
||||
private List<Client> Clients = new List<Client>();
|
||||
public PartyInitPacket(List<Client> clients)
|
||||
{
|
||||
this.players = players;
|
||||
party_object = new ObjectHeader((uint)players[0].Account.AccountId, ObjectType.Party);
|
||||
leader = new ObjectHeader((uint)players[0].Account.AccountId, ObjectType.Player);
|
||||
people_amount = (uint)players.Length;
|
||||
this.Clients = clients;
|
||||
|
||||
party_object = new ObjectHeader((uint)clients[0]._account.AccountId, ObjectType.Party);
|
||||
leader = new ObjectHeader((uint)clients[0]._account.AccountId, ObjectType.Player);
|
||||
people_amount = (uint)Clients.Count;
|
||||
|
||||
// 队伍结构数据
|
||||
for (int i = 0; i < players.Length; i++)
|
||||
for (int i = 0; i < Clients.Count; i++)
|
||||
{
|
||||
entries[i].id = new ObjectHeader((uint)players[i].Account.AccountId, ObjectType.Player); // player of player
|
||||
entries[i].nickname = players[i].Account.Nickname;
|
||||
entries[i].char_name = players[i].Name;
|
||||
entries[i].level = (byte)players[i].Jobs.entries.hunter.level;
|
||||
entries[i].sublevel = (byte)players[i].Jobs.entries.hunter.level2;
|
||||
entries[i].mainClass = players[i].Jobs.mainClass;
|
||||
entries[i].subClass = players[i].Jobs.subClass;
|
||||
entries[i].id = new ObjectHeader((uint)Clients[i]._account.AccountId, ObjectType.Player); // player of player
|
||||
entries[i].nickname = Clients[i]._account.Nickname;
|
||||
var character = Clients[i].Character;
|
||||
entries[i].char_name = character.Name;
|
||||
entries[i].level = (byte)character.Jobs.entries.hunter.level;
|
||||
entries[i].sublevel = (byte)character.Jobs.entries.hunter.level2;
|
||||
entries[i].mainClass = character.Jobs.mainClass;
|
||||
entries[i].subClass = character.Jobs.subClass;
|
||||
entries[i].color = (PartyColor)i;
|
||||
entries[i].unk2 = 0;
|
||||
entries[i].mapid = 0;
|
||||
entries[i].unk3 = 0;
|
||||
entries[i].unk6 = players[i].Name;
|
||||
entries[i].unk6 = character.Name;
|
||||
}
|
||||
}
|
||||
|
||||
public override byte[] Build()
|
||||
{
|
||||
if (players.Length < 1)
|
||||
if (Clients.Count < 1)
|
||||
return new byte[0];
|
||||
|
||||
// xor: 0xD863, sub: 0xA9
|
||||
@ -145,59 +84,6 @@ namespace PSO2SERVER.Protocol.Packets
|
||||
}
|
||||
|
||||
pkt.WriteAscii(unk2, 0xD863, 0xA9);
|
||||
|
||||
//// 队伍结构数据
|
||||
//for(int i = 0; i < players.Length; i++)
|
||||
//{
|
||||
// PartyEntry pe = new PartyEntry();
|
||||
// pkt.WriteStruct(new ObjectHeader((uint)players[i].Accounts.AccountId, ObjectType.Player)); // player of player
|
||||
// pkt.WriteUtf16(players[i].name, 0xD863, 0xA9);
|
||||
// pkt.WriteUtf16(players[i].Accounts.Nickname, 0xD863, 0xA9);
|
||||
// pkt.Write((byte)players[i].Jobs.entries.hunter.level); // Active class level
|
||||
// pkt.Write((byte)players[i].Jobs.entries.hunter.level2); // idk
|
||||
// pkt.Write((byte)players[i].Jobs.mainClass); // idk
|
||||
// pkt.Write((byte)players[i].Jobs.subClass); // idk
|
||||
// pkt.Write((byte)i); // idk
|
||||
// pkt.WriteBytes(0, 7);
|
||||
// pkt.Write((uint)0); // idk
|
||||
// ///hp
|
||||
// pkt.Write((uint)0);
|
||||
// pkt.Write((uint)0);
|
||||
// pkt.Write((uint)0);
|
||||
// /// 玩家所在的地图ID。
|
||||
// pkt.Write(pe.mapid);
|
||||
// pkt.Write(pe.unk3);
|
||||
// pkt.WriteBytes(0, 12);
|
||||
// pkt.Write((uint)0);
|
||||
// pkt.Write((uint)0);
|
||||
// pkt.Write((uint)0);
|
||||
//}
|
||||
|
||||
//for(int i = 0; i < 4 - players.Length; i++) // Empty entries
|
||||
//{
|
||||
// pkt.WriteStruct(new ObjectHeader(0, 0)); // player of player
|
||||
// pkt.WriteMagic(0, 0xD863, 0xA9);
|
||||
// pkt.WriteMagic(0, 0xD863, 0xA9);
|
||||
// pkt.Write((byte)0); // Active class level
|
||||
// pkt.Write((byte)0); // idk
|
||||
// pkt.Write((byte)0); // idk
|
||||
// pkt.Write((byte)0); // idk
|
||||
// pkt.Write((byte)0); // idk
|
||||
// pkt.WriteBytes(0, 7);
|
||||
// pkt.Write((uint)0); // idk
|
||||
// ///hp
|
||||
// pkt.Write((uint)0);
|
||||
// pkt.Write((uint)0);
|
||||
// pkt.Write((uint)0);
|
||||
// /// 玩家所在的地图ID。
|
||||
// pkt.Write((ushort)0);
|
||||
// pkt.Write((ushort)0);
|
||||
// pkt.WriteBytes(0, 12);
|
||||
// pkt.Write((uint)0);
|
||||
// pkt.Write((uint)0);
|
||||
// pkt.Write((uint)0);
|
||||
//}
|
||||
|
||||
return pkt.ToArray();
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ namespace PSO2SERVER.Protocol.Packets
|
||||
using (var db = new ServerEf())
|
||||
{
|
||||
var chars = db.Characters
|
||||
.Where(w => w.Account.AccountId == AccountId)
|
||||
.Where(w => w.AccountID == AccountId)
|
||||
.OrderBy(o => o.CharacterID) // TODO: 按照最后游玩的角色排序
|
||||
.Select(s => s);
|
||||
|
||||
|
@ -5,11 +5,11 @@ namespace PSO2SERVER.Protocol.Packets
|
||||
{
|
||||
internal class GuildInfoPacket : Packet
|
||||
{
|
||||
private readonly Character _character;
|
||||
private readonly Client Client;
|
||||
|
||||
public GuildInfoPacket(Character character)
|
||||
public GuildInfoPacket(Client client)
|
||||
{
|
||||
_character = character;
|
||||
Client = client;
|
||||
}
|
||||
|
||||
#region implemented abstract members of Packet
|
||||
@ -25,7 +25,7 @@ namespace PSO2SERVER.Protocol.Packets
|
||||
writer.Write((byte) 0);
|
||||
|
||||
// Character ID
|
||||
writer.Write((uint) _character.CharacterID);
|
||||
writer.Write((uint)Client.Character.CharacterID);
|
||||
|
||||
// Padding?
|
||||
for (var i = 0; i < 4; i++)
|
||||
@ -33,14 +33,14 @@ namespace PSO2SERVER.Protocol.Packets
|
||||
|
||||
// Nickname
|
||||
// TODO: The above and below may be switched around, need more data
|
||||
writer.WriteFixedLengthUtf16(_character.Account.Nickname, 16);
|
||||
writer.WriteFixedLengthUtf16(Client._account.Nickname, 16);
|
||||
|
||||
// Padding?
|
||||
for (var i = 0; i < 36; i++)
|
||||
writer.Write((byte) 0);
|
||||
|
||||
// Accounts name
|
||||
writer.WriteFixedLengthUtf16(_character.Name, 16);
|
||||
writer.WriteFixedLengthUtf16(Client.Character.Name, 16);
|
||||
|
||||
// Unknown?
|
||||
for (var i = 0; i < 24; i++)
|
||||
|
@ -8,11 +8,10 @@ namespace PSO2SERVER.Protocol.Packets
|
||||
{
|
||||
public class MissionPassInfoPacket : Packet
|
||||
{
|
||||
public FixedList<uint> unk { get; set; } = new FixedList<uint>(0x2F);
|
||||
public FixedList<uint> unk { get; set; } = new FixedList<uint>(0x2F, 0);
|
||||
|
||||
public MissionPassInfoPacket()
|
||||
{
|
||||
unk = new FixedList<uint>(0x2F);
|
||||
}
|
||||
|
||||
#region implemented abstract members of Packet
|
||||
|
@ -341,6 +341,7 @@
|
||||
<Compile Include="Object\ObjectManager.cs" />
|
||||
<Compile Include="Protocol\Handlers\04-ObjectHandler\04-75-ActionEnd.cs" />
|
||||
<Compile Include="Protocol\Handlers\06-PlayerStatusHandler\06-01-DealDamage.cs" />
|
||||
<Compile Include="Protocol\Handlers\07-ChatHandler\07-37-UNK.cs" />
|
||||
<Compile Include="Protocol\Handlers\0B-QuestHandler\0B-20-AcceptQuest.cs" />
|
||||
<Compile Include="Protocol\Handlers\0F-ItemHandler\0F-01-ItemPickupRequest.cs" />
|
||||
<Compile Include="Protocol\Handlers\0F-ItemHandler\0F-1C-GetItemDescription.cs" />
|
||||
|
@ -133,8 +133,10 @@ namespace PSO2SERVER.Zone
|
||||
// 设置客户端的账户ID
|
||||
c.SendPacket(new SetAccountIDPacket(c._account.AccountId));
|
||||
|
||||
Logger.WriteObj(c.Character);
|
||||
|
||||
// Spawn Character
|
||||
c.SendPacket(new CharacterSpawnPacket(c.Character, location, true, true));
|
||||
c.SendPacket(new CharacterSpawnPacket(c, location, true, true));
|
||||
c.CurrentLocation = location;
|
||||
c.CurrentMap = this;
|
||||
|
||||
@ -151,11 +153,11 @@ namespace PSO2SERVER.Zone
|
||||
}
|
||||
|
||||
// Spawn for others, Spawn others for me
|
||||
CharacterSpawnPacket spawnMe = new CharacterSpawnPacket(c.Character, location, false, true);
|
||||
CharacterSpawnPacket spawnMe = new CharacterSpawnPacket(c, location, false, true);
|
||||
foreach (Client other in Clients)
|
||||
{
|
||||
other.SendPacket(spawnMe);
|
||||
c.SendPacket(new CharacterSpawnPacket(other.Character, other.CurrentLocation, false, true));
|
||||
c.SendPacket(new CharacterSpawnPacket(other, other.CurrentLocation, false, true));
|
||||
}
|
||||
|
||||
Clients.Add(c);
|
||||
|
Loading…
Reference in New Issue
Block a user