forked from Raphael/SCHALE.GameServer
Initial Implementation of Saving and Loading Data from Official -> PS (replace accountid = 1)
This commit is contained in:
parent
33995fb87a
commit
1c91ecfa6b
|
@ -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,7 +25,10 @@
|
||||||
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
|
@ -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!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue