解析部分数据包

This commit is contained in:
Longfeng Qin 2024-09-20 21:58:37 +08:00
parent 1bb52cc659
commit 971c1942a3
45 changed files with 335 additions and 121 deletions

View File

@ -41,7 +41,7 @@ namespace PSO2SERVER
public bool IsClosed { get; private set; }
public SocketClient Socket { get; private set; }
// Game properties, TODO Consider moving these somewhere else
public Player User { get; set; }
public Account _account { get; set; }
public Character Character { get; set; }
//public Zone.Zone CurrentZone { get; set; }
public Map CurrentZone;
@ -240,7 +240,8 @@ namespace PSO2SERVER
{
// Check for and create packets directory if it doesn't exist
var packetPath = string.Format(
"packets/{0}"
"packets/0x{0:X2}-0x{1:X2}/{2}"
, typeA, typeB
, _server.StartTime.ToShortDateString().Replace('/', '-')
);
@ -272,9 +273,11 @@ namespace PSO2SERVER
{
// Check for and create packets directory if it doesn't exist
var packetPath = string.Format(
"UnkClientPackets/{0}"
"UnkClientPackets/0x{0:X2}-0x{1:X2}/{2}"
, typeA, typeB
, _server.StartTime.ToShortDateString().Replace('/', '-')
);
if (!Directory.Exists(packetPath))
Directory.CreateDirectory(packetPath);

View File

@ -277,7 +277,7 @@ namespace PSO2SERVER
// SpawnClone
var spawnClone = new ConsoleCommand(SpawnClone, "spawnclone");
spawnClone.Arguments.Add(new ConsoleCommandArgument("Username", false));
spawnClone.Arguments.Add(new ConsoleCommandArgument("Player Name", false));
spawnClone.Arguments.Add(new ConsoleCommandArgument("Account Name", false));
spawnClone.Arguments.Add(new ConsoleCommandArgument("X", false));
spawnClone.Arguments.Add(new ConsoleCommandArgument("Y", false));
spawnClone.Arguments.Add(new ConsoleCommandArgument("Z", false));
@ -653,7 +653,7 @@ namespace PSO2SERVER
// This is probably not the right way to do this
ServerApp.Instance.Server.Clients[i].Socket.Close();
Logger.WriteCommand(client,
"[CMD] Logged out user " + ServerApp.Instance.Server.Clients[i].User.Username);
"[CMD] Logged out user " + ServerApp.Instance.Server.Clients[i]._account.Username);
}
Logger.WriteCommand(client, "[CMD] Logged out all players successfully");
@ -695,17 +695,17 @@ namespace PSO2SERVER
if (z == 0)
z = 134.375f;
var fakePlayer = new Player
var fakePlayer = new Account
{
Username = name,
Nickname = playerName,
PlayerId = (12345678 + new Random().Next())
AccountId = (12345678 + new Random().Next())
};
var fakeChar = new Character
{
Character_ID = 12345678 + new Random().Next(),
Player = fakePlayer,
Account = fakePlayer,
Name = playerName,
Looks = client.Character.Looks,
Jobs = client.Character.Jobs
@ -878,7 +878,7 @@ namespace PSO2SERVER
var id = 0;
if (client != null)
{
id = client.User.PlayerId;
id = client._account.AccountId;
foundPlayer = true;
}
else
@ -912,7 +912,7 @@ namespace PSO2SERVER
var id = 0;
if (client != null)
{
id = client.User.PlayerId;
id = client._account.AccountId;
foundPlayer = true;
}
else

View File

@ -35,7 +35,20 @@ namespace PSO2SERVER.Database
public float PosZ { get; set; }
}
public class Player
public class Account
{
[Key]
public int AccountId { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Nickname { get; set; }
public string SettingsIni { get; set; }
public string Cpu_Info { get; set; }
public string Video_Info { get; set; }
}
public class PlayerSystemInfo
{
[Key]
public int PlayerId { get; set; }
@ -90,7 +103,7 @@ namespace PSO2SERVER.Database
public class ServerEf : DbContext
{
public DbSet<ServerInfo> ServerInfos { get; set; }
public DbSet<Player> Players { get; set; }
public DbSet<Account> Account { get; set; }
public DbSet<Character> Characters { get; set; }
public DbSet<Teleport> Teleports { get; set; }
public DbSet<NPC> NPCs { get; set; }
@ -126,7 +139,7 @@ namespace PSO2SERVER.Database
ServerInfos.Add(revision);
//TODO Possibly move this somewhere else?
Database.ExecuteSqlCommand("ALTER TABLE Players AUTO_INCREMENT=10000000");
Database.ExecuteSqlCommand("ALTER TABLE Account AUTO_INCREMENT=10000000");
}
SaveChanges();

View File

@ -49,7 +49,7 @@ namespace PSO2SERVER
public static int FindPlayerByUsername(string name)
{
for (var i = 0; i < ServerApp.Instance.Server.Clients.Count; i++)
if (name.ToLower() == ServerApp.Instance.Server.Clients[i].User.Username.ToLower())
if (name.ToLower() == ServerApp.Instance.Server.Clients[i]._account.Username.ToLower())
return i;
return -1;

View File

@ -309,7 +309,7 @@ namespace PSO2SERVER.Models
public string Unk4 { get; set; }
public virtual Player Player { get; set; }
public virtual Account Account { get; set; }
}

View File

@ -31,13 +31,13 @@ namespace PSO2SERVER.Packets.Handlers
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
// Set Player ID
// Set Account ID
//var setPlayerId = new PacketWriter();
//setPlayerId.WritePlayerHeader((uint)context.User.PlayerId);
//setPlayerId.WritePlayerHeader((uint)context._account.AccountId);
//context.SendPacket(0x06, 0x00, 0, setPlayerId.ToArray());
context.SendPacket(new SetPlayerIDPacket(context.User.PlayerId));
context.SendPacket(new SetPlayerIDPacket(context._account.AccountId));
// Spawn Player
// Spawn Account
new CharacterSpawn().HandlePacket(context, flags, data, position, size);
}

View File

@ -6,13 +6,13 @@ using PSO2SERVER.Database;
namespace PSO2SERVER.Packets.Handlers
{
[PacketHandlerAttr(0x03, 0x0C)]
public class PingResponse : PacketHandler
public class ServerPong : PacketHandler
{
#region implemented abstract members of PacketHandler
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
Logger.Write("[HI!] 收到 {0} Ping回应 ", context.User.Username);
Logger.Write("[HI!] 收到 {0} Ping回应 ", context._account.Username);
}
#endregion

View File

@ -34,7 +34,7 @@ namespace PSO2SERVER.Packets.Handlers
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context.User == null || context.Character == null)
if (context._account == null || context.Character == null)
return;
context.SendPacket(new LoadingScreenRemovePacket());

View File

@ -15,7 +15,7 @@ namespace PSO2SERVER.Packets.Handlers
if (context.currentParty.currentQuest == null)
return;
var instanceName = String.Format("{0}-{1}", context.currentParty.currentQuest.name, context.User.Nickname);
var instanceName = String.Format("{0}-{1}", context.currentParty.currentQuest.name, context._account.Nickname);
ZoneManager.Instance.NewInstance(instanceName, new Map("campship", 150, 0, Map.MapType.Campship, 0));
// todo: add next map
ZoneManager.Instance.AddMapToInstance(instanceName, new Map("area1", 311, -1, Map.MapType.Other, (Map.MapFlags)0x6) { GenerationArgs = new Map.GenParam((uint)new Random().Next(), 2, 3)});

View File

@ -18,7 +18,7 @@ namespace PSO2SERVER.Packets.Handlers
// TODO: WTF terribad hax?
if (context.CurrentLocation.PosZ >= 20)
{
var instanceName = String.Format("{0}-{1}", context.currentParty.currentQuest.name, context.User.Nickname);
var instanceName = String.Format("{0}-{1}", context.currentParty.currentQuest.name, context._account.Nickname);
Map forest = ZoneManager.Instance.MapFromInstance("area1", instanceName);
forest.SpawnClient(context, new PSOLocation(0, 1, 0, -0, -37, 0.314f, 145.5f));

View File

@ -15,11 +15,11 @@ namespace PSO2SERVER.Packets.Handlers
/// (0x03, 0x35) Move Lobby -> Casino.
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context.User == null)
if (context._account == null)
return;
// Dunno what these are yet.
context.SendPacket(0x11, 0xA, 0x0, BitConverter.GetBytes(context.User.PlayerId));
context.SendPacket(0x11, 0xA, 0x0, BitConverter.GetBytes(context._account.AccountId));
context.SendPacket(0x1E, 0xC, 0x0, BitConverter.GetBytes(101));
Map casinoMap = ZoneManager.Instance.MapFromInstance("casino", "lobby");

View File

@ -15,11 +15,11 @@ namespace PSO2SERVER.Packets.Handlers
/// (0x03, 0x39) Move Lobby -> Bridge.
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context.User == null)
if (context._account == null)
return;
// Dunno what these are yet.
context.SendPacket(0x11, 0xA, 0x0, BitConverter.GetBytes(context.User.PlayerId));
context.SendPacket(0x11, 0xA, 0x0, BitConverter.GetBytes(context._account.AccountId));
context.SendPacket(0x1E, 0xC, 0x0, BitConverter.GetBytes(101));
Map bridgeMap = ZoneManager.Instance.MapFromInstance("bridge", "lobby");

