Initial Implementation of Saving and Loading Data from Official -> PS (replace accountid = 1)

This commit is contained in:
raphaeIl 2024-11-19 08:46:10 -05:00
parent 33995fb87a
commit 1c91ecfa6b
4 changed files with 314 additions and 22 deletions

View File

@ -7,6 +7,7 @@
foreach (var character in characters) foreach (var character in characters)
{ {
character.AccountServerId = account.ServerId; character.AccountServerId = account.ServerId;
character.ServerId = 0; // just in case if this key was set (like from pcaps)
context.Characters.Add(character); context.Characters.Add(character);
} }
@ -24,8 +25,11 @@
if (existingEquipment != null && equipment.BoundCharacterServerId == default) if (existingEquipment != null && equipment.BoundCharacterServerId == default)
existingEquipment.StackCount += equipment.StackCount; existingEquipment.StackCount += equipment.StackCount;
else else
{
equipment.ServerId = 0;
context.Equipment.Add(equipment); context.Equipment.Add(equipment);
} }
}
return [.. equipmentDB]; return [.. equipmentDB];
} }
@ -54,7 +58,10 @@
existingItem.StackCount += item.StackCount; existingItem.StackCount += item.StackCount;
item.ServerId = existingItem.ServerId; item.ServerId = existingItem.ServerId;
} else } else
{
item.ServerId = 0;
context.Items.Add(item); context.Items.Add(item);
}
context.SaveChanges(); context.SaveChanges();
} }
@ -67,6 +74,8 @@
foreach (var gear in gears) foreach (var gear in gears)
{ {
gear.AccountServerId = account.ServerId; gear.AccountServerId = account.ServerId;
gear.ServerId = 0;
context.Gears.Add(gear); context.Gears.Add(gear);
var targetCharacter = account.Characters.FirstOrDefault(x => x.ServerId == gear.BoundCharacterServerId); var targetCharacter = account.Characters.FirstOrDefault(x => x.ServerId == gear.BoundCharacterServerId);
@ -114,6 +123,7 @@
foreach (var cafe in cafes) foreach (var cafe in cafes)
{ {
cafe.AccountServerId = account.ServerId; cafe.AccountServerId = account.ServerId;
cafe.CafeDBId = 0;
context.Cafes.Add(cafe); context.Cafes.Add(cafe);
} }
@ -125,6 +135,7 @@
foreach (var furniture in furnitures) foreach (var furniture in furnitures)
{ {
furniture.AccountServerId = account.ServerId; furniture.AccountServerId = account.ServerId;
furniture.ServerId = 0;
account.Furnitures.Add(furniture); account.Furnitures.Add(furniture);
} }

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,261 @@
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using SCHALE.Common.Database;
using SCHALE.Common.Database.ModelExtensions;
using SCHALE.Common.Migrations.SqlServerMigrations;
using SCHALE.Common.NetworkProtocol;
using SCHALE.Common.Utils;
using SCHALE.GameServer.Services.Irc;
using SCHALE.GameServer.Utils;
namespace SCHALE.GameServer.Commands
{
[CommandHandler("loaddata", "s", "/loaddata <file_name>")]
internal class LoadDataCommand : Command
{
public LoadDataCommand(IrcConnection connection, string[] args, bool validate = true) : base(connection, args, validate) { }
[Argument(0, @"^.*$", "The file name of the packet json saved or Operation", ArgumentFlags.IgnoreCase)]
public string DataFileName { get; set; } = string.Empty;
public override void Execute()
{
switch (DataFileName.ToLower())
{
case "list":
ListData();
break;
default:
LoadData();
break;
}
}
public void LoadData()
{
var context = connection.Context;
var account = connection.Account;
string dataFileRelativePath = $"./Resources/account_data/{DataFileName}";
if (!PcapUtils.Load(dataFileRelativePath))
{
connection.SendChatMessage($"File {DataFileName} was not found! Be sure to include \".json\".");
connection.SendChatMessage($"Usage: /loaddata <file_name>");
throw new FileNotFoundException("File not found!");
}
AccountAuthResponse accountInfoPacket = PcapUtils.GetPacketFromPcap<AccountAuthResponse>(Protocol.Account_Auth, PacketType.Response);
if (accountInfoPacket == null)
{
connection.SendChatMessage($"Your data file does not contain the AccountAuthResponse - {Protocol.Account_Auth} Packet.");
throw new InvalidDataException("Invalid Data!");
}
AccountLoginSyncResponse accountDataPacket = PcapUtils.GetPacketFromPcap<AccountLoginSyncResponse>(Protocol.Account_LoginSync, PacketType.Response);
if (accountDataPacket == null)
{
connection.SendChatMessage($"Your data file does not contain the AccountLoginSyncResponse - {Protocol.Account_LoginSync} Packet.");
throw new InvalidDataException("Invalid Data!");
}
// ready to put pcap data into db
// User Info
account.Nickname = accountInfoPacket.AccountDB.Nickname;
account.State = accountInfoPacket.AccountDB.State;
account.Level = accountInfoPacket.AccountDB.Level;
account.Exp = accountInfoPacket.AccountDB.Exp;
account.RepresentCharacterServerId = accountInfoPacket.AccountDB.RepresentCharacterServerId;
Dictionary<long, CharacterDB> oldToNewCharacterServerId = new Dictionary<long, CharacterDB>(); // for converting old char id to new
foreach (var character in accountDataPacket.CharacterListResponse.CharacterDBs)
{
oldToNewCharacterServerId.Add(character.ServerId, character);
}
// All Character Data
InventoryUtils.RemoveAllCharacters(connection);
var charactersAdded = account.AddCharacters(context, accountDataPacket.CharacterListResponse.CharacterDBs.ToArray());
context.SaveChanges();
// All Weapon Data
context.Weapons.RemoveRange(context.Weapons.Where(x => x.AccountServerId == connection.AccountServerId));
foreach (var weapon in accountDataPacket.CharacterListResponse.WeaponDBs)
{
if (oldToNewCharacterServerId.ContainsKey(weapon.BoundCharacterServerId))
{
weapon.BoundCharacterServerId = oldToNewCharacterServerId[weapon.BoundCharacterServerId].ServerId;
}
}
account.AddWeapons(context, accountDataPacket.CharacterListResponse.WeaponDBs.ToArray());
// All Item Data
if (accountDataPacket.ItemListResponse == null)
{
ItemListResponse seperateItemListPacket = PcapUtils.GetPacketFromPcap<ItemListResponse>(Protocol.Item_List, PacketType.Response);
if (seperateItemListPacket != null)
{
accountDataPacket.ItemListResponse = seperateItemListPacket;
}
else
{
connection.SendChatMessage("Could not find any packet associated with item data.");
}
}
else
{
context.Items.RemoveRange(context.Items.Where(x => x.AccountServerId == connection.AccountServerId));
account.AddItems(context, accountDataPacket.ItemListResponse.ItemDBs.ToArray());
}
// All Gear Data
context.Gears.RemoveRange(context.Gears.Where(x => x.AccountServerId == connection.AccountServerId));
foreach (var gear in accountDataPacket.CharacterGearListResponse.GearDBs)
{
if (oldToNewCharacterServerId.ContainsKey(gear.BoundCharacterServerId))
{
gear.BoundCharacterServerId = oldToNewCharacterServerId[gear.BoundCharacterServerId].ServerId;
}
}
account.AddGears(context, accountDataPacket.CharacterGearListResponse.GearDBs.ToArray());
Dictionary<long, EquipmentDB> oldToNewEquipmentServerId = new Dictionary<long, EquipmentDB>(); // for converting old char id to new
// All Equipment Data
context.Equipment.RemoveRange(context.Equipment.Where(x => x.AccountServerId == connection.AccountServerId));
foreach (var equipment in accountDataPacket.EquipmentItemListResponse.EquipmentDBs)
{
oldToNewEquipmentServerId.Add(equipment.ServerId, equipment);
}
account.AddEquipment(context, accountDataPacket.EquipmentItemListResponse.EquipmentDBs.ToArray());
context.SaveChanges();
foreach (var character in charactersAdded)
{
for (int i = 0; i < 3; i++)
{
if (oldToNewEquipmentServerId.ContainsKey(character.EquipmentServerIds[i]))
{
character.EquipmentServerIds[i] = oldToNewEquipmentServerId[character.EquipmentServerIds[i]].ServerId;
}
}
}
// All Memory Lobby Data
context.MemoryLobbies.RemoveRange(context.MemoryLobbies.Where(x => x.AccountServerId == connection.AccountServerId));
account.AddMemoryLobbies(context, accountDataPacket.MemoryLobbyListResponse.MemoryLobbyDBs.ToArray());
Dictionary<long, CafeDB> oldToNewCafeServerId = new Dictionary<long, CafeDB>(); // for converting old char id to new
// All Cafe Data
context.Cafes.RemoveRange(context.Cafes.Where(x => x.AccountServerId == connection.AccountServerId));
foreach (var cafe in accountDataPacket.CafeGetInfoResponse.CafeDBs)
{
oldToNewCafeServerId.Add(cafe.CafeDBId, cafe);
}
account.AddCafes(context, accountDataPacket.CafeGetInfoResponse.CafeDBs.ToArray());
context.SaveChanges();
// All Furniture Data
context.Furnitures.RemoveRange(context.Furnitures.Where(x => x.AccountServerId == connection.AccountServerId));
foreach (var furniture in accountDataPacket.CafeGetInfoResponse.FurnitureDBs)
{
if (oldToNewCafeServerId.ContainsKey(furniture.CafeDBId))
{
furniture.CafeDBId = oldToNewCafeServerId[furniture.CafeDBId].CafeDBId;
}
}
account.AddFurnitures(context, accountDataPacket.CafeGetInfoResponse.FurnitureDBs.ToArray());
// All Echelon Data
context.Echelons.RemoveRange(context.Echelons.Where(x => x.AccountServerId == connection.AccountServerId));
foreach (var echelon in accountDataPacket.EchelonListResponse.EchelonDBs)
{
if (oldToNewCharacterServerId.ContainsKey(echelon.LeaderServerId))
{
echelon.LeaderServerId = oldToNewCharacterServerId[echelon.LeaderServerId].ServerId;
}
for (int i = 0; i < echelon.MainSlotServerIds.Count; i++)
{
long targetId = echelon.MainSlotServerIds[i];
if (oldToNewCharacterServerId.ContainsKey(targetId))
{
echelon.MainSlotServerIds[i] = oldToNewCharacterServerId[targetId].ServerId;
}
}
for (int i = 0; i < echelon.SupportSlotServerIds.Count; i++)
{
long targetId = echelon.SupportSlotServerIds[i];
if (oldToNewCharacterServerId.ContainsKey(targetId))
{
echelon.SupportSlotServerIds[i] = oldToNewCharacterServerId[targetId].ServerId;
}
}
for (int i = 0; i < echelon.SkillCardMulliganCharacterIds.Count; i++)
{
long targetId = echelon.SkillCardMulliganCharacterIds[i];
if (oldToNewCharacterServerId.ContainsKey(targetId))
{
echelon.SkillCardMulliganCharacterIds[i] = oldToNewCharacterServerId[targetId].ServerId;
}
}
}
account.AddEchelons(context, accountDataPacket.EchelonListResponse.EchelonDBs.ToArray());
context.SaveChanges();
connection.SendChatMessage("Sucessfully Loaded All Data from the save file.");
}
public void ListData()
{
string dataFolderRelativePath = $"./Resources/account_data/";
string dataFolderPath = Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory), dataFolderRelativePath);
connection.SendChatMessage("Data Files:");
if (Directory.Exists(dataFolderPath))
{
string[] files = Directory.GetFiles(dataFolderPath);
foreach (string file in files)
{
connection.SendChatMessage(Path.GetFileName(file));
}
}
else
{
connection.SendChatMessage("That path does not exist!");
}
}
}
}

View File

@ -11,17 +11,18 @@ namespace SCHALE.GameServer.Utils
{ {
public static class PcapUtils public static class PcapUtils
{ {
private static string DefaultPcapFilePath = Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory), "packets.json"); private static readonly string DefaultPcapFileName = "packets.json";
//private static readonly string CurrentPcapFileName = "";
private static List<RequestPacket> RequestPackets { get; } private static List<RequestPacket> RequestPackets { get; } = null;
private static List<ResponsePacket> ResponsePackets { get; } private static List<ResponsePacket> ResponsePackets { get; } = null;
static PcapUtils() static PcapUtils()
{ {
RequestPackets = new List<RequestPacket>(); RequestPackets = new List<RequestPacket>();
ResponsePackets = new List<ResponsePacket>(); ResponsePackets = new List<ResponsePacket>();
PcapUtils.Load(); PcapUtils.Load(DefaultPcapFileName);
} }
// gets all packets of that type // gets all packets of that type
@ -43,15 +44,21 @@ namespace SCHALE.GameServer.Utils
return GetPacketsFromPcap<T>((Protocol)protocol, packetType).FirstOrDefault(); return GetPacketsFromPcap<T>((Protocol)protocol, packetType).FirstOrDefault();
} }
private static void Load() public static bool Load(string pcapFileName)
{ {
if (!Path.Exists(DefaultPcapFilePath)) // clear first? not clearing can cause conflicts
RequestPackets.Clear();
ResponsePackets.Clear();
string PcapFilePath = Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory), pcapFileName);
if (!Path.Exists(PcapFilePath))
{ {
Log.Information("Pcap json file was not found."); Log.Error($"Pcap json file was not found at path {PcapFilePath}.");
return; return false;
} }
var json = File.ReadAllText(DefaultPcapFilePath); var json = File.ReadAllText(PcapFilePath);
var jsonPackets = System.Text.Json.JsonSerializer.Deserialize<JsonArray>(json); var jsonPackets = System.Text.Json.JsonSerializer.Deserialize<JsonArray>(json);
foreach (JsonNode packetNode in jsonPackets) foreach (JsonNode packetNode in jsonPackets)
@ -92,6 +99,9 @@ namespace SCHALE.GameServer.Utils
Log.Information($"Loaded Pcap Type: {packetNode["type"]}, Protocol: {protocol}"); Log.Information($"Loaded Pcap Type: {packetNode["type"]}, Protocol: {protocol}");
} }
Log.Information($"Successfully Loaded Packets from: {PcapFilePath}!");
return true;
} }
public static Type? GetPacketTypeByProtocol(Protocol protocol, PacketType packetType) public static Type? GetPacketTypeByProtocol(Protocol protocol, PacketType packetType)