mirror of
https://github.com/EpinelPS/EpinelPS.git
synced 2025-12-12 15:04:36 +01:00
initial memorypack format support
This commit is contained in:
4
.editorconfig
Normal file
4
.editorconfig
Normal file
@@ -0,0 +1,4 @@
|
||||
[*.cs]
|
||||
|
||||
# CA5397: Do not use deprecated SslProtocols values
|
||||
dotnet_diagnostic.CA5397.severity = none
|
||||
@@ -42,12 +42,15 @@ public class LoadRecordInitializerGenerator : IIncrementalGenerator
|
||||
if (context.SemanticModel.GetDeclaredSymbol(variable) is not IFieldSymbol symbol)
|
||||
return null;
|
||||
|
||||
if (symbol.Type is not INamedTypeSymbol namedSymbol)
|
||||
return null;
|
||||
|
||||
foreach (var attr in symbol.GetAttributes())
|
||||
{
|
||||
|
||||
if (attr.ConstructorArguments.Length == 3)
|
||||
if (attr.ConstructorArguments.Length == 2)
|
||||
{
|
||||
if (attr.ConstructorArguments[0].Value is not string fileName || attr.ConstructorArguments[1].Value is not string key || attr.ConstructorArguments[2].Value is not INamedTypeSymbol recordType)
|
||||
if (attr.ConstructorArguments[0].Value is not string fileName || attr.ConstructorArguments[1].Value is not string key)
|
||||
return null;
|
||||
|
||||
return new LoadFieldInfo
|
||||
@@ -56,7 +59,7 @@ public class LoadRecordInitializerGenerator : IIncrementalGenerator
|
||||
FieldName = symbol.Name,
|
||||
FileName = fileName,
|
||||
Key = key,
|
||||
RecordTypeName = recordType.ToDisplayString()
|
||||
RecordTypeName = namedSymbol.TypeArguments[1].Name
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -71,23 +74,24 @@ public class LoadRecordInitializerGenerator : IIncrementalGenerator
|
||||
sb.AppendLine("using System.Threading.Tasks;");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("namespace EpinelPS.Data;");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("public static class GameDataInitializer");
|
||||
sb.AppendLine("{");
|
||||
sb.AppendFormat($"public static int TotalFiles = {fieldInfos.Length};");
|
||||
sb.AppendLine(" public static async Task InitializeGameData(IProgress<double> progress = null)");
|
||||
sb.AppendLine(" {");
|
||||
sb.AppendLine($"\tpublic static int TotalFiles = {fieldInfos.Length};");
|
||||
sb.AppendLine("\tpublic static async Task InitializeGameData(IProgress<double> progress = null)");
|
||||
sb.AppendLine("\t{");
|
||||
|
||||
foreach (var info in fieldInfos)
|
||||
{
|
||||
var tempVar = $"data_{info.FieldName}";
|
||||
sb.AppendLine($" var {tempVar} = await {info.ContainingClass}.Instance.LoadZip<{info.RecordTypeName}>(\"{info.FileName}\", progress);");
|
||||
sb.AppendLine($" foreach (var obj in {tempVar}.records)");
|
||||
sb.AppendLine(" {");
|
||||
sb.AppendLine($" {info.ContainingClass}.Instance.{info.FieldName}.Add(obj.{info.Key}, obj);");
|
||||
sb.AppendLine(" }");
|
||||
sb.AppendLine($"\t\tvar {tempVar} = await {info.ContainingClass}.Instance.LoadZip<{info.RecordTypeName}>(\"{info.FileName}\", progress);");
|
||||
sb.AppendLine($"\t\tforeach (var obj in {tempVar})");
|
||||
sb.AppendLine("\t\t{");
|
||||
sb.AppendLine($"\t\t\t{info.ContainingClass}.Instance.{info.FieldName}.Add(obj.{info.Key}, obj);");
|
||||
sb.AppendLine("\t\t}");
|
||||
}
|
||||
|
||||
sb.AppendLine(" }");
|
||||
sb.AppendLine("\t}");
|
||||
sb.AppendLine("}");
|
||||
|
||||
return sb.ToString();
|
||||
|
||||
@@ -13,6 +13,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{4BB2E7
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EpinelPS.Analyzers", "EpinelPS.Analyzers\EpinelPS.Analyzers.csproj", "{E3B18A3D-B20B-447D-BCBE-12931E18B41E}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using EpinelPS.Utils;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Security.Cryptography;
|
||||
using EpinelPS.Utils;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using MemoryPack;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace EpinelPS.Data
|
||||
{
|
||||
@@ -33,171 +35,175 @@ namespace EpinelPS.Data
|
||||
private int totalFiles = 1;
|
||||
private int currentFile = 0;
|
||||
|
||||
// TODO: all of the data types need to be changed to match the game
|
||||
private bool UseMemoryPack = false;
|
||||
|
||||
public readonly Dictionary<string, MapInfo> MapData = [];
|
||||
|
||||
[LoadRecord("MainQuestTable.json", "id", typeof(MainQuestCompletionTable))]
|
||||
[LoadRecord("MainQuestTable.json", "id")]
|
||||
public readonly Dictionary<int, MainQuestCompletionRecord> QuestDataRecords = [];
|
||||
|
||||
[LoadRecord("CampaignStageTable.json", "id", typeof(CampaignStageTable))]
|
||||
[LoadRecord("CampaignStageTable.json", "id")]
|
||||
public readonly Dictionary<int, CampaignStageRecord> StageDataRecords = [];
|
||||
|
||||
[LoadRecord("RewardTable.json", "id", typeof(RewardTable))]
|
||||
[LoadRecord("RewardTable.json", "id")]
|
||||
public readonly Dictionary<int, RewardTableRecord> RewardDataRecords = [];
|
||||
|
||||
[LoadRecord("UserExpTable.json", "level", typeof(UserExpTable))]
|
||||
[LoadRecord("UserExpTable.json", "level")]
|
||||
public readonly Dictionary<int, UserExpRecord> UserExpDataRecords = [];
|
||||
|
||||
[LoadRecord("CampaignChapterTable.json", "chapter", typeof(CampaignChapterTable))]
|
||||
[LoadRecord("CampaignChapterTable.json", "chapter")]
|
||||
public readonly Dictionary<int, CampaignChapterRecord> ChapterCampaignData = [];
|
||||
|
||||
[LoadRecord("CharacterCostumeTable.json", "id", typeof(CharacterCostumeTable))]
|
||||
[LoadRecord("CharacterCostumeTable.json", "id")]
|
||||
public readonly Dictionary<int, CharacterCostumeRecord> CharacterCostumeTable = [];
|
||||
|
||||
[LoadRecord("CharacterTable.json", "id", typeof(CharacterTable))]
|
||||
[LoadRecord("CharacterTable.json", "id")]
|
||||
public readonly Dictionary<int, CharacterRecord> CharacterTable = [];
|
||||
|
||||
[LoadRecord("ContentsTutorialTable.json", "id", typeof(TutorialTable))]
|
||||
[LoadRecord("ContentsTutorialTable.json", "id")]
|
||||
public readonly Dictionary<int, ClearedTutorialData> TutorialTable = [];
|
||||
[LoadRecord("ItemEquipTable.json", "id", typeof(ItemEquipTable))]
|
||||
[LoadRecord("ItemEquipTable.json", "id")]
|
||||
|
||||
public readonly Dictionary<int, ItemEquipRecord> ItemEquipTable = [];
|
||||
|
||||
[LoadRecord("ItemMaterialTable.json", "id", typeof(ItemMaterialTable))]
|
||||
[LoadRecord("ItemMaterialTable.json", "id")]
|
||||
public readonly Dictionary<int, ItemMaterialRecord> itemMaterialTable = [];
|
||||
|
||||
[LoadRecord("ItemEquipExpTable.json", "id", typeof(ItemEquipExpTable))]
|
||||
[LoadRecord("ItemEquipExpTable.json", "id")]
|
||||
public readonly Dictionary<int, ItemEquipExpRecord> itemEquipExpTable = [];
|
||||
|
||||
[LoadRecord("ItemEquipGradeExpTable.json", "id", typeof(ItemEquipGradeExpTable))]
|
||||
[LoadRecord("ItemEquipGradeExpTable.json", "id")]
|
||||
public readonly Dictionary<int, ItemEquipGradeExpRecord> ItemEquipGradeExpTable = [];
|
||||
|
||||
[LoadRecord("CharacterLevelTable.json", "level", typeof(CharacterLevelTable))]
|
||||
[LoadRecord("CharacterLevelTable.json", "level")]
|
||||
public readonly Dictionary<int, CharacterLevelData> LevelData = [];
|
||||
|
||||
[LoadRecord("TacticAcademyFunctionTable.json", "id", typeof(TacticAcademyLessonTable))]
|
||||
[LoadRecord("TacticAcademyFunctionTable.json", "id")]
|
||||
public readonly Dictionary<int, TacticAcademyLessonRecord> TacticAcademyLessons = [];
|
||||
|
||||
[LoadRecord("SideStoryStageTable.json", "id", typeof(SideStoryStageTable))]
|
||||
[LoadRecord("SideStoryStageTable.json", "id")]
|
||||
public readonly Dictionary<int, SideStoryStageRecord> SidestoryRewardTable = [];
|
||||
|
||||
[LoadRecord("FieldItemTable.json", "id", typeof(FieldItemTable))]
|
||||
[LoadRecord("FieldItemTable.json", "id")]
|
||||
public readonly Dictionary<int, FieldItemRecord> FieldItems = [];
|
||||
|
||||
[LoadRecord("OutpostBattleTable.json", "id", typeof(OutpostBattleTable))]
|
||||
[LoadRecord("OutpostBattleTable.json", "id")]
|
||||
public readonly Dictionary<int, OutpostBattleTableRecord> OutpostBattle = [];
|
||||
|
||||
[LoadRecord("JukeboxListTable.json", "id", typeof(JukeboxListTable))]
|
||||
[LoadRecord("JukeboxListTable.json", "id")]
|
||||
public readonly Dictionary<int, JukeboxListRecord> jukeboxListDataRecords = [];
|
||||
|
||||
[LoadRecord("JukeboxThemeTable.json", "id", typeof(JukeboxThemeTable))]
|
||||
[LoadRecord("JukeboxThemeTable.json", "id")]
|
||||
public readonly Dictionary<int, JukeboxThemeRecord> jukeboxThemeDataRecords = [];
|
||||
|
||||
[LoadRecord("GachaTypeTable.json", "id", typeof(GachaTypeTable))]
|
||||
[LoadRecord("GachaTypeTable.json", "id")]
|
||||
public readonly Dictionary<int, GachaType> gachaTypes = [];
|
||||
|
||||
[LoadRecord("EventManagerTable.json", "id", typeof(EventManagerTable))]
|
||||
[LoadRecord("EventManagerTable.json", "id")]
|
||||
public readonly Dictionary<int, EventManager> eventManagers = [];
|
||||
|
||||
[LoadRecord("LiveWallpaperTable.json", "id", typeof(LiveWallpaperTable))]
|
||||
[LoadRecord("LiveWallpaperTable.json", "id")]
|
||||
public readonly Dictionary<int, LiveWallpaperRecord> lwptablemgrs = [];
|
||||
|
||||
[LoadRecord("AlbumResourceTable.json", "id", typeof(AlbumResourceTable))]
|
||||
[LoadRecord("AlbumResourceTable.json", "id")]
|
||||
public readonly Dictionary<int, AlbumResourceRecord> albumResourceRecords = [];
|
||||
|
||||
[LoadRecord("UserFrameTable.json", "id", typeof(UserFrameTable))]
|
||||
[LoadRecord("UserFrameTable.json", "id")]
|
||||
public readonly Dictionary<int, UserFrameTableRecord> userFrameTable = [];
|
||||
|
||||
[LoadRecord("ArchiveRecordManagerTable.json", "id", typeof(ArchiveRecordManagerTable))]
|
||||
[LoadRecord("ArchiveRecordManagerTable.json", "id")]
|
||||
public readonly Dictionary<int, ArchiveRecordManagerRecord> archiveRecordManagerTable = [];
|
||||
|
||||
[LoadRecord("ArchiveEventStoryTable.json", "id", typeof(ArchiveEventStoryTable))]
|
||||
[LoadRecord("ArchiveEventStoryTable.json", "id")]
|
||||
public readonly Dictionary<int, ArchiveEventStoryRecord> archiveEventStoryRecords = [];
|
||||
|
||||
[LoadRecord("ArchiveEventQuestTable.json", "id", typeof(ArchiveEventQuestTable))]
|
||||
[LoadRecord("ArchiveEventQuestTable.json", "id")]
|
||||
public readonly Dictionary<int, ArchiveEventQuestRecord> archiveEventQuestRecords = [];
|
||||
|
||||
[LoadRecord("ArchiveEventDungeonStageTable.json", "id", typeof(ArchiveEventDungeonStageTable))]
|
||||
[LoadRecord("ArchiveEventDungeonStageTable.json", "id")]
|
||||
public readonly Dictionary<int, ArchiveEventDungeonStageRecord> archiveEventDungeonStageRecords = [];
|
||||
|
||||
[LoadRecord("UserTitleTable.json", "id", typeof(UserTitleTable))]
|
||||
[LoadRecord("UserTitleTable.json", "id")]
|
||||
public readonly Dictionary<int, UserTitleRecord> userTitleRecords = [];
|
||||
|
||||
[LoadRecord("ArchiveMessengerConditionTable.json", "id", typeof(ArchiveMessengerConditionTable))]
|
||||
[LoadRecord("ArchiveMessengerConditionTable.json", "id")]
|
||||
public readonly Dictionary<int, ArchiveMessengerConditionRecord> archiveMessengerConditionRecords = [];
|
||||
|
||||
[LoadRecord("CharacterStatTable.json", "id", typeof(CharacterStatTable))]
|
||||
[LoadRecord("CharacterStatTable.json", "id")]
|
||||
public readonly Dictionary<int, CharacterStatRecord> characterStatTable = [];
|
||||
|
||||
[LoadRecord("SkillInfoTable.json", "id", typeof(SkillInfoTable))]
|
||||
[LoadRecord("SkillInfoTable.json", "id")]
|
||||
public readonly Dictionary<int, SkillInfoRecord> skillInfoTable = [];
|
||||
|
||||
[LoadRecord("CostTable.json", "id", typeof(CostTable))]
|
||||
[LoadRecord("CostTable.json", "id")]
|
||||
public readonly Dictionary<int, CostRecord> costTable = [];
|
||||
|
||||
[LoadRecord("MidasProductTable.json", "midas_product_id_proximabeta", typeof(MidasProductTable))]
|
||||
[LoadRecord("MidasProductTable.json", "midas_product_id_proximabeta")]
|
||||
public readonly Dictionary<string, MidasProductRecord> mediasProductTable = [];
|
||||
|
||||
[LoadRecord("TowerTable.json", "id", typeof(TowerTable))]
|
||||
[LoadRecord("TowerTable.json", "id")]
|
||||
public readonly Dictionary<int, TowerRecord> towerTable = [];
|
||||
|
||||
[LoadRecord("TriggerTable.json", "id", typeof(TriggerTable))]
|
||||
[LoadRecord("TriggerTable.json", "id")]
|
||||
public readonly Dictionary<int, TriggerRecord> TriggerTable = [];
|
||||
|
||||
[LoadRecord("InfraCoreGradeTable.json", "id", typeof(InfracoreTable))]
|
||||
[LoadRecord("InfraCoreGradeTable.json", "id")]
|
||||
public readonly Dictionary<int, InfracoreRecord> InfracoreTable = [];
|
||||
|
||||
[LoadRecord("AttractiveCounselCharacterTable.json", "name_code", typeof(AttractiveCounselCharacterTable))]
|
||||
[LoadRecord("AttractiveCounselCharacterTable.json", "name_code")]
|
||||
public readonly Dictionary<int, AttractiveCounselCharacterRecord> AttractiveCounselCharacterTable = [];
|
||||
|
||||
[LoadRecord("AttractiveLevelRewardTable.json", "id", typeof(AttractiveLevelRewardTable))]
|
||||
[LoadRecord("AttractiveLevelRewardTable.json", "id")]
|
||||
public readonly Dictionary<int, AttractiveLevelRewardRecord> AttractiveLevelReward = [];
|
||||
|
||||
[LoadRecord("SubQuestTable.json", "id", typeof(SubquestTable))]
|
||||
[LoadRecord("SubQuestTable.json", "id")]
|
||||
public readonly Dictionary<int, SubquestRecord> Subquests = [];
|
||||
|
||||
[LoadRecord("MessengerDialogTable.json", "id", typeof(MessengerDialogTable))]
|
||||
[LoadRecord("MessengerDialogTable.json", "id")]
|
||||
public readonly Dictionary<string, MessengerDialogRecord> Messages = [];
|
||||
|
||||
[LoadRecord("MessengerConditionTriggerTable.json", "id", typeof(MessengerMsgConditionTable))]
|
||||
[LoadRecord("MessengerConditionTriggerTable.json", "id")]
|
||||
public readonly Dictionary<int, MessengerMsgConditionRecord> MessageConditions = [];
|
||||
|
||||
[LoadRecord("ScenarioRewardsTable.json", "condition_id", typeof(ScenarioRewardTable))]
|
||||
[LoadRecord("ScenarioRewardsTable.json", "condition_id")]
|
||||
public readonly Dictionary<string, ScenarioRewardRecord> ScenarioRewards = [];
|
||||
|
||||
// Note: same data types are intentional
|
||||
[LoadRecord("ProductOfferTable.json", "id", typeof(ProductOfferTable))]
|
||||
[LoadRecord("ProductOfferTable.json", "id")]
|
||||
public readonly Dictionary<int, ProductOfferRecord> ProductOffers = [];
|
||||
|
||||
[LoadRecord("PopupPackageListTable.json", "id", typeof(ProductOfferTable))]
|
||||
[LoadRecord("PopupPackageListTable.json", "id")]
|
||||
public readonly Dictionary<int, ProductOfferRecord> PopupPackages = [];
|
||||
|
||||
[LoadRecord("InterceptNormalTable.json", "id", typeof(InterceptionTable))]
|
||||
[LoadRecord("InterceptNormalTable.json", "id")]
|
||||
public readonly Dictionary<int, InterceptionRecord> InterceptNormal = [];
|
||||
|
||||
[LoadRecord("InterceptSpecialTable.json", "id", typeof(InterceptionTable))]
|
||||
[LoadRecord("InterceptSpecialTable.json", "id")]
|
||||
public readonly Dictionary<int, InterceptionRecord> InterceptSpecial = [];
|
||||
|
||||
[LoadRecord("ConditionRewardTable.json", "id", typeof(ConditionRewardTable))]
|
||||
[LoadRecord("ConditionRewardTable.json", "id")]
|
||||
public readonly Dictionary<int, ConditionRewardRecord> ConditionRewards = [];
|
||||
[LoadRecord("ItemConsumeTable.json", "id", typeof(ItemConsumeTable))]
|
||||
[LoadRecord("ItemConsumeTable.json", "id")]
|
||||
public readonly Dictionary<int, ItemConsumeRecord> ConsumableItems = [];
|
||||
[LoadRecord("ItemRandomTable.json", "id", typeof(RandomItemTable))]
|
||||
[LoadRecord("ItemRandomTable.json", "id")]
|
||||
public readonly Dictionary<int, RandomItemRecord> RandomItem = [];
|
||||
[LoadRecord("LostSectorTable.json", "id", typeof(LostSectorTable))]
|
||||
[LoadRecord("LostSectorTable.json", "id")]
|
||||
public readonly Dictionary<int, LostSectorRecord> LostSector = [];
|
||||
[LoadRecord("LostSectorStageTable.json", "id", typeof(LostSectorStageTable))]
|
||||
[LoadRecord("LostSectorStageTable.json", "id")]
|
||||
public readonly Dictionary<int, LostSectorStageRecord> LostSectorStages = [];
|
||||
[LoadRecord("ItemPieceTable.json", "id", typeof(ItemPieceTable))]
|
||||
[LoadRecord("ItemPieceTable.json", "id")]
|
||||
public readonly Dictionary<int, ItemPieceRecord> PieceItems = [];
|
||||
[LoadRecord("GachaGradeProbTable.json", "id", typeof(GachaGradeProbTable))]
|
||||
[LoadRecord("GachaGradeProbTable.json", "id")]
|
||||
public readonly Dictionary<int, GachaGradeProbRecord> GachaGradeProb = [];
|
||||
[LoadRecord("GachaListProbTable.json", "id", typeof(GachaListProbTable))]
|
||||
[LoadRecord("GachaListProbTable.json", "id")]
|
||||
public readonly Dictionary<int, GachaListProbRecord> GachaListProb = [];
|
||||
[LoadRecord("RecycleResearchStatTable.json", "id", typeof(RecycleResearchStatTable))]
|
||||
[LoadRecord("RecycleResearchStatTable.json", "id")]
|
||||
public readonly Dictionary<int, RecycleResearchStatRecord> RecycleResearchStats = [];
|
||||
[LoadRecord("RecycleResearchLevelTable.json", "id", typeof(RecycleResearchLevelTable))]
|
||||
[LoadRecord("RecycleResearchLevelTable.json", "id")]
|
||||
public readonly Dictionary<int, RecycleResearchLevelRecord> RecycleResearchLevels = [];
|
||||
|
||||
|
||||
static async Task<GameData> BuildAsync()
|
||||
{
|
||||
await Load();
|
||||
@@ -232,7 +238,10 @@ namespace EpinelPS.Data
|
||||
MpkSize = rawBytes2.Length;
|
||||
}
|
||||
|
||||
LoadGameData(filePath, GameConfig.Root.StaticData);
|
||||
if (UseMemoryPack)
|
||||
LoadGameData(mpkFilePath, GameConfig.Root.StaticDataMpk);
|
||||
else
|
||||
LoadGameData(filePath, GameConfig.Root.StaticData);
|
||||
if (MainZip == null) throw new Exception("failed to read zip file");
|
||||
}
|
||||
|
||||
@@ -371,25 +380,49 @@ namespace EpinelPS.Data
|
||||
}
|
||||
#endregion
|
||||
|
||||
public async Task<T> LoadZip<T>(string entry, IProgress<double> bar) where T : new()
|
||||
public async Task<X[]> LoadZip<X>(string entry, IProgress<double> bar) where X : new()
|
||||
{
|
||||
var fileEntry = MainZip.GetEntry(entry);
|
||||
if (fileEntry == null)
|
||||
try
|
||||
{
|
||||
Logging.WriteLine(entry + " does not exist in static data", LogType.Error);
|
||||
return new T();
|
||||
if (UseMemoryPack) entry = entry.Replace(".json", ".mpk");
|
||||
|
||||
var fileEntry = MainZip.GetEntry(entry);
|
||||
if (fileEntry == null)
|
||||
{
|
||||
Logging.WriteLine(entry + " does not exist in static data", LogType.Error);
|
||||
return [];
|
||||
}
|
||||
|
||||
X[]? deserializedObject;
|
||||
|
||||
if (UseMemoryPack)
|
||||
{
|
||||
var stream = MainZip.GetInputStream(fileEntry);
|
||||
deserializedObject = await MemoryPackSerializer.DeserializeAsync<X[]>(stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
using StreamReader fileReader = new(MainZip.GetInputStream(fileEntry));
|
||||
string fileString = await fileReader.ReadToEndAsync();
|
||||
|
||||
var obj = JsonConvert.DeserializeObject<DataTable<X>>(fileString);
|
||||
if (obj == null) throw new Exception("deserializeobject failed");
|
||||
deserializedObject = obj.records.ToArray();
|
||||
}
|
||||
|
||||
if (deserializedObject == null) throw new Exception("failed to parse " + entry);
|
||||
|
||||
currentFile++;
|
||||
bar.Report((double)currentFile / totalFiles);
|
||||
|
||||
return deserializedObject;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"Failed to parse {entry}:\n{ex.ToString()}\n", LogType.Error);
|
||||
return [];
|
||||
}
|
||||
|
||||
using StreamReader fileReader = new(MainZip.GetInputStream(fileEntry));
|
||||
string fileString = await fileReader.ReadToEndAsync();
|
||||
|
||||
T? deserializedObject = JsonConvert.DeserializeObject<T>(fileString);
|
||||
if (deserializedObject == null) throw new Exception("failed to parse " + entry);
|
||||
|
||||
currentFile++;
|
||||
bar.Report((double)currentFile / totalFiles);
|
||||
|
||||
return deserializedObject;
|
||||
}
|
||||
|
||||
public async Task Parse()
|
||||
@@ -397,6 +430,7 @@ namespace EpinelPS.Data
|
||||
using var progress = new ProgressBar();
|
||||
|
||||
totalFiles = GameDataInitializer.TotalFiles;
|
||||
if (totalFiles == 0) throw new Exception("Source generator failed.");
|
||||
|
||||
await GameDataInitializer.InitializeGameData(progress);
|
||||
|
||||
@@ -407,9 +441,9 @@ namespace EpinelPS.Data
|
||||
item.Name.StartsWith("LostSectorMap/")
|
||||
)
|
||||
{
|
||||
var x = await LoadZip<MapInfoTable>(item.Name, progress);
|
||||
var x = await LoadZip<MapInfo>(item.Name, progress);
|
||||
|
||||
foreach (var map in x.records)
|
||||
foreach (var map in x)
|
||||
{
|
||||
MapData.Add(map.id, map);
|
||||
}
|
||||
@@ -540,14 +574,14 @@ namespace EpinelPS.Data
|
||||
|
||||
internal IEnumerable<int> GetStageIdsForChapter(int chapterNumber, bool normal)
|
||||
{
|
||||
string mod = normal ? "Normal" : "Hard";
|
||||
ChapterMod mod = normal ? ChapterMod.Normal : ChapterMod.Hard;
|
||||
foreach (var item in StageDataRecords)
|
||||
{
|
||||
var data = item.Value;
|
||||
|
||||
int chVal = data.chapter_id - 1;
|
||||
|
||||
if (chapterNumber == chVal && data.chapter_mod == mod && data.stage_type == "Main")
|
||||
if (chapterNumber == chVal && data.mod == mod && data.stage_type == StageType.Main)
|
||||
{
|
||||
yield return data.id;
|
||||
}
|
||||
@@ -622,10 +656,10 @@ namespace EpinelPS.Data
|
||||
return false;
|
||||
}
|
||||
|
||||
internal string GetMapIdFromChapter(int chapter, int mod)
|
||||
internal string GetMapIdFromChapter(int chapter, ChapterMod mod)
|
||||
{
|
||||
CampaignChapterRecord data = ChapterCampaignData[chapter - 1];
|
||||
if (mod != 0)
|
||||
if (mod == ChapterMod.Hard)
|
||||
return data.hard_field_id;
|
||||
else return data.field_id;
|
||||
}
|
||||
|
||||
@@ -1,50 +1,148 @@
|
||||
namespace EpinelPS.Data
|
||||
using System.Data;
|
||||
using MemoryPack;
|
||||
|
||||
namespace EpinelPS.Data
|
||||
{
|
||||
public class MainQuestCompletionRecord
|
||||
public class DataTable<T>
|
||||
{
|
||||
public string version { get; set; } = "";
|
||||
public List<T> records { get; set; } = [];
|
||||
}
|
||||
public enum Category
|
||||
{
|
||||
Campaign_View,
|
||||
Outpost_View,
|
||||
Ark_View,
|
||||
Lobby_Enter,
|
||||
Campaign_Enter,
|
||||
Outpost_Building_Enter,
|
||||
Ark_Marker,
|
||||
Campaign_Clear,
|
||||
Outpost_Select,
|
||||
Tribe_Tower_Clear,
|
||||
Tribe_Tower_Enter,
|
||||
Tribe_Tower_View,
|
||||
Run_Gacha,
|
||||
Npc_Talk,
|
||||
FieldObject_Collection,
|
||||
End,
|
||||
LostSector_View,
|
||||
LostSector_Clear,
|
||||
SimulationRoom_View,
|
||||
EventQuest_Stage_Enter,
|
||||
EventQuest_Stage_Clear,
|
||||
EventQuest_Stage_Group_Clear,
|
||||
EventQuest_Popup_Enter,
|
||||
Normal_Chapter_View,
|
||||
Field_Interaction_Action_Trigger,
|
||||
FavoriteItemQuest_Stage_Enter,
|
||||
FavoriteItemQuest_Stage_Clear,
|
||||
FavoriteItemQuest_Stage_Group_Clear,
|
||||
SimulationRoom_Select
|
||||
}
|
||||
public enum ScenarioType
|
||||
{
|
||||
None,
|
||||
FieldTalk,
|
||||
Dialog,
|
||||
Balloon
|
||||
}
|
||||
public enum ChapterMod
|
||||
{
|
||||
Normal,
|
||||
Hard
|
||||
}
|
||||
public enum StageCategory
|
||||
{
|
||||
Normal,
|
||||
Story,
|
||||
Hard,
|
||||
Extra,
|
||||
Boss
|
||||
}
|
||||
public enum StageType
|
||||
{
|
||||
None,
|
||||
Main,
|
||||
Sub,
|
||||
Emergency,
|
||||
EventQuest,
|
||||
FavoriteItemQuest
|
||||
}
|
||||
public enum EquipmentRarityType
|
||||
{
|
||||
None,
|
||||
T1,
|
||||
T2,
|
||||
T3,
|
||||
T4,
|
||||
T5,
|
||||
T6,
|
||||
T7,
|
||||
T8,
|
||||
T9,
|
||||
T10
|
||||
}
|
||||
[MemoryPackable]
|
||||
public partial class MainQuestCompletionRecord
|
||||
{
|
||||
public int id;
|
||||
public int group_id;
|
||||
public string category = "";
|
||||
public Category category;
|
||||
public int condition_id;
|
||||
public string condition_ui_localkey = "";
|
||||
public string shortcut_type = "";
|
||||
public int shortcut_value;
|
||||
public string name_localkey = "";
|
||||
public string description_localkey = "";
|
||||
public int next_main_quest_id = 0;
|
||||
public int reward_id = 0;
|
||||
public ScenarioType scenario_type;
|
||||
public string episode_id = "";
|
||||
public int target_chapter_id;
|
||||
public string header_bg_resource_id = "";
|
||||
}
|
||||
public class MainQuestCompletionTable
|
||||
{
|
||||
public List<MainQuestCompletionRecord> records = [];
|
||||
}
|
||||
public class CampaignStageRecord
|
||||
[MemoryPackable]
|
||||
public partial class CampaignStageRecord
|
||||
{
|
||||
public int id;
|
||||
public int chapter_id;
|
||||
public string stage_category = "";
|
||||
public ChapterMod mod;
|
||||
public int parent_id;
|
||||
public int group_id;
|
||||
public string name = "";
|
||||
public StageCategory stage_category;
|
||||
public StageType stage_type;
|
||||
public bool allow_autobattle;
|
||||
public int enter_condition;
|
||||
public int monster_stage_level;
|
||||
public int dynobj_stage_level;
|
||||
public int standard_battle_power;
|
||||
public int statinc_groupid;
|
||||
public bool allow_quickbattle;
|
||||
public int fieldmonster_id;
|
||||
public int spotid;
|
||||
public int reward_id = 0;
|
||||
/// <summary>
|
||||
/// Can be Normal or Hard
|
||||
/// </summary>
|
||||
public string chapter_mod = "";
|
||||
public string stage_type = "";
|
||||
public ScenarioType enter_scenario_type;
|
||||
public string enter_scenario = "";
|
||||
public ScenarioType exit_scenario_type;
|
||||
public string exit_scenario = "";
|
||||
public int current_outpost_battle_id;
|
||||
public int cleared_battleid;
|
||||
public int fixedCharacterid;
|
||||
public int characterLevel;
|
||||
}
|
||||
public class CampaignStageTable
|
||||
{
|
||||
public List<CampaignStageRecord> records = [];
|
||||
}
|
||||
public class RewardTableRecord
|
||||
[MemoryPackable]
|
||||
public partial class RewardTableRecord
|
||||
{
|
||||
public int id;
|
||||
public int user_exp;
|
||||
public int character_exp;
|
||||
public RewardEntry[]? rewards;
|
||||
}
|
||||
public class RewardTable
|
||||
{
|
||||
public List<RewardTableRecord> records = [];
|
||||
}
|
||||
|
||||
public class RewardEntry
|
||||
[MemoryPackable]
|
||||
public partial class RewardEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// example: 1000000
|
||||
@@ -55,8 +153,6 @@
|
||||
public int reward_id;
|
||||
public int reward_value;
|
||||
}
|
||||
|
||||
|
||||
public class ClearedTutorialData
|
||||
{
|
||||
public int id;
|
||||
@@ -66,12 +162,8 @@
|
||||
public int NextId;
|
||||
public bool SaveTutorial;
|
||||
}
|
||||
public class TutorialTable
|
||||
{
|
||||
public List<ClearedTutorialData> records = [];
|
||||
}
|
||||
|
||||
public class CharacterLevelData
|
||||
[MemoryPackable]
|
||||
public partial class CharacterLevelData
|
||||
{
|
||||
/// <summary>
|
||||
/// level
|
||||
@@ -94,17 +186,13 @@
|
||||
/// </summary>
|
||||
public int character_exp2 = 0;
|
||||
}
|
||||
public class CharacterLevelTable
|
||||
{
|
||||
public List<CharacterLevelData> records = [];
|
||||
}
|
||||
|
||||
public class TacticAcademyLessonReward
|
||||
{
|
||||
public int lesson_reward_id;
|
||||
public int lesson_reward_value;
|
||||
}
|
||||
public class TacticAcademyLessonRecord
|
||||
[MemoryPackable]
|
||||
public partial class TacticAcademyLessonRecord
|
||||
{
|
||||
public int currency_id;
|
||||
public int currency_value;
|
||||
@@ -114,24 +202,16 @@
|
||||
public TacticAcademyLessonReward[]? lesson_reward;
|
||||
}
|
||||
|
||||
public class TacticAcademyLessonTable
|
||||
{
|
||||
public List<TacticAcademyLessonRecord> records = [];
|
||||
}
|
||||
|
||||
public class CampaignChapterRecord
|
||||
[MemoryPackable]
|
||||
public partial class CampaignChapterRecord
|
||||
{
|
||||
public int id;
|
||||
public int chapter;
|
||||
public string field_id = "";
|
||||
public string hard_field_id = "";
|
||||
}
|
||||
public class CampaignChapterTable
|
||||
{
|
||||
public List<CampaignChapterRecord> records = [];
|
||||
}
|
||||
|
||||
public class CharacterRecord
|
||||
[MemoryPackable]
|
||||
public partial class CharacterRecord
|
||||
{
|
||||
public int id;
|
||||
public int piece_id;
|
||||
@@ -169,12 +249,9 @@
|
||||
public bool prism_is_active;
|
||||
public bool is_detail_close;
|
||||
}
|
||||
public class CharacterTable
|
||||
{
|
||||
public List<CharacterRecord> records = [];
|
||||
}
|
||||
|
||||
public class ItemEquipRecord
|
||||
[MemoryPackable]
|
||||
public partial class ItemEquipRecord
|
||||
{
|
||||
public int id;
|
||||
public string name_localkey = "";
|
||||
@@ -204,12 +281,9 @@
|
||||
public int option_slot;
|
||||
public int option_slot_success_ratio;
|
||||
}
|
||||
public class ItemEquipTable
|
||||
{
|
||||
public List<ItemEquipRecord> records = [];
|
||||
}
|
||||
|
||||
public class FieldItemRecord
|
||||
[MemoryPackable]
|
||||
public partial class FieldItemRecord
|
||||
{
|
||||
public int id;
|
||||
public string item_type = "";
|
||||
@@ -217,11 +291,9 @@
|
||||
public bool is_final_reward;
|
||||
public string difficulty = "";
|
||||
}
|
||||
public class FieldItemTable
|
||||
{
|
||||
public List<FieldItemRecord> records = [];
|
||||
}
|
||||
public class JukeboxListRecord
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class JukeboxListRecord
|
||||
{
|
||||
public int id;
|
||||
public int theme;
|
||||
@@ -235,12 +307,8 @@
|
||||
public string get_info_value = "";
|
||||
}
|
||||
|
||||
public class JukeboxListTable
|
||||
{
|
||||
public List<JukeboxListRecord> records = [];
|
||||
}
|
||||
|
||||
public class JukeboxThemeRecord
|
||||
[MemoryPackable]
|
||||
public partial class JukeboxThemeRecord
|
||||
{
|
||||
public int id;
|
||||
public string name_localkey = "";
|
||||
@@ -250,11 +318,8 @@
|
||||
public string bg_color = "";
|
||||
}
|
||||
|
||||
public class JukeboxThemeTable
|
||||
{
|
||||
public List<JukeboxThemeRecord> records = [];
|
||||
}
|
||||
public class OutpostBattleTableRecord
|
||||
[MemoryPackable]
|
||||
public partial class OutpostBattleTableRecord
|
||||
{
|
||||
public int id;
|
||||
public int credit;
|
||||
@@ -262,12 +327,9 @@
|
||||
public int character_exp2;
|
||||
public int user_exp;
|
||||
}
|
||||
public class OutpostBattleTable
|
||||
{
|
||||
public List<OutpostBattleTableRecord> records = [];
|
||||
}
|
||||
|
||||
public class GachaPriceGroup
|
||||
[MemoryPackable]
|
||||
public partial class GachaPriceGroup
|
||||
{
|
||||
public int gacha_price_type;
|
||||
public int gacha_price_value_count_1;
|
||||
@@ -275,7 +337,7 @@
|
||||
public int gacha_price_value_count_10;
|
||||
}
|
||||
|
||||
public class GachaType
|
||||
public partial class GachaType
|
||||
{
|
||||
public int id;
|
||||
public string type = "";
|
||||
@@ -298,12 +360,8 @@
|
||||
public int previous_gacha_id;
|
||||
}
|
||||
|
||||
public class GachaTypeTable
|
||||
{
|
||||
public List<GachaType> records = [];
|
||||
}
|
||||
|
||||
public class GachaGradeProbRecord
|
||||
[MemoryPackable]
|
||||
public partial class GachaGradeProbRecord
|
||||
{
|
||||
public int id;
|
||||
public int group_id;
|
||||
@@ -311,23 +369,16 @@
|
||||
public int prob;
|
||||
public int gacha_list_id;
|
||||
}
|
||||
public class GachaGradeProbTable
|
||||
{
|
||||
public List<GachaGradeProbRecord> records = [];
|
||||
}
|
||||
|
||||
public class GachaListProbRecord
|
||||
[MemoryPackable]
|
||||
public partial class GachaListProbRecord
|
||||
{
|
||||
public int id;
|
||||
public int group_id;
|
||||
public int gacha_id;
|
||||
}
|
||||
public class GachaListProbTable
|
||||
{
|
||||
public List<GachaListProbRecord> records = [];
|
||||
}
|
||||
|
||||
public class EventManager
|
||||
[MemoryPackable]
|
||||
public partial class EventManager
|
||||
{
|
||||
public int id;
|
||||
public string event_system_type = "";
|
||||
@@ -348,23 +399,17 @@
|
||||
public string active_type = "";
|
||||
public string banner_print_type = "";
|
||||
}
|
||||
[MemoryPackable]
|
||||
|
||||
public class EventManagerTable
|
||||
{
|
||||
public List<EventManager> records = [];
|
||||
}
|
||||
|
||||
public class LiveWallpaperRecord
|
||||
public partial class LiveWallpaperRecord
|
||||
{
|
||||
public int id;
|
||||
public string livewallpaper_type = "";
|
||||
}
|
||||
[MemoryPackable]
|
||||
|
||||
public class LiveWallpaperTable
|
||||
{
|
||||
public List<LiveWallpaperRecord> records = [];
|
||||
}
|
||||
public class AlbumResourceRecord
|
||||
public partial class AlbumResourceRecord
|
||||
{
|
||||
public int id;
|
||||
public int sub_category_id;
|
||||
@@ -376,12 +421,9 @@
|
||||
public string dialogtype = "";
|
||||
}
|
||||
|
||||
public class AlbumResourceTable
|
||||
{
|
||||
public List<AlbumResourceRecord> records = [];
|
||||
}
|
||||
|
||||
public class UserFrameTableRecord
|
||||
[MemoryPackable]
|
||||
public partial class UserFrameTableRecord
|
||||
{
|
||||
public int id;
|
||||
public string resource_id = "";
|
||||
@@ -394,12 +436,9 @@
|
||||
public bool is_sub_resource_prism;
|
||||
}
|
||||
|
||||
public class UserFrameTable
|
||||
{
|
||||
public List<UserFrameTableRecord> records = [];
|
||||
}
|
||||
|
||||
public class ArchiveRecordManagerRecord
|
||||
[MemoryPackable]
|
||||
public partial class ArchiveRecordManagerRecord
|
||||
{
|
||||
public int id;
|
||||
public string record_type = "";
|
||||
@@ -416,12 +455,9 @@
|
||||
public string record_unlock_bg_addressable = "";
|
||||
}
|
||||
|
||||
public class ArchiveRecordManagerTable
|
||||
{
|
||||
public List<ArchiveRecordManagerRecord> records = [];
|
||||
}
|
||||
|
||||
public class ArchiveEventStoryRecord
|
||||
[MemoryPackable]
|
||||
public partial class ArchiveEventStoryRecord
|
||||
{
|
||||
public int id;
|
||||
public int event_id;
|
||||
@@ -433,12 +469,9 @@
|
||||
public int archive_currency_item_id;
|
||||
}
|
||||
|
||||
public class ArchiveEventStoryTable
|
||||
{
|
||||
public List<ArchiveEventStoryRecord> records = [];
|
||||
}
|
||||
|
||||
public class ArchiveEventQuestRecord
|
||||
[MemoryPackable]
|
||||
public partial class ArchiveEventQuestRecord
|
||||
{
|
||||
public int id;
|
||||
public int event_quest_manager_id;
|
||||
@@ -450,12 +483,9 @@
|
||||
public string end_scenario_id = "";
|
||||
}
|
||||
|
||||
public class ArchiveEventQuestTable
|
||||
{
|
||||
public List<ArchiveEventQuestRecord> records = [];
|
||||
}
|
||||
|
||||
public class ArchiveEventDungeonStageRecord
|
||||
[MemoryPackable]
|
||||
public partial class ArchiveEventDungeonStageRecord
|
||||
{
|
||||
public int id;
|
||||
public int group;
|
||||
@@ -466,11 +496,8 @@
|
||||
public bool is_repeat_clear;
|
||||
}
|
||||
|
||||
public class ArchiveEventDungeonStageTable
|
||||
{
|
||||
public List<ArchiveEventDungeonStageRecord> records = [];
|
||||
}
|
||||
public class UserTitleRecord
|
||||
[MemoryPackable]
|
||||
public partial class UserTitleRecord
|
||||
{
|
||||
public int id;
|
||||
public int order;
|
||||
@@ -483,32 +510,23 @@
|
||||
public bool not_acquired_is_visible;
|
||||
}
|
||||
|
||||
public class UserTitleTable
|
||||
{
|
||||
public List<UserTitleRecord> records = [];
|
||||
}
|
||||
|
||||
public class ArchiveMessengerConditionList
|
||||
[MemoryPackable]
|
||||
public partial class ArchiveMessengerConditionList
|
||||
{
|
||||
public string condition_type = "";
|
||||
public int condition_id;
|
||||
}
|
||||
|
||||
public class ArchiveMessengerConditionRecord
|
||||
[MemoryPackable]
|
||||
public partial class ArchiveMessengerConditionRecord
|
||||
{
|
||||
public int id;
|
||||
public int archive_messenger_group_id;
|
||||
public List<ArchiveMessengerConditionList> archive_messenger_condition_list = [];
|
||||
public string tid = "";
|
||||
}
|
||||
|
||||
public class ArchiveMessengerConditionTable
|
||||
{
|
||||
public string version = "";
|
||||
public List<ArchiveMessengerConditionRecord> records = [];
|
||||
}
|
||||
|
||||
public class CharacterStatRecord
|
||||
[MemoryPackable]
|
||||
public partial class CharacterStatRecord
|
||||
{
|
||||
public int id;
|
||||
public int group;
|
||||
@@ -520,12 +538,8 @@
|
||||
public int level_bio_resist;
|
||||
}
|
||||
|
||||
public class CharacterStatTable
|
||||
{
|
||||
public List<CharacterStatRecord> records = [];
|
||||
}
|
||||
|
||||
public class ItemMaterialRecord
|
||||
[MemoryPackable]
|
||||
public partial class ItemMaterialRecord
|
||||
{
|
||||
public int id;
|
||||
public string name_localkey = "";
|
||||
@@ -540,12 +554,9 @@
|
||||
public int stack_max;
|
||||
}
|
||||
|
||||
public class ItemMaterialTable
|
||||
{
|
||||
public List<ItemMaterialRecord> records = [];
|
||||
}
|
||||
|
||||
public class SkillInfoRecord
|
||||
[MemoryPackable]
|
||||
public partial class SkillInfoRecord
|
||||
{
|
||||
public int id;
|
||||
public int group_id;
|
||||
@@ -564,11 +575,6 @@
|
||||
public string description_value = "";
|
||||
}
|
||||
|
||||
public class SkillInfoTable
|
||||
{
|
||||
public List<SkillInfoRecord> records = [];
|
||||
}
|
||||
|
||||
public class CostRecord
|
||||
{
|
||||
public int id;
|
||||
@@ -582,11 +588,8 @@
|
||||
public int item_value;
|
||||
}
|
||||
|
||||
public class CostTable
|
||||
{
|
||||
public List<CostRecord> records = [];
|
||||
}
|
||||
public class MidasProductRecord
|
||||
[MemoryPackable]
|
||||
public partial class MidasProductRecord
|
||||
{
|
||||
public int id;
|
||||
public string product_type = "";
|
||||
@@ -597,10 +600,7 @@
|
||||
public bool is_free;
|
||||
public string cost = "";
|
||||
}
|
||||
public class MidasProductTable
|
||||
{
|
||||
public List<MidasProductRecord> records = [];
|
||||
}
|
||||
|
||||
public enum ShopCategoryType
|
||||
{
|
||||
None = 0,
|
||||
@@ -613,7 +613,8 @@
|
||||
Mileage = 7,
|
||||
Trade = 8
|
||||
}
|
||||
public class TowerRecord
|
||||
[MemoryPackable]
|
||||
public partial class TowerRecord
|
||||
{
|
||||
public int id;
|
||||
public int floor;
|
||||
@@ -621,12 +622,9 @@
|
||||
public int standard_battle_power;
|
||||
public int reward_id;
|
||||
}
|
||||
public class TowerTable
|
||||
{
|
||||
public List<TowerRecord> records = [];
|
||||
}
|
||||
|
||||
public class ItemEquipExpRecord
|
||||
[MemoryPackable]
|
||||
public partial class ItemEquipExpRecord
|
||||
{
|
||||
public int id;
|
||||
public int level;
|
||||
@@ -635,56 +633,39 @@
|
||||
public int grade_core_id;
|
||||
}
|
||||
|
||||
public class ItemEquipExpTable
|
||||
{
|
||||
public List<ItemEquipExpRecord> records = [];
|
||||
}
|
||||
|
||||
public class ItemEquipGradeExpRecord
|
||||
[MemoryPackable]
|
||||
public partial class ItemEquipGradeExpRecord
|
||||
{
|
||||
public int id;
|
||||
public int exp;
|
||||
public string item_rare = "";
|
||||
public EquipmentRarityType item_rare;
|
||||
public int grade_core_id;
|
||||
public int exp;
|
||||
}
|
||||
|
||||
public class ItemEquipGradeExpTable
|
||||
{
|
||||
public List<ItemEquipGradeExpRecord> records = [];
|
||||
}
|
||||
|
||||
public class UserExpRecord
|
||||
[MemoryPackable]
|
||||
public partial class UserExpRecord
|
||||
{
|
||||
public int level;
|
||||
public int exp;
|
||||
public int reward_id;
|
||||
}
|
||||
public class UserExpTable
|
||||
{
|
||||
public List<UserExpRecord> records = [];
|
||||
}
|
||||
|
||||
public class CharacterCostumeRecord
|
||||
[MemoryPackable]
|
||||
public partial class CharacterCostumeRecord
|
||||
{
|
||||
public int id;
|
||||
}
|
||||
public class CharacterCostumeTable
|
||||
{
|
||||
public List<CharacterCostumeRecord> records = [];
|
||||
}
|
||||
|
||||
public class SideStoryStageRecord
|
||||
[MemoryPackable]
|
||||
public partial class SideStoryStageRecord
|
||||
{
|
||||
public int id;
|
||||
public int first_clear_reward;
|
||||
}
|
||||
|
||||
public class SideStoryStageTable
|
||||
{
|
||||
public List<SideStoryStageRecord> records = [];
|
||||
}
|
||||
|
||||
public class TriggerRecord
|
||||
[MemoryPackable]
|
||||
public partial class TriggerRecord
|
||||
{
|
||||
public int id;
|
||||
public int condition_id;
|
||||
@@ -694,15 +675,13 @@
|
||||
public bool print_value;
|
||||
public int before_trigger_id;
|
||||
}
|
||||
public class TriggerTable
|
||||
{
|
||||
public List<TriggerRecord> records = [];
|
||||
}
|
||||
|
||||
public class InfracoreFunction
|
||||
{
|
||||
public int function;
|
||||
}
|
||||
public class InfracoreRecord
|
||||
[MemoryPackable]
|
||||
public partial class InfracoreRecord
|
||||
{
|
||||
public int id;
|
||||
public int grade;
|
||||
@@ -710,22 +689,16 @@
|
||||
public int infra_core_exp;
|
||||
public List<InfracoreFunction> function_list = [];
|
||||
}
|
||||
public class InfracoreTable
|
||||
{
|
||||
public List<InfracoreRecord> records = [];
|
||||
}
|
||||
public class AttractiveCounselCharacterRecord
|
||||
[MemoryPackable]
|
||||
public partial class AttractiveCounselCharacterRecord
|
||||
{
|
||||
public int id;
|
||||
public int name_code;
|
||||
public int collect_reward_id;
|
||||
}
|
||||
public class AttractiveCounselCharacterTable
|
||||
{
|
||||
public List<AttractiveCounselCharacterRecord> records = [];
|
||||
}
|
||||
|
||||
public class AttractiveLevelRewardRecord
|
||||
[MemoryPackable]
|
||||
public partial class AttractiveLevelRewardRecord
|
||||
{
|
||||
public int id;
|
||||
public int name_code;
|
||||
@@ -733,11 +706,8 @@
|
||||
public int attractive_level;
|
||||
public int costume;
|
||||
}
|
||||
public class AttractiveLevelRewardTable
|
||||
{
|
||||
public List<AttractiveLevelRewardRecord> records = [];
|
||||
}
|
||||
public class SubquestRecord
|
||||
[MemoryPackable]
|
||||
public partial class SubquestRecord
|
||||
{
|
||||
public int id;
|
||||
public int group_id;
|
||||
@@ -747,11 +717,9 @@
|
||||
public string end_messenger_conversation_id = "";
|
||||
public int before_sub_quest_id;
|
||||
}
|
||||
public class SubquestTable
|
||||
{
|
||||
public List<SubquestRecord> records = [];
|
||||
}
|
||||
public class MessengerDialogRecord
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class MessengerDialogRecord
|
||||
{
|
||||
public string id = "";
|
||||
public string conversation_id = "";
|
||||
@@ -759,41 +727,36 @@
|
||||
public bool is_opener;
|
||||
public int reward_id;
|
||||
}
|
||||
public class MessengerDialogTable
|
||||
{
|
||||
public List<MessengerDialogRecord> records = [];
|
||||
}
|
||||
public class MessengerMsgConditionRecord
|
||||
[MemoryPackable]
|
||||
public partial class MessengerMsgConditionRecord
|
||||
{
|
||||
public int id;
|
||||
public string tid = "";
|
||||
public int reward_id;
|
||||
}
|
||||
public class MessengerMsgConditionTable
|
||||
public enum ScenarioRewardCondition
|
||||
{
|
||||
public List<MessengerMsgConditionRecord> records = [];
|
||||
}
|
||||
public class ScenarioRewardRecord
|
||||
{
|
||||
public int id;
|
||||
public string condition_id = "";
|
||||
public string condition_type = "";
|
||||
public int reward_id;
|
||||
}
|
||||
public class ScenarioRewardTable
|
||||
{
|
||||
public List<ScenarioRewardRecord> records = [];
|
||||
MainScenario,
|
||||
AttractiveScenario
|
||||
}
|
||||
|
||||
public class ProductOfferRecord
|
||||
[MemoryPackable]
|
||||
public partial class ScenarioRewardRecord
|
||||
{
|
||||
public int id;
|
||||
public ScenarioRewardCondition condition_type;
|
||||
public string condition_id = "";
|
||||
public int reward_id;
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class ProductOfferRecord
|
||||
{
|
||||
public int id;
|
||||
}
|
||||
public class ProductOfferTable
|
||||
{
|
||||
public List<ProductOfferRecord> records = [];
|
||||
}
|
||||
public class InterceptionRecord
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class InterceptionRecord
|
||||
{
|
||||
public int id;
|
||||
public int group;
|
||||
@@ -801,11 +764,9 @@
|
||||
public int percent_condition_reward_group;
|
||||
public long fixed_damage;
|
||||
}
|
||||
public class InterceptionTable
|
||||
{
|
||||
public List<InterceptionRecord> records = [];
|
||||
}
|
||||
public class ConditionRewardRecord
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class ConditionRewardRecord
|
||||
{
|
||||
public int id;
|
||||
public int group;
|
||||
@@ -814,10 +775,7 @@
|
||||
public long value_max;
|
||||
public int reward_id;
|
||||
}
|
||||
public class ConditionRewardTable
|
||||
{
|
||||
public List<ConditionRewardRecord> records = [];
|
||||
}
|
||||
|
||||
public enum ItemSubType
|
||||
{
|
||||
BundleBox,
|
||||
@@ -829,7 +787,8 @@
|
||||
ArcadeItem,
|
||||
EquipCombination
|
||||
}
|
||||
public class ItemConsumeRecord
|
||||
[MemoryPackable]
|
||||
public partial class ItemConsumeRecord
|
||||
{
|
||||
public int id;
|
||||
public string use_type = "";
|
||||
@@ -838,22 +797,18 @@
|
||||
public int use_id;
|
||||
public int use_value;
|
||||
}
|
||||
public class ItemConsumeTable
|
||||
{
|
||||
public List<ItemConsumeRecord> records = [];
|
||||
}
|
||||
public class ItemPieceRecord
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class ItemPieceRecord
|
||||
{
|
||||
public int id;
|
||||
public string use_type = "";
|
||||
public int use_id;
|
||||
public int use_value;
|
||||
}
|
||||
public class ItemPieceTable
|
||||
{
|
||||
public List<ItemPieceRecord> records = [];
|
||||
}
|
||||
public class RandomItemRecord
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class RandomItemRecord
|
||||
{
|
||||
public int id;
|
||||
public int group_id;
|
||||
@@ -863,11 +818,9 @@
|
||||
public int reward_value_max;
|
||||
public int ratio;
|
||||
}
|
||||
public class RandomItemTable
|
||||
{
|
||||
public List<RandomItemRecord> records = [];
|
||||
}
|
||||
public class RecycleResearchStatRecord
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class RecycleResearchStatRecord
|
||||
{
|
||||
public int id;
|
||||
public string recycle_type = "";
|
||||
@@ -877,11 +830,9 @@
|
||||
public int defense;
|
||||
public int hp;
|
||||
}
|
||||
public class RecycleResearchStatTable
|
||||
{
|
||||
public List<RecycleResearchStatRecord> records = [];
|
||||
}
|
||||
public class RecycleResearchLevelRecord
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class RecycleResearchLevelRecord
|
||||
{
|
||||
public int id;
|
||||
public string recycle_type = "";
|
||||
@@ -890,16 +841,15 @@
|
||||
public int item_id;
|
||||
public int item_value;
|
||||
}
|
||||
public class RecycleResearchLevelTable
|
||||
{
|
||||
public List<RecycleResearchLevelRecord> records = [];
|
||||
}
|
||||
|
||||
public enum ContentOpenType
|
||||
{
|
||||
Stage,
|
||||
NonUpdate
|
||||
}
|
||||
public class LostSectorRecord
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class LostSectorRecord
|
||||
{
|
||||
public int id;
|
||||
public int sector;
|
||||
@@ -910,20 +860,14 @@
|
||||
public int open_condition_value;
|
||||
|
||||
}
|
||||
public class LostSectorTable
|
||||
{
|
||||
public List<LostSectorRecord> records = [];
|
||||
}
|
||||
public class LostSectorStageRecord
|
||||
[MemoryPackable]
|
||||
public partial class LostSectorStageRecord
|
||||
{
|
||||
public int id;
|
||||
public bool is_use_quick_battle;
|
||||
public int sector;
|
||||
}
|
||||
public class LostSectorStageTable
|
||||
{
|
||||
public List<LostSectorStageRecord> records = [];
|
||||
}
|
||||
|
||||
|
||||
public class ItemSpawner
|
||||
{
|
||||
@@ -936,14 +880,13 @@
|
||||
public string positionId = "";
|
||||
public int stageId;
|
||||
}
|
||||
public class MapInfo
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class MapInfo
|
||||
{
|
||||
public string id { get; set; } = "";
|
||||
public List<ItemSpawner> ItemSpawner { get; set; } = [];
|
||||
public List<StageSpawner> StageSpawner { get; set; } = [];
|
||||
}
|
||||
public class MapInfoTable
|
||||
{
|
||||
public List<MapInfo> records = [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,10 +2,9 @@ namespace EpinelPS.Data
|
||||
{
|
||||
[System.AttributeUsage(System.AttributeTargets.Field)]
|
||||
|
||||
public class LoadRecordAttribute(string file, string primaryKey, Type tableType) : Attribute
|
||||
public class LoadRecordAttribute(string file, string primaryKey) : Attribute
|
||||
{
|
||||
public string File { get; set; } = file;
|
||||
public string PrimaryKey { get; set; } = primaryKey;
|
||||
public Type TableType { get; set; } = tableType;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@
|
||||
<PackageReference Include="Google.Api.CommonProtos" Version="2.17.0" />
|
||||
<PackageReference Include="Google.Protobuf.Tools" Version="3.31.1" />
|
||||
<PackageReference Include="Grpc.AspNetCore" Version="2.71.0" />
|
||||
<PackageReference Include="MemoryPack" Version="1.21.4" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Paseto.Core" Version="1.4.1" />
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace EpinelPS.LobbyServer.Stage
|
||||
var response = new ResClearStage();
|
||||
var clearedStage = GameData.Instance.GetStageData(StageId) ?? throw new Exception("cleared stage cannot be null");
|
||||
|
||||
var stageMapId = GameData.Instance.GetMapIdFromChapter(clearedStage.chapter_id, clearedStage.chapter_mod);
|
||||
var stageMapId = GameData.Instance.GetMapIdFromChapter(clearedStage.chapter_id, clearedStage.mod);
|
||||
|
||||
if (user.FieldInfoNew.Count == 0)
|
||||
{
|
||||
@@ -89,33 +89,29 @@ namespace EpinelPS.LobbyServer.Stage
|
||||
});
|
||||
}
|
||||
|
||||
if (clearedStage.stage_category == "Normal" || clearedStage.stage_category == "Boss" || clearedStage.stage_category == "Hard")
|
||||
if (clearedStage.stage_category == StageCategory.Normal || clearedStage.stage_category == StageCategory.Boss || clearedStage.stage_category == StageCategory.Hard)
|
||||
{
|
||||
if (clearedStage.chapter_mod == "Hard")
|
||||
if (clearedStage.mod == ChapterMod.Hard)
|
||||
{
|
||||
if (StageId > user.LastHardStageCleared)
|
||||
user.LastHardStageCleared = StageId;
|
||||
}
|
||||
else if (clearedStage.chapter_mod == "Normal")
|
||||
else
|
||||
{
|
||||
if (StageId > user.LastNormalStageCleared)
|
||||
user.LastNormalStageCleared = StageId;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unknown chapter mod " + clearedStage.chapter_mod);
|
||||
}
|
||||
}
|
||||
else if (clearedStage.stage_category == "Extra")
|
||||
else if (clearedStage.stage_category == StageCategory.Extra)
|
||||
{
|
||||
|
||||
// TODO
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unknown stage category " + clearedStage.stage_category);
|
||||
}
|
||||
|
||||
if (clearedStage.stage_type != "Sub")
|
||||
if (clearedStage.stage_type != StageType.Sub)
|
||||
{
|
||||
// add outpost reward level if unlocked
|
||||
if (user.MainQuestData.TryGetValue(21, out bool _))
|
||||
@@ -137,9 +133,9 @@ namespace EpinelPS.LobbyServer.Stage
|
||||
|
||||
|
||||
// Mark chapter as completed if boss stage was completed
|
||||
if (clearedStage.stage_category == "Boss" && clearedStage.stage_type == "Main")
|
||||
if (clearedStage.stage_category == StageCategory.Boss && clearedStage.stage_type == StageType.Main)
|
||||
{
|
||||
if (clearedStage.chapter_mod == "Hard")
|
||||
if (clearedStage.mod == ChapterMod.Hard)
|
||||
user.AddTrigger(TriggerType.HardChapterClear, 1, clearedStage.chapter_id);
|
||||
else
|
||||
user.AddTrigger(TriggerType.ChapterClear, 1, clearedStage.chapter_id);
|
||||
|
||||
@@ -15,9 +15,9 @@ namespace EpinelPS.LobbyServer.Stage
|
||||
var response = new ResEnterStage();
|
||||
|
||||
var clearedStage = GameData.Instance.GetStageData(req.StageId) ?? throw new Exception("cleared stage cannot be null");
|
||||
var map = GameData.Instance.GetMapIdFromChapter(clearedStage.chapter_id, clearedStage.chapter_id);
|
||||
var map = GameData.Instance.GetMapIdFromChapter(clearedStage.chapter_id, clearedStage.mod);
|
||||
|
||||
if (clearedStage.stage_category == "Boss")
|
||||
if (clearedStage.stage_category == StageCategory.Boss)
|
||||
{
|
||||
// When entering a boss stage, unlock boss information in campaign
|
||||
if (!user.FieldInfoNew.ContainsKey(map))
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace EpinelPS.LobbyServer.Stage
|
||||
ReqGetStageData req = await ReadData<ReqGetStageData>();
|
||||
var user = GetUser();
|
||||
|
||||
var mapId = GameData.Instance.GetMapIdFromChapter(req.Chapter, req.Mod);
|
||||
var mapId = GameData.Instance.GetMapIdFromChapter(req.Chapter, (ChapterMod)req.Mod);
|
||||
|
||||
ResGetStageData response = new()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user