View File

@ -15,11 +15,11 @@ namespace PSO2SERVER.Packets.Handlers
/// (0x03, 0x3C) Move Lobby -> Cafe.
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context.User == null)
if (context._account == null)
return;
// Dunno what these are yet.
context.SendPacket(0x11, 0xA, 0x0, BitConverter.GetBytes(context.User.PlayerId));
context.SendPacket(0x11, 0xA, 0x0, BitConverter.GetBytes(context._account.AccountId));
context.SendPacket(0x1E, 0xC, 0x0, BitConverter.GetBytes(101));
Map dstMap = ZoneManager.Instance.MapFromInstance("cafe", "lobby");

View File

@ -37,7 +37,7 @@ namespace PSO2SERVER.Packets.Handlers
if (c == context || c.Character == null || c.CurrentZone != context.CurrentZone)
continue;
//PacketWriter output = new PacketWriter();
//output.WriteStruct(new ObjectHeader((uint)context.User.PlayerId, EntityType.Player));
//output.WriteStruct(new ObjectHeader((uint)context._account.AccountId, EntityType.Account));
//output.WriteStruct(preformer);
//output.Write(preData);
//output.WriteAscii(command, 0x4315, 0x7A);
@ -48,7 +48,7 @@ namespace PSO2SERVER.Packets.Handlers
//c.SendPacket(0x4, 0x80, 0x44, output.ToArray());
c.SendPacket(new MovementActionServerPacket(context.User.PlayerId, preformer, preData
c.SendPacket(new MovementActionServerPacket(context._account.AccountId, preformer, preData
, command, rest, thingCount, things, final));
}
}

View File

@ -18,7 +18,7 @@ namespace PSO2SERVER.Packets.Handlers
// //// TODO: WTF terribad hax?
// //if (context.CurrentLocation.PosZ >= 20)
// //{
// // var instanceName = String.Format("{0}-{1}", context.currentParty.currentQuest.name, context.User.Nickname);
// // var instanceName = String.Format("{0}-{1}", context.currentParty.currentQuest.name, context._account.Nickname);
// // Map forest = ZoneManager.Instance.MapFromInstance("area1", instanceName);
// // forest.SpawnClient(context, new PSOLocation(0, 1, 0, -0, -37, 0.314f, 145.5f));

View File

@ -31,7 +31,7 @@ namespace PSO2SERVER.Packets.Handlers
srcObj = new PSOObject
{
Header = srcObject,
Name = "Player"
Name = "Account"
};
}
else
@ -53,7 +53,7 @@ namespace PSO2SERVER.Packets.Handlers
if (teleporterEndpoint == null)
{
Logger.WriteError("[OBJ] Teleporter for {0} in {1} does not contain a destination!", srcObj.Header.ID, "lobby");
// Teleport Player to default point
// Teleport Account 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"));
@ -70,7 +70,7 @@ namespace PSO2SERVER.Packets.Handlers
PosY = teleporterEndpoint.PosY,
PosZ = teleporterEndpoint.PosZ,
};
// Teleport Player
// Teleport Account
context.SendPacket(new TeleportTransferPacket(srcObj, endpointLocation));
// Unhide player
context.SendPacket(new ObjectActionPacket(dstObject, srcObject, new ObjectHeader(), new ObjectHeader(), "Forwarded"));
@ -80,9 +80,9 @@ namespace PSO2SERVER.Packets.Handlers
if (command == "READY")
{
context.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)context.User.PlayerId, EntityType.Player), srcObj.Header, srcObj.Header,
context.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)context._account.AccountId, EntityType.Player), srcObj.Header, srcObj.Header,
new ObjectHeader(), "FavsNeutral"));
context.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)context.User.PlayerId, EntityType.Player), srcObj.Header, srcObj.Header,
context.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)context._account.AccountId, EntityType.Player), srcObj.Header, srcObj.Header,
new ObjectHeader(), "AP")); // Short for Appear, Thanks Zapero!
}
@ -93,7 +93,7 @@ namespace PSO2SERVER.Packets.Handlers
if (client.Character == null || client == context)
continue;
client.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)client.User.PlayerId, EntityType.Player), srcObj.Header,
client.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)client._account.AccountId, EntityType.Player), srcObj.Header,
new ObjectHeader(dstObject.ID, EntityType.Player), new ObjectHeader(), "SitSuccess"));
}
}

View File

@ -23,12 +23,12 @@ namespace PSO2SERVER.Packets.Handlers
if (c == context || c.Character == null || c.CurrentZone != context.CurrentZone)
continue;
//PacketWriter writer = new PacketWriter();
//writer.WriteStruct(new ObjectHeader((uint)c.User.PlayerId, EntityType.Player));
//writer.WriteStruct(new ObjectHeader((uint)c._account.AccountId, EntityType.Account));
//writer.WriteStruct(actor);
//writer.Write(rest);
//c.SendPacket(0x4, 0x81, 0x40, writer.ToArray());
c.SendPacket(new ActionUpdateServerPacket(c.User.PlayerId, actor, rest));
c.SendPacket(new ActionUpdateServerPacket(c._account.AccountId, actor, rest));
}
}

View File

@ -36,7 +36,7 @@ namespace PSO2SERVER.Packets.Handlers
{
command.Run(args, args.Length, full, context);
valid = true;
Logger.WriteCommand(null, "[CMD] {0} 发送指令 {1}", context.User.Username, full);
Logger.WriteCommand(null, "[CMD] {0} 发送指令 {1}", context._account.Username, full);
}
if (valid)
@ -51,7 +51,7 @@ namespace PSO2SERVER.Packets.Handlers
Logger.Write("[CHT] <{0}> 频道{1}说 {2}", context.Character.Name, channel, message);
var writer = new PacketWriter();
writer.WritePlayerHeader((uint) context.User.PlayerId);
writer.WritePlayerHeader((uint) context._account.AccountId);
writer.Write(channel);
writer.WriteUtf16(message, 0x9D3F, 0x44);

