mirror of
https://github.com/EpinelPS/EpinelPS.git
synced 2025-12-14 07:55:01 +01:00
Experimental archive support
Note archive event returns to stage 1 if hard mode is played and left unfinished quick battle doesnt work as well Prolouge always plays
This commit is contained in:
@@ -62,6 +62,8 @@ namespace EpinelPS.Database
|
||||
public class EventData
|
||||
{
|
||||
public List<string> CompletedScenarios = new();
|
||||
public int Diff = 0; // Default value for Diff
|
||||
public int LastStage = 0; // Default value for LastStage
|
||||
}
|
||||
|
||||
public class SynchroSlot
|
||||
|
||||
@@ -48,6 +48,10 @@ namespace EpinelPS.StaticInfo
|
||||
public Dictionary<int, LiveWallpaperRecord> lwptablemgrs = new Dictionary<int, LiveWallpaperRecord>(); // Fixed initialization
|
||||
private Dictionary<int, AlbumResourceRecord> albumResourceRecords = new Dictionary<int, AlbumResourceRecord>();
|
||||
public Dictionary<int, UserFrameTableRecord> userFrameTable = new Dictionary<int, UserFrameTableRecord>();
|
||||
public Dictionary<int, ArchiveRecordManagerRecord> archiveRecordManagerTable = new Dictionary<int, ArchiveRecordManagerRecord>();
|
||||
public Dictionary<int, ArchiveEventStoryRecord> archiveEventStoryRecords = new Dictionary<int, ArchiveEventStoryRecord>();
|
||||
public Dictionary<int, ArchiveEventQuestRecord> archiveEventQuestRecords = new Dictionary<int, ArchiveEventQuestRecord>();
|
||||
public Dictionary<int, ArchiveEventDungeonStageRecord> archiveEventDungeonStageRecords = new Dictionary<int, ArchiveEventDungeonStageRecord>();
|
||||
|
||||
|
||||
|
||||
@@ -377,6 +381,12 @@ namespace EpinelPS.StaticInfo
|
||||
{
|
||||
OutpostBattle.Add(obj.id, obj);
|
||||
}
|
||||
|
||||
var archiveRecordManagerTableData = await LoadZip<ArchiveRecordManagerTable>("ArchiveRecordManagerTable.json", progress);
|
||||
foreach (var obj in archiveRecordManagerTableData.records)
|
||||
{
|
||||
archiveRecordManagerTable.Add(obj.id, obj);
|
||||
}
|
||||
|
||||
var gachaTypeTable = await LoadZip<GachaTypeTable>("GachaTypeTable.json", progress);
|
||||
|
||||
@@ -407,6 +417,26 @@ namespace EpinelPS.StaticInfo
|
||||
{
|
||||
userFrameTable[record.id] = record;
|
||||
}
|
||||
// Load and parse ArchiveEventDungeonStageTable.json
|
||||
var archiveEventDungeonStageData = await LoadZip<ArchiveEventDungeonStageTable>("ArchiveEventDungeonStageTable.json", progress);
|
||||
foreach (var obj in archiveEventDungeonStageData.records)
|
||||
{
|
||||
archiveEventDungeonStageRecords.Add(obj.id, obj);
|
||||
}
|
||||
|
||||
// Load and parse ArchiveEventStoryTable.json
|
||||
var archiveEventStoryTable = await LoadZip<ArchiveEventStoryTable>("ArchiveEventStoryTable.json", progress);
|
||||
foreach (var obj in archiveEventStoryTable.records)
|
||||
{
|
||||
archiveEventStoryRecords.Add(obj.id, obj);
|
||||
}
|
||||
|
||||
// Load and parse ArchiveEventQuestTable.json
|
||||
var archiveEventQuestTable = await LoadZip<ArchiveEventQuestTable>("ArchiveEventQuestTable.json", progress);
|
||||
foreach (var obj in archiveEventQuestTable.records)
|
||||
{
|
||||
archiveEventQuestRecords.Add(obj.id, obj);
|
||||
}
|
||||
|
||||
var albumResourceTable = await LoadZip<AlbumResourceTable>("AlbumResourceTable.json", progress);
|
||||
foreach (var obj in albumResourceTable.records)
|
||||
|
||||
@@ -317,5 +317,77 @@
|
||||
{
|
||||
public List<UserFrameTableRecord> records;
|
||||
}
|
||||
|
||||
public class ArchiveRecordManagerRecord
|
||||
{
|
||||
public int id;
|
||||
public string record_type;
|
||||
public string record_title_locale;
|
||||
public int record_main_archive_event_id;
|
||||
public int record_list_order;
|
||||
public int unlock_ticket_id;
|
||||
public int unlock_ticket_count;
|
||||
public int reward_info_list_id;
|
||||
public int event_quest_clear_reward_id;
|
||||
public int recommended_story_list_id;
|
||||
public int included_contents_group_id;
|
||||
public string record_slot_bg_addressable;
|
||||
public string record_unlock_bg_addressable;
|
||||
}
|
||||
|
||||
public class ArchiveRecordManagerTable
|
||||
{
|
||||
public List<ArchiveRecordManagerRecord> records;
|
||||
}
|
||||
|
||||
public class ArchiveEventStoryRecord
|
||||
{
|
||||
public int id;
|
||||
public int event_id;
|
||||
public string prologue_scenario = "";
|
||||
public int dungeon_id;
|
||||
public int album_category_group;
|
||||
public string ui_prefab = "";
|
||||
public int archive_ticket_item_id;
|
||||
public int archive_currency_item_id;
|
||||
}
|
||||
|
||||
public class ArchiveEventStoryTable
|
||||
{
|
||||
public List<ArchiveEventStoryRecord> records;
|
||||
}
|
||||
|
||||
public class ArchiveEventQuestRecord
|
||||
{
|
||||
public int id;
|
||||
public int event_quest_manager_id;
|
||||
public string condition_type = "";
|
||||
public int condition_value;
|
||||
public string name_localkey = "";
|
||||
public string description_localkey = "";
|
||||
public int next_quest_id;
|
||||
public string end_scenario_id = "";
|
||||
}
|
||||
|
||||
public class ArchiveEventQuestTable
|
||||
{
|
||||
public List<ArchiveEventQuestRecord> records;
|
||||
}
|
||||
|
||||
public class ArchiveEventDungeonStageRecord
|
||||
{
|
||||
public int id;
|
||||
public int group;
|
||||
public int step;
|
||||
public string stage_name = "";
|
||||
public string stage_contents_type = "";
|
||||
public int stage_id;
|
||||
public bool is_repeat_clear;
|
||||
}
|
||||
|
||||
public class ArchiveEventDungeonStageTable
|
||||
{
|
||||
public List<ArchiveEventDungeonStageRecord> records;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
43
EpinelPS/LobbyServer/Msgs/Archive/ArchiveClearStage.cs
Normal file
43
EpinelPS/LobbyServer/Msgs/Archive/ArchiveClearStage.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using EpinelPS.Utils;
|
||||
using EpinelPS.Database;
|
||||
namespace EpinelPS.LobbyServer.Msgs.Archive
|
||||
{
|
||||
[PacketPath("/archive/storydungeon/clearstage")]
|
||||
public class ClearArchiveStage : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqClearArchiveStage>(); // has fields EventId, StageId, BattleResult
|
||||
var evid = req.EventId;
|
||||
var stgid = req.StageId;
|
||||
var result = req.BattleResult; // if 2 add to event info as last stage
|
||||
var user = GetUser();
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new Exception("User not found.");
|
||||
}
|
||||
|
||||
// Check if the EventInfo exists for the given EventId
|
||||
if (!user.EventInfo.ContainsKey(evid))
|
||||
{
|
||||
throw new Exception($"Event with ID {evid} not found.");
|
||||
}
|
||||
|
||||
// Update the EventData if BattleResult is 2
|
||||
if (result == 1)
|
||||
{
|
||||
var eventData = user.EventInfo[evid];
|
||||
|
||||
// Update the LastStage in EventData
|
||||
eventData.LastStage = stgid;
|
||||
|
||||
}
|
||||
JsonDb.Save();
|
||||
var response = new ResClearArchiveStage();
|
||||
|
||||
// Send the response back to the client
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
EpinelPS/LobbyServer/Msgs/Archive/ArchiveEnterStage.cs
Normal file
18
EpinelPS/LobbyServer/Msgs/Archive/ArchiveEnterStage.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Msgs.Archive
|
||||
{
|
||||
[PacketPath("/archive/storydungeon/enterstage")]
|
||||
public class EnterArchiveStage : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqEnterArchiveStage>();// has fields EventId StageId TeamNumber
|
||||
var evid = req.EventId;
|
||||
|
||||
var response = new ResEnterArchiveStage();
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
38
EpinelPS/LobbyServer/Msgs/Archive/CompleteArchiveScenario.cs
Normal file
38
EpinelPS/LobbyServer/Msgs/Archive/CompleteArchiveScenario.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using EpinelPS.Utils;
|
||||
using EpinelPS.Database;
|
||||
using EpinelPS.StaticInfo; // Ensure this namespace is included
|
||||
|
||||
namespace EpinelPS.LobbyServer.Msgs.Archive
|
||||
{
|
||||
[PacketPath("/archive/scenario/complete")]
|
||||
public class CompleteScenario : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqCompleteArchiveScenario>(); // req has EventId, ScenarioId, DialogType fields
|
||||
var evid = req.EventId;
|
||||
var scenid = req.ScenarioId;
|
||||
var dialtyp = req.DialogType;
|
||||
|
||||
var user = GetUser();
|
||||
|
||||
// Ensure we are working with the user's EventInfo and not CompletedScenarios
|
||||
if (!user.EventInfo.TryGetValue(evid, out var evt))
|
||||
{
|
||||
// Create a new EventData if the event doesn't exist
|
||||
evt = new EventData();
|
||||
user.EventInfo[evid] = evt;
|
||||
}
|
||||
|
||||
// Ensure the CompletedScenarios list is initialized and add the ScenarioId
|
||||
if (!evt.CompletedScenarios.Contains(scenid))
|
||||
{
|
||||
evt.CompletedScenarios.Add(scenid);
|
||||
}
|
||||
JsonDb.Save();
|
||||
// Prepare and send the response
|
||||
var response = new ResCompleteArchiveScenario();
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
38
EpinelPS/LobbyServer/Msgs/Archive/FastClearArchiveStage.cs
Normal file
38
EpinelPS/LobbyServer/Msgs/Archive/FastClearArchiveStage.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using EpinelPS.Utils;
|
||||
using EpinelPS.Database;
|
||||
namespace EpinelPS.LobbyServer.Msgs.Archive
|
||||
{
|
||||
[PacketPath("/archive/storydungeon/fastclearstage")]
|
||||
public class FastClearArchiveStage : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqFastClearArchiveStage>();
|
||||
var evid = req.EventId;
|
||||
var stgid = req.StageId;
|
||||
|
||||
var user = GetUser();
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new Exception("User not found.");
|
||||
}
|
||||
|
||||
// Check if the EventInfo exists for the given EventId
|
||||
if (!user.EventInfo.ContainsKey(evid))
|
||||
{
|
||||
throw new Exception($"Event with ID {evid} not found.");
|
||||
}
|
||||
|
||||
var eventData = user.EventInfo[evid];
|
||||
// Update the LastStage in EventData
|
||||
eventData.LastStage = stgid;
|
||||
|
||||
JsonDb.Save();
|
||||
var response = new ResFastClearArchiveStage();
|
||||
|
||||
// Send the response back to the client
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
50
EpinelPS/LobbyServer/Msgs/Archive/GetArchiveStoryDungeon.cs
Normal file
50
EpinelPS/LobbyServer/Msgs/Archive/GetArchiveStoryDungeon.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using EpinelPS.Utils;
|
||||
using EpinelPS.Database;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Msgs.Archive
|
||||
{
|
||||
[PacketPath("/archive/storydungeon/get")]
|
||||
public class GetArchiveStoryDungeon : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqGetArchiveStoryDungeon>(); // has EventId field
|
||||
var evid = req.EventId;
|
||||
|
||||
// Retrieve the user based on session (assuming GetCurrentUser is defined elsewhere)
|
||||
var user = GetUser();
|
||||
if (user == null)
|
||||
{
|
||||
throw new Exception("User not found.");
|
||||
}
|
||||
|
||||
// Access EventData directly
|
||||
if (!user.EventInfo.ContainsKey(evid))
|
||||
{
|
||||
throw new Exception($"Event with ID {evid} not found.");
|
||||
}
|
||||
|
||||
var eventData = user.EventInfo[evid];
|
||||
|
||||
// Prepare the response
|
||||
var response = new ResGetArchiveStoryDungeon();
|
||||
|
||||
// Populate team data
|
||||
response.TeamData = new NetUserTeamData()
|
||||
{
|
||||
LastContentsTeamNumber = 1,
|
||||
Type = 1
|
||||
};
|
||||
|
||||
// Populate the last cleared stage
|
||||
response.LastClearedArchiveStageList.Add(new NetLastClearedArchiveStage()
|
||||
{
|
||||
DifficultyId = eventData.Diff,
|
||||
StageId = eventData.LastStage
|
||||
});
|
||||
|
||||
// Send the response
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using EpinelPS.Utils;
|
||||
using EpinelPS.StaticInfo;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Msgs.Archive
|
||||
{
|
||||
@@ -10,8 +11,20 @@ namespace EpinelPS.LobbyServer.Msgs.Archive
|
||||
var req = await ReadData<ReqGetArchiveRecord>();
|
||||
|
||||
var response = new ResGetArchiveRecord();
|
||||
response.ArchiveRecordManagerList.AddRange([100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800]);
|
||||
response.UnlockedArchiveRecordList.AddRange([100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800]);
|
||||
|
||||
// Explicitly select IDs from the records
|
||||
var allIds = GameData.Instance.archiveRecordManagerTable.Values.Select(record => record.id).ToList();
|
||||
|
||||
// Add the IDs to the response lists
|
||||
response.ArchiveRecordManagerList.AddRange(allIds);
|
||||
response.UnlockedArchiveRecordList.AddRange(allIds);
|
||||
|
||||
// Get entries with record_type "EventQuest"
|
||||
var eventQuestRecords = GameData.Instance.archiveRecordManagerTable.Values.Where(record => record.record_type == "EventQuest").ToList();
|
||||
|
||||
response.UnlockedArchiveEventQuestList.AddRange(eventQuestRecords.Select(record => record.id));
|
||||
|
||||
|
||||
// TODO: allow unlocking
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
|
||||
53
EpinelPS/LobbyServer/Msgs/Archive/GetNonResettable.cs
Normal file
53
EpinelPS/LobbyServer/Msgs/Archive/GetNonResettable.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using EpinelPS.Utils;
|
||||
using EpinelPS.StaticInfo; // Ensure this namespace is included
|
||||
|
||||
|
||||
namespace EpinelPS.LobbyServer.Msgs.Archive
|
||||
{
|
||||
[PacketPath("/archive/scenario/getnonresettable")]
|
||||
public class GetNonResettable : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqGetNonResettableArchiveScenario>(); // req has EventId field
|
||||
var evid = req.EventId;
|
||||
var response = new ResGetNonResettableArchiveScenario();
|
||||
|
||||
// Access the GameData instance
|
||||
var gameData = GameData.Instance;
|
||||
|
||||
if (evid == 130002)
|
||||
{
|
||||
// Directly use the archiveEventQuestRecords dictionary
|
||||
foreach (var record in gameData.archiveEventQuestRecords.Values)
|
||||
{
|
||||
if (record.event_quest_manager_id == evid)
|
||||
{
|
||||
// Add the end_scenario_id to the ScenarioIdList
|
||||
if (!string.IsNullOrEmpty(record.end_scenario_id))
|
||||
{
|
||||
response.ScenarioIdList.Add(record.end_scenario_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Directly use the archiveEventStoryRecords dictionary
|
||||
foreach (var record in gameData.archiveEventStoryRecords.Values)
|
||||
{
|
||||
if (record.event_id == evid)
|
||||
{
|
||||
// Add the prologue_scenario to the ScenarioIdList
|
||||
if (!string.IsNullOrEmpty(record.prologue_scenario))
|
||||
{
|
||||
response.ScenarioIdList.Add(record.prologue_scenario);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
EpinelPS/LobbyServer/Msgs/Archive/GetResettable.cs
Normal file
22
EpinelPS/LobbyServer/Msgs/Archive/GetResettable.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using EpinelPS.Utils;
|
||||
using EpinelPS.StaticInfo;
|
||||
namespace EpinelPS.LobbyServer.Msgs.Archive
|
||||
{
|
||||
[PacketPath("/archive/scenario/getresettable")]
|
||||
public class GetResettable : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqGetResettableArchiveScenario>();
|
||||
var response = new ResGetResettableArchiveScenario(); // has ScenarioIdList field that takes in strings
|
||||
|
||||
// Retrieve stage IDs from GameData
|
||||
var stageIds = GameData.Instance.archiveEventDungeonStageRecords.Values.Select(record => record.stage_id.ToString()).ToList();
|
||||
|
||||
// Add them to the response
|
||||
response.ScenarioIdList.Add(stageIds);
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user