View File

@ -41,7 +41,7 @@ namespace PSO2SERVER.Packets.Handlers
questDef = def
};
context.currentParty.currentQuest = quest;
context.SendPacket(new SetQuestInfoPacket(def, context.User));
context.SendPacket(new SetQuestInfoPacket(def, context._account));
context.SendPacket(new QuestStartPacket(def, diff));
}

View File

@ -18,7 +18,7 @@ namespace PSO2SERVER.Packets.Handlers
if (c.Character == null || c.CurrentZone != context.CurrentZone)
continue;
c.SendPacket(new NewBusyStatePacket(context.User.PlayerId, BusyState.Busy));
c.SendPacket(new NewBusyStatePacket(context._account.AccountId, BusyState.Busy));
}
}
}

View File

@ -19,7 +19,7 @@ namespace PSO2SERVER.Packets.Handlers
if (c.Character == null || c.CurrentZone != context.CurrentZone)
continue;
c.SendPacket(new NewBusyStatePacket(context.User.PlayerId, BusyState.NotBusy));
c.SendPacket(new NewBusyStatePacket(context._account.AccountId, BusyState.NotBusy));
}
}
}

View File

@ -37,13 +37,13 @@ namespace PSO2SERVER.Packets.Handlers
// What am I doing here even
using (var db = new ServerEf())
{
var users = from u in db.Players
var users = from u in db.Account
where u.Username.ToLower().Equals(username.ToLower())
select u;
var error = "";
Player user;
Account user;
if (!users.Any())
{
@ -62,7 +62,7 @@ namespace PSO2SERVER.Packets.Handlers
else // We're all good!
{
// 直接插入新账户至数据库
user = new Player
user = new Account
{
Username = username.ToLower(),
Password = BCrypt.Net.BCrypt.HashPassword(password),
@ -70,7 +70,7 @@ namespace PSO2SERVER.Packets.Handlers
// Since we can't display the nickname prompt yet, just default it to the username
SettingsIni = File.ReadAllText(ServerApp.ServerSettingsKey)
};
db.Players.Add(user);
db.Account.Add(user);
db.SaveChanges();
context.SendPacket(0x11, 0x1e, 0x0, new byte[0x44]); // Request nickname
@ -96,7 +96,7 @@ namespace PSO2SERVER.Packets.Handlers
}
}
context.SendPacket(new LoginDataPacket("Server AuthList 1", error, (user == null) ? (uint)0 : (uint)user.PlayerId));
context.SendPacket(new LoginDataPacket("Server AuthList 1", error, (user == null) ? (uint)0 : (uint)user.AccountId));
// Mystery packet
//var mystery = new PacketWriter();
@ -110,12 +110,7 @@ namespace PSO2SERVER.Packets.Handlers
return;
}
// Settings packet
var settings = new PacketWriter();
settings.WriteAscii(user.SettingsIni, 0x54AF, 0x100);
context.SendPacket(0x2B, 2, 4, settings.ToArray());
context.User = user;
context._account = user;
}

View File

@ -11,10 +11,10 @@ namespace PSO2SERVER.Packets.Handlers
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context.User == null)
if (context._account == null)
return;
context.SendPacket(new CharacterListPacket(context.User.PlayerId));
context.SendPacket(new CharacterListPacket(context._account.AccountId));
}
#endregion

View File

@ -23,7 +23,7 @@ namespace PSO2SERVER.Packets.Handlers
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context.User == null)
if (context._account == null)
return;
var reader = new PacketReader(data, position, size);
@ -31,7 +31,7 @@ namespace PSO2SERVER.Packets.Handlers
var charId = pkt.CharId;
//Logger.Write("id {0}", charId);
Logger.Write("id {0}", charId);
if (context.Character == null) // On character create, this is already set.
{
@ -39,14 +39,14 @@ namespace PSO2SERVER.Packets.Handlers
{
try
{
var character = db.Characters.FirstOrDefault(c => c.Character_ID == charId);
var character = db.Characters.FirstOrDefault(c => c.Player_ID == charId);
if (character == null || character.Player == null || character.Player.PlayerId != context.User.PlayerId)
if (character == null || character.Account == null || character.Account.AccountId != context._account.AccountId)
{
Logger.WriteError("数据库中未找到 {0} 角色ID {1} ({2})"
, context.User.Username
, context._account.Username
, charId
, context.User.PlayerId
, context._account.AccountId
);
context.Socket.Close();
return;

View File

@ -14,7 +14,7 @@ namespace PSO2SERVER.Packets.Handlers
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context.User == null)
if (context._account == null)
return;
@ -33,20 +33,20 @@ namespace PSO2SERVER.Packets.Handlers
var looks = reader.ReadStruct<Character.LooksParam>();
var jobs = reader.ReadStruct<Character.JobParam>();
Logger.WriteInternal("[CHR] {0} 创建了名为 {1} 的新角色.", context.User.Username, name);
Logger.WriteInternal("[CHR] {0} 创建了名为 {1} 的新角色.", context._account.Username, name);
var newCharacter = new Character
{
Name = name,
Jobs = jobs,
Looks = looks,
Player = context.User
Account = context._account
};
// Add to database
using (var db = new ServerEf())
{
// Check if any characters exist for this player
var existingCharacters = db.Characters.Where(c => c.Player.PlayerId == context.User.PlayerId).ToList();
var existingCharacters = db.Characters.Where(c => c.Account.AccountId == context._account.AccountId).ToList();
if (existingCharacters.Count > 0)
{
// Increment ID if characters already exist
@ -58,18 +58,20 @@ namespace PSO2SERVER.Packets.Handlers
newCharacter.Character_ID = 1;
}
//Logger.Write("newCharacter.CharacterId {0} {1}", newCharacter.CharacterId, context.User.PlayerId);
newCharacter.Player_ID = context._account.AccountId;
//Logger.Write("newCharacter.CharacterId {0} {1}", newCharacter.CharacterId, context._account.AccountId);
db.Characters.Add(newCharacter);
db.Entry(newCharacter.Player).State = EntityState.Modified;
db.Entry(newCharacter.Account).State = EntityState.Modified;
db.SaveChanges();
}
// Assign character to player
context.Character = newCharacter;
// Set Player ID
context.SendPacket(new CharacterCreateResponsePacket(CharacterCreateResponsePacket.CharacterCreationStatus.Success, (uint)context.User.PlayerId));
// Set Account ID
context.SendPacket(new CharacterCreateResponsePacket(CharacterCreateResponsePacket.CharacterCreationStatus.Success, (uint)context._account.AccountId));
// Spawn
context.SendPacket(new NoPayloadPacket(0x11, 0x3E));

View File

@ -16,7 +16,7 @@ namespace PSO2SERVER.Packets.Handlers
var reader = new PacketReader(data);
var id = reader.ReadInt32();
Logger.Write("[CHR] {0} 正在删除ID {1} 的角色", context.User.Username, id);
Logger.Write("[CHR] {0} 正在删除ID {1} 的角色", context._account.Username, id);
// Delete Character
using (var db = new ServerEf())

View File

@ -0,0 +1,68 @@
using System;
using System.Data.Entity.Infrastructure;
using System.IO;
using System.Linq;
using PSO2SERVER.Database;
using PSO2SERVER.Models;
using PSO2SERVER.Packets.PSOPackets;
namespace PSO2SERVER.Packets.Handlers
{
[PacketHandlerAttr(0x11, 0x2D)]
class SystemInformation : PacketHandler
{
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
var reader = new PacketReader(data, position, size);
var cpu_info = reader.ReadAscii(0x883D, 0x9F);
var video_info = reader.ReadAscii(0x883D, 0x9F);
//reader.BaseStream.Seek(8, SeekOrigin.Current);
//var vram = reader.ReadInt64();
//var windows_version = reader.ReadAscii(0x883D, 0x9F);
//Logger.Write("Setting 内容: " + windows_version);
using (var db = new ServerEf())
{
try
{
var player = db.Account.FirstOrDefault(w => w.AccountId == context._account.AccountId);
if (player == null)
{
Logger.WriteError("未找到 AccountId: {0}", context._account.AccountId);
return;
}
if (!string.IsNullOrWhiteSpace(cpu_info))
{
player.Cpu_Info = cpu_info;
}
if (!string.IsNullOrWhiteSpace(video_info))
{
player.Video_Info = video_info;
}
// 保存更改并捕获可能的异常
db.SaveChanges();
}
catch (DbUpdateException dbEx)
{
Logger.WriteError("数据库更新时发生异常: {0}", dbEx.Message);
// 处理数据库更新错误
}
catch (Exception ex)
{
Logger.WriteError("构建数据包时发生异常: {0}", ex.Message);
// 处理其他异常情况
}
}
//context.SendPacket(new LoadSettingsPacket(context._account.AccountId));
}
}
}

View File

@ -17,7 +17,7 @@ namespace PSO2SERVER.Packets.Handlers
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if (context.User == null || context.Character == null)
if (context._account == null || context.Character == null)
return;
// Looks/Jobs

View File

@ -0,0 +1,18 @@
using System;
using PSO2SERVER.Models;
using PSO2SERVER.Packets.PSOPackets;
namespace PSO2SERVER.Packets.Handlers
{
[PacketHandlerAttr(0x2B, 0x00)]
class SettingsRequest : PacketHandler
{
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
//var info = string.Format("[<--] 接收到的数据 (hex): ");
//Logger.WriteHex(info, data);
context.SendPacket(new LoadSettingsPacket(context._account.AccountId));
}
}
}

View File

@ -0,0 +1,56 @@
using System;
using System.Data.Entity.Infrastructure;
using System.Linq;
using PSO2SERVER.Database;
using PSO2SERVER.Models;
using PSO2SERVER.Packets.PSOPackets;
namespace PSO2SERVER.Packets.Handlers
{
[PacketHandlerAttr(0x2B, 0x01)]
class SavePlayerSettings : PacketHandler
{
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
var reader = new PacketReader(data, position, size);
var setting = reader.ReadAscii(0xCEF1, 0xB5);
using (var db = new ServerEf())
{
try
{
var player = db.Account.FirstOrDefault(w => w.AccountId == context._account.AccountId);
if (player == null)
{
Logger.WriteError("未找到 AccountId: {0}", context._account.AccountId);
return;
}
if (string.IsNullOrWhiteSpace(setting))
{
Logger.WriteError("新的设置内容无效。");
return;
}
player.SettingsIni = setting;
// 保存更改并捕获可能的异常
db.SaveChanges();
}
catch (DbUpdateException dbEx)
{
Logger.WriteError("数据库更新时发生异常: {0}", dbEx.Message);
// 处理数据库更新错误
}
catch (Exception ex)
{
Logger.WriteError("构建数据包时发生异常: {0}", ex.Message);
// 处理其他异常情况
}
}
//context.SendPacket(new LoadSettingsPacket(context._account.AccountId));
}
}
}

View File

@ -12,7 +12,7 @@ namespace PSO2SERVER.Packets.Handlers
{
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
context.SendPacket(new SymbolArtListPacket(new Models.ObjectHeader((uint)context.User.PlayerId, Models.EntityType.Player)));
context.SendPacket(new SymbolArtListPacket(new Models.ObjectHeader((uint)context._account.AccountId, Models.EntityType.Player)));
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.IO;
using PSO2SERVER.Models;
namespace PSO2SERVER.Packets.PSOPackets
{
class ServerPingPacket : Packet
{
public ServerPingPacket()
{
}
public override byte[] Build()
{
PacketWriter writer = new PacketWriter();
return writer.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x03, 0x0B, PacketFlags.None);
}
}
}

View File

@ -37,8 +37,8 @@ namespace PSO2SERVER.Packets.PSOPackets
{
var writer = new PacketWriter();
// Player header
writer.WritePlayerHeader((uint)_character.Player.PlayerId);
// Account header
writer.WritePlayerHeader((uint)_character.Account.AccountId);
// Spawn position
writer.Write(Position);
@ -54,7 +54,7 @@ namespace PSO2SERVER.Packets.PSOPackets
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)_character.Account.AccountId); // 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"
@ -65,7 +65,7 @@ namespace PSO2SERVER.Packets.PSOPackets
writer.WriteFixedLengthUtf16("", 32); // title?
writer.Write((uint)0); // 0x204
writer.Write((uint)0); // gmflag?
writer.WriteFixedLengthUtf16(_character.Player.Nickname, 16); // nickname, maybe not 16 chars?
writer.WriteFixedLengthUtf16(_character.Account.Nickname, 16); // nickname, maybe not 16 chars?
for (var i = 0; i < 64; i++)
writer.Write((byte)0);

View File

@ -22,14 +22,14 @@ namespace PSO2SERVER.Packets.PSOPackets
// xor: 0xD863, sub: 0xA9
PacketWriter writer = new PacketWriter();
writer.WriteBytes(0, 12); // Unknown 12 bytes, not obj header
writer.WriteStruct(new ObjectHeader((uint)members[0].Player.PlayerId, EntityType.Player)); // Player receiving the thing
writer.WriteStruct(new ObjectHeader((uint)members[0].Account.AccountId, EntityType.Player)); // Account receiving the thing
writer.WriteStruct(members.Length); // Likely partymembercount
for(int i = 0; i < members.Length; i++)
{
writer.WriteStruct(new ObjectHeader((uint)members[i].Player.PlayerId, EntityType.Player)); // Header of player
writer.WriteStruct(new ObjectHeader((uint)members[i].Account.AccountId, EntityType.Player)); // Header of player
writer.WriteUtf16(members[i].Name, 0xD863, 0xA9);
writer.WriteUtf16(members[i].Player.Nickname, 0xD863, 0xA9);
writer.WriteUtf16(members[i].Account.Nickname, 0xD863, 0xA9);
writer.Write((byte)members[i].Jobs.entries.hunter.level); // Active class level
writer.Write((byte)0); // idk
writer.Write((byte)4); // idk

View File

@ -10,9 +10,9 @@ namespace PSO2SERVER.Packets.PSOPackets
{
QuestDefiniton questdef;
Database.Player p;
Database.Account p;
public SetQuestInfoPacket(QuestDefiniton questdef, Database.Player p)
public SetQuestInfoPacket(QuestDefiniton questdef, Database.Account p)
{
this.questdef = questdef;
this.p = p;
@ -26,7 +26,7 @@ namespace PSO2SERVER.Packets.PSOPackets
writer.Write((ushort)0);
writer.Write((ushort)0);
writer.Write((ushort)1);
writer.WriteStruct(new ObjectHeader((uint)p.PlayerId, EntityType.Player));
writer.WriteStruct(new ObjectHeader((uint)p.AccountId, EntityType.Player));
writer.Write(0);
writer.Write((ushort)0);
writer.Write((ushort)0);

View File

@ -41,7 +41,7 @@ namespace PSO2SERVER.Packets.PSOPackets
using (var db = new ServerEf())
{
var chars = db.Characters
.Where(w => w.Player.PlayerId == _PlayerId)
.Where(w => w.Account.AccountId == _PlayerId)
.OrderBy(o => o.Character_ID) // TODO: Order by last played
.Select(s => s);

View File

@ -32,13 +32,13 @@ namespace PSO2SERVER.Packets.PSOPackets
// Nickname
// TODO: The above and below may be switched around, need more data
writer.WriteFixedLengthUtf16(_character.Player.Nickname, 16);
writer.WriteFixedLengthUtf16(_character.Account.Nickname, 16);
// Padding?
for (var i = 0; i < 36; i++)
writer.Write((byte) 0);
// Player name
// Account name
writer.WriteFixedLengthUtf16(_character.Name, 16);
// Unknown?

View File

@ -1,6 +1,8 @@
using PSO2SERVER.Models;
using PSO2SERVER.Database;
using PSO2SERVER.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
@ -8,22 +10,62 @@ namespace PSO2SERVER.Packets.PSOPackets
{
public class LoadSettingsPacket : Packet
{
public LoadSettingsPacket()
private int _PlayerId;
public LoadSettingsPacket(int PlayerId)
{
_PlayerId = PlayerId;
}
#region implemented abstract members of Packet
public override byte[] Build()
{
var pkt = new PacketWriter();
return pkt.ToArray();
var writer = new PacketWriter();
using (var db = new ServerEf())
{
try
{
// 使用 FirstOrDefault 以避免异常
var player = db.Account.FirstOrDefault(w => w.AccountId == _PlayerId);
if (player == null)
{
Logger.WriteError("未找到 AccountId: {0}", _PlayerId);
// 可以选择返回一个特定的错误包或空数组
return Array.Empty<byte>();
}
// 确保 SettingsIni 不为 null
if (player.SettingsIni != null)
{
writer.WriteAscii(player.SettingsIni, 0x54AF, 0x100);
}
else
{
Logger.WriteError("AccountId: {0} 的 SettingsIni 为 null, 载入默认值", _PlayerId);
player.SettingsIni = File.ReadAllText(ServerApp.ServerSettingsKey);
// 保存更改并捕获可能的异常
db.SaveChanges();
// 可以选择如何处理此情况
writer.WriteAscii(player.SettingsIni, 0x54AF, 0x100);
}
}
catch (Exception ex)
{
Logger.WriteError("构建数据包时发生异常: {0}", ex.Message);
// 处理异常情况,例如返回错误包
}
}
return writer.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x2B, 0x02, PacketFlags.None);
return new PacketHeader(0x2B, 0x02, PacketFlags.PACKED);
}
#endregion

View File

@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PSO2SERVER.Packets.PSOPackets
{
class SetScenePacket
{
}
}

View File

@ -35,6 +35,7 @@ namespace PSO2SERVER.Packets
}
var charCount = magic - 1;
var padding = 4 - (charCount & 3);
//Logger.Write("charCount = " + charCount + " padding = " + padding);
var data = ReadBytes((int) charCount);
for (var i = 0; i < padding; i++)

View File

@ -40,7 +40,7 @@ namespace PSO2SERVER.Party
{
if(!members.Contains(c))
{
Logger.WriteWarning("[PTY] Client {0} was trying to be removed from {1}, but he was never in {1}!", c.User.Username, name);
Logger.WriteWarning("[PTY] Client {0} was trying to be removed from {1}, but he was never in {1}!", c._account.Username, name);
return;
}

View File

@ -41,7 +41,7 @@ namespace PSO2SERVER.Party
if (GetCurrentPartyForClient(c) != null)
return; // For now
parties.Add(new Party(c.User.Username, c), c.User.Username);
parties.Add(new Party(c._account.Username, c), c._account.Username);
}
public void AddPlayerToParty(Client c, Party p)

View File

@ -59,10 +59,10 @@ namespace PSO2SERVER
// TODO: Disconnect a client if we don't get a response in a certain amount of time
foreach (var client in Clients)
{
if (client != null && client.User != null)
if (client != null && client._account != null)
{
Logger.Write("[HEY] Pinging " + client.User.Username);
client.SendPacket(new NoPayloadPacket(0x03, 0x0B));
Logger.Write("[HEY] Pinging " + client._account.Username);
client.SendPacket(new ServerPingPacket());
}
}
}

View File

@ -171,7 +171,7 @@
<Compile Include="Network\PortChecker.cs" />
<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-0C-ServerPong.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" />
@ -202,7 +202,11 @@
<Compile Include="Packets\Handlers\0E-PartyHandler\0E-0C-QuestCounterHandler.cs" />
<Compile Include="Packets\Handlers\03-ServerHandler\03-34-TeleportCasinoToLobby.cs" />
<Compile Include="Packets\Handlers\11-ClientHandler\11-41-CreateCharacterOne.cs" />
<Compile Include="Packets\Handlers\11-ClientHandler\11-2D-SystemInformation.cs" />
<Compile Include="Packets\Handlers\2B-SettingHandler\2B-01-SavePlayerSettings.cs" />
<Compile Include="Packets\Handlers\2B-SettingHandler\2B-00-SettingsRequest.cs" />
<Compile Include="Packets\Handlers\2F-SymbolHandler\2F-06-SymbolArtHandler.cs" />
<Compile Include="Packets\PSOPackets\03-ServerPacket\03-0B-ServerPingPacket.cs" />
<Compile Include="Packets\PSOPackets\4D-ClassicMissionPassPacket\4D-03-MissionPassPacket.cs" />
<Compile Include="Packets\PSOPackets\4D-ClassicMissionPassPacket\4D-01-MissionPassInfoPacket.cs" />
<Compile Include="Packets\PSOPackets\2B-SettingsPacket\2B-02-LoadSettingsPacket.cs" />
@ -344,7 +348,6 @@
<Compile Include="Packets\PSOPackets\2F-SymbolPacket\2F-05-SymbolArtResultPacket.cs" />
<Compile Include="Packets\PSOPackets\2F-SymbolPacket\2F-03-SymbolArtClientDataPacket.cs" />
<Compile Include="Packets\PSOPackets\2F-SymbolPacket\2F-01-SymbolArtDataRequestPacket.cs" />
<Compile Include="Packets\PSOPackets\UN-UN-SetScenePacket.cs" />
<Compile Include="Packets\PSOPackets\2F-SymbolPacket\2F-07-SymbolArtListPacket.cs" />
<Compile Include="Packets\PSOPackets\04-ObjectRelatedPacket\04-02-TeleportTransferPacket.cs" />
<Compile Include="Party\Party.cs" />

View File

@ -110,7 +110,7 @@ namespace PSO2SERVER.Zone
{
//PacketWriter writer = new PacketWriter();
//writer.WriteStruct(new ObjectHeader(3, EntityType.Map));
//writer.WriteStruct(new ObjectHeader((uint)c.User.PlayerId, EntityType.Player));
//writer.WriteStruct(new ObjectHeader((uint)c._account.AccountId, EntityType.Account));
//writer.Write(0x1); // 8 Zeros
//writer.Write(0); // 8 Zeros
//writer.Write(~(uint)Type); // F4 FF FF FF
@ -132,7 +132,7 @@ namespace PSO2SERVER.Zone
_map.GenerationArgs.xsize = GenerationArgs.xsize;
_map.GenerationArgs.ysize = GenerationArgs.ysize;
c.SendPacket(new MapTransferPacket(_map, c.User.PlayerId));
c.SendPacket(new MapTransferPacket(_map, c._account.AccountId));
}
if (c.CurrentZone != null)
@ -141,9 +141,9 @@ namespace PSO2SERVER.Zone
}
//var setPlayerId = new PacketWriter();
//setPlayerId.WritePlayerHeader((uint)c.User.PlayerId);
//setPlayerId.WritePlayerHeader((uint)c._account.AccountId);
//c.SendPacket(0x06, 0x00, 0, setPlayerId.ToArray());
c.SendPacket(new SetPlayerIDPacket(c.User.PlayerId));
c.SendPacket(new SetPlayerIDPacket(c._account.AccountId));
// Spawn Character
c.SendPacket(new CharacterSpawnPacket(c.Character, location));
@ -175,7 +175,7 @@ namespace PSO2SERVER.Zone
Clients.Add(c);
Logger.Write("[MAP] {0} 已生成至 {1}.", c.User.Username, Name);
Logger.Write("[MAP] {0} 已生成至 {1}.", c._account.Username, Name);
if (InstanceName != null && ZoneManager.Instance.playerCounter.ContainsKey(InstanceName))
{
@ -195,10 +195,10 @@ namespace PSO2SERVER.Zone
foreach (Client other in Clients)
{
//PacketWriter writer = new PacketWriter();
//writer.WriteStruct(new ObjectHeader((uint)other.User.PlayerId, EntityType.Player));
//writer.WriteStruct(new ObjectHeader((uint)c.User.PlayerId, EntityType.Player));
//writer.WriteStruct(new ObjectHeader((uint)other._account.AccountId, EntityType.Account));
//writer.WriteStruct(new ObjectHeader((uint)c._account.AccountId, EntityType.Account));
//other.SendPacket(0x4, 0x3B, 0x40, writer.ToArray());
other.SendPacket(new DespawnPlayerPacket(other.User.PlayerId, c.User.PlayerId));
other.SendPacket(new DespawnPlayerPacket(other._account.AccountId, c._account.AccountId));
}
if (InstanceName != null && ZoneManager.Instance.playerCounter.ContainsKey(InstanceName))