diff --git a/nksrv/LobbyServer/Msgs/Campaign/GetCampaignField.cs b/nksrv/LobbyServer/Msgs/Campaign/GetCampaignField.cs index 070b784..a28a42f 100644 --- a/nksrv/LobbyServer/Msgs/Campaign/GetCampaignField.cs +++ b/nksrv/LobbyServer/Msgs/Campaign/GetCampaignField.cs @@ -1,4 +1,5 @@ using nksrv.LobbyServer.Msgs.Stage; +using nksrv.StaticInfo; using nksrv.Utils; using Swan.Logging; using System; @@ -20,7 +21,7 @@ namespace nksrv.LobbyServer.Msgs.Campaign Console.WriteLine("Map ID: " + req.MapId); var response = new ResGetCampaignFieldData(); - response.Field = GetStage.CreateFieldInfo(user, GetChapterFromMapId(req.MapId)); + response.Field = GetStage.CreateFieldInfo(user, StaticDataParser.Instance.GetNormalChapterNumberFromFieldName(req.MapId)); // todo save this data response.Team = new NetUserTeamData() { LastContentsTeamNumber = 1, Type = 1 }; @@ -53,21 +54,5 @@ namespace nksrv.LobbyServer.Msgs.Campaign WriteData(response); } - - public static int GetChapterFromMapId(string mapId) - { - switch (mapId) - { - case "fcbg_cityforest_000": - return 0; - case "fcbg_cityforest_003": - return 1; - case "fcbg_cityforest_001": - return 2; - default: - Logger.Warn("TODO: I don't know what chapter mapid " + mapId + " is"); - return 101; - } - } } } diff --git a/nksrv/LobbyServer/Msgs/Outpost/CheckInfracore.cs b/nksrv/LobbyServer/Msgs/Outpost/CheckInfracore.cs new file mode 100644 index 0000000..e32ee93 --- /dev/null +++ b/nksrv/LobbyServer/Msgs/Outpost/CheckInfracore.cs @@ -0,0 +1,23 @@ +using nksrv.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace nksrv.LobbyServer.Msgs.Outpost +{ + [PacketPath("/infracore/check")] + public class CheckInfracore : LobbyMsgHandler + { + protected override async Task HandleAsync() + { + var req = await ReadData(); + var response = new ResCheckReceiveInfraCoreReward(); + + // TODO + + WriteData(response); + } + } +} diff --git a/nksrv/LobbyServer/Msgs/Outpost/GetOutpostData.cs b/nksrv/LobbyServer/Msgs/Outpost/GetOutpostData.cs new file mode 100644 index 0000000..4aa03a3 --- /dev/null +++ b/nksrv/LobbyServer/Msgs/Outpost/GetOutpostData.cs @@ -0,0 +1,48 @@ +using nksrv.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace nksrv.LobbyServer.Msgs.Outpost +{ + [PacketPath("/outpost/getoutpostdata")] + public class GetOutpostData : LobbyMsgHandler + { + protected override async Task HandleAsync() + { + var req = await ReadData(); + var user = GetUser(); + + var battleTime = DateTime.UtcNow - user.BattleTime; + var battleTimeMs = (long)(battleTime.TotalNanoseconds / 100); + + + var response = new ResGetOutpostData + { + OutpostBattleLevel = new NetOutpostBattleLevel() { Level = 1 }, + CommanderBgm = new NetUserJukeboxDataV2(), + BattleTime = 864000000000, Jukebox = new(), MaxBattleTime = 864000000000 + }; + + response.OutpostBattleLevel = user.OutpostBattleLevel; + response.OutpostBattleTime = new NetOutpostBattleTime() { MaxBattleTime = 864000000000, MaxOverBattleTime = 12096000000000, BattleTime = battleTimeMs }; + + // todo dont hardcode this + response.Data.Add(new NetUserOutpostData() { SlotId = 1, BuildingId = 22401, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 }); + response.Data.Add(new NetUserOutpostData() { SlotId = 4, BuildingId = 22701, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 }); + response.Data.Add(new NetUserOutpostData() { SlotId = 5, BuildingId = 22801, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 }); + response.Data.Add(new NetUserOutpostData() { SlotId = 6, BuildingId = 22901, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 }); + response.Data.Add(new NetUserOutpostData() { SlotId = 7, BuildingId = 23001, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 }); + response.Data.Add(new NetUserOutpostData() { SlotId = 3, BuildingId = 23101, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 }); + response.Data.Add(new NetUserOutpostData() { SlotId = 2, BuildingId = 23201, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 }); + response.Data.Add(new NetUserOutpostData() { SlotId = 9, BuildingId = 23301, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 }); + response.Data.Add(new NetUserOutpostData() { SlotId = 8, BuildingId = 23401, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 }); + response.Data.Add(new NetUserOutpostData() { SlotId = 10, BuildingId = 23501, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 }); + response.Data.Add(new NetUserOutpostData() { SlotId = 38, BuildingId = 33601, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 }); + // TODO + WriteData(response); + } + } +} diff --git a/nksrv/LobbyServer/Msgs/Outpost/ShowBattleReward.cs b/nksrv/LobbyServer/Msgs/Outpost/ShowBattleReward.cs new file mode 100644 index 0000000..ea5fd09 --- /dev/null +++ b/nksrv/LobbyServer/Msgs/Outpost/ShowBattleReward.cs @@ -0,0 +1,27 @@ +using nksrv.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace nksrv.LobbyServer.Msgs.Outpost +{ + [PacketPath("/outpost/showoutpostbattlereward")] + public class ShowBattleReward : LobbyMsgHandler + { + protected override async Task HandleAsync() + { + var req = await ReadData(); + var user = GetUser(); + + var battleTime = DateTime.UtcNow - user.BattleTime; + var battleTimeMs = (long)(battleTime.TotalNanoseconds / 100); + + var response = new ResShowOutpostBattleReward(); + response.OutpostBattleLevel = user.OutpostBattleLevel; + response.OutpostBattleTime = new NetOutpostBattleTime() { MaxBattleTime = 864000000000, MaxOverBattleTime = 12096000000000, BattleTime = battleTimeMs }; + WriteData(response); + } + } +} diff --git a/nksrv/LobbyServer/Msgs/Stage/ClearStage.cs b/nksrv/LobbyServer/Msgs/Stage/ClearStage.cs index a8670d0..a7bab7a 100644 --- a/nksrv/LobbyServer/Msgs/Stage/ClearStage.cs +++ b/nksrv/LobbyServer/Msgs/Stage/ClearStage.cs @@ -77,7 +77,8 @@ namespace nksrv.LobbyServer.Msgs.Stage { if (item.reward_id != 0) { - if (item.reward_type == "Currency") + if (string.IsNullOrEmpty(item.reward_type)) { } + else if (item.reward_type == "Currency") { Dictionary current = new Dictionary(); diff --git a/nksrv/LobbyServer/Msgs/User/EnterLobbyServer.cs b/nksrv/LobbyServer/Msgs/User/EnterLobbyServer.cs index f09b272..f89e27c 100644 --- a/nksrv/LobbyServer/Msgs/User/EnterLobbyServer.cs +++ b/nksrv/LobbyServer/Msgs/User/EnterLobbyServer.cs @@ -15,6 +15,9 @@ namespace nksrv.LobbyServer.Msgs.User var req = await ReadData(); var user = GetUser(); + var battleTime = DateTime.UtcNow - user.BattleTime; + var battleTimeMs = (long)(battleTime.TotalNanoseconds / 100); + // NOTE: Keep this in sync with GetUser code var response = new ResEnterLobbyServer(); @@ -22,8 +25,8 @@ namespace nksrv.LobbyServer.Msgs.User response.ResetHour = 20; response.Nickname = user.Nickname; response.SynchroLv = 1; - response.OutpostBattleLevel = new NetOutpostBattleLevel() { Level = 1 }; - response.OutpostBattleTime = new NetOutpostBattleTime() { MaxBattleTime = 864000000000, MaxOverBattleTime = 12096000000000 }; + response.OutpostBattleLevel = user.OutpostBattleLevel; + response.OutpostBattleTime = new NetOutpostBattleTime() { MaxBattleTime = 864000000000, MaxOverBattleTime = 12096000000000, BattleTime = battleTimeMs }; // Add default slot data if (user.RepresentationTeamData.Slots.Count == 0) diff --git a/nksrv/LobbyServer/Msgs/User/GetUser.cs b/nksrv/LobbyServer/Msgs/User/GetUser.cs index f096c20..c86821b 100644 --- a/nksrv/LobbyServer/Msgs/User/GetUser.cs +++ b/nksrv/LobbyServer/Msgs/User/GetUser.cs @@ -13,15 +13,16 @@ namespace nksrv.LobbyServer.Msgs.User protected override async Task HandleAsync() { var req = await ReadData(); - - var response = new ResGetUserData(); - var user = GetUser(); + var battleTime = DateTime.UtcNow - user.BattleTime; + var battleTimeMs = (long)(battleTime.TotalNanoseconds / 100); + + response.User = LobbyHandler.CreateNetUserDataFromUser(user); response.ResetHour = 20; - response.OutpostBattleTime = new NetOutpostBattleTime() { MaxBattleTime = 864000000000, MaxOverBattleTime = 12096000000000 }; + response.OutpostBattleTime = new NetOutpostBattleTime() { MaxBattleTime = 864000000000, MaxOverBattleTime = 12096000000000, BattleTime = battleTimeMs }; response.IsSimple = req.IsSimple; foreach (var item in user.Currency) diff --git a/nksrv/Protos/allmsgs.proto b/nksrv/Protos/allmsgs.proto index dfc77cc..77d9823 100644 --- a/nksrv/Protos/allmsgs.proto +++ b/nksrv/Protos/allmsgs.proto @@ -1672,4 +1672,83 @@ message NetShopProductData { message ReqShopProductList{} message ResShopProductList { repeated NetShopProductData shops = 2; +} + +enum NetJukeboxLocation { + NetJukeboxLocation_CommanderRoom = 0; + NetJukeboxLocation_Lobby = 1; +} + +enum NetJukeboxBgmType { + NetJukeboxBgmType_JukeboxTableId = 0; + NetJukeboxBgmType_JukeboxPlaylist = 1; + NetJukeboxBgmType_JukeboxFavorite = 2; +} + +message NetJukeboxPlaylistSong { + int32 order = 1; + int32 jukeboxTableId = 2; +} + +message NetJukeboxPlaylist { + int64 jukeboxPlaylistUid = 1; + string title = 2; + repeated NetJukeboxPlaylistSong songs = 3; +} + +message NetJukeboxFavorite { + repeated NetJukeboxPlaylistSong songs = 1; +} + +message NetJukeboxBgm { + NetJukeboxLocation location = 1; + NetJukeboxBgmType type = 2; + oneof jukeboxBgm { + int32 JukeboxTableId = 3; + NetJukeboxPlaylist JukeboxPlaylist = 4; + NetJukeboxFavorite JukeboxFavorite = 5; + } + bool IsShuffle = 6; +} + +message NetUserJukeboxData { + int32 selectTid = 1; + repeated int32 list = 2; +} +message NetUserJukeboxDataV2 { + NetJukeboxBgm commandBgm = 1; + repeated int32 jukeboxTableIds = 2; +} + +message ReqGetOutpostData {} +message ResGetOutpostData { + int32 skinGroupId = 2; + repeated NetUserOutpostData data = 3; + int64 battleTime = 4; + int64 maxBattleTime = 5; + repeated int32 conditionTriggerTidList = 6; + repeated int32 dispatchClearCountList = 7; + NetUserJukeboxData jukebox = 8; + repeated NetTimeReward timeRewardBuffs = 9; + NetOutpostBattleLevel outpostBattleLevel = 10; + bool isDispatchRefreshed = 11; + NetOutpostBattleTime outpostBattleTime = 12; + NetUserJukeboxDataV2 commanderBgm = 13; +} + + +message ReqCheckReceiveInfraCoreReward {} +message ResCheckReceiveInfraCoreReward { + bool isReceived = 2; +} + +message ReqShowOutpostBattleReward {} +message ResShowOutpostBattleReward { + int64 battleTime = 1; + int64 maxBattleTime = 2; + int32 fastBattleCount = 3; + NetRewardData reward = 5; + repeated NetTimeReward timeRewardBuffs = 6; + NetOutpostBattleLevel outpostBattleLevel = 7; + NetOutpostBattleTime outpostBattleTime = 8; } \ No newline at end of file diff --git a/nksrv/StaticInfo/StaticDataParser.cs b/nksrv/StaticInfo/StaticDataParser.cs index 12685de..bd40cc5 100644 --- a/nksrv/StaticInfo/StaticDataParser.cs +++ b/nksrv/StaticInfo/StaticDataParser.cs @@ -45,6 +45,7 @@ namespace nksrv.StaticInfo private JArray stageDataRecords; private JArray rewardDataRecords; private JArray userExpDataRecords; + private JArray chapterCampaignData; public StaticDataParser(string filePath) { if (!File.Exists(filePath)) throw new ArgumentException("Static data file must exist", nameof(filePath)); @@ -203,12 +204,13 @@ namespace nksrv.StaticInfo var campaignStageData = MainZip.GetEntry("CampaignStageTable.json"); var rewardDataEntry = MainZip.GetEntry("RewardTable.json"); var userExpTable = MainZip.GetEntry("UserExpTable.json"); - + var chapterCampaignEntry = MainZip.GetEntry("CampaignChapterTable.json"); if (mainQuestData == null) throw new Exception("MainQuestTable.json does not exist in static data"); if (campaignStageData == null) throw new Exception("CampaignStageTable.json does not exist in static data"); if (rewardDataEntry == null) throw new Exception("RewardTable.json does not exist in static data"); if (userExpTable == null) throw new Exception("UserExpTable.json does not exist in static data"); + if (chapterCampaignEntry == null) throw new Exception("CampaignChapterTable.json does not exist in static data"); using StreamReader mainQuestReader = new StreamReader(MainZip.GetInputStream(mainQuestData)); var mainQuestDataString = await mainQuestReader.ReadToEndAsync(); @@ -222,20 +224,26 @@ namespace nksrv.StaticInfo using StreamReader userExpTableReader = new StreamReader(MainZip.GetInputStream(userExpTable)); var userExpTableString = await userExpTableReader.ReadToEndAsync(); + using StreamReader chapterCampaignReader = new StreamReader(MainZip.GetInputStream(chapterCampaignEntry)); + var chapterCampaignString = await chapterCampaignReader.ReadToEndAsync(); + var questdata = JObject.Parse(mainQuestDataString); var stagedata = JObject.Parse(campaignStageDataString); var rewardData = JObject.Parse(rewardJsonString); var userExpTableData = JObject.Parse(userExpTableString); + var chapterCampaignData = JObject.Parse(chapterCampaignString); questDataRecords = (JArray?)questdata["records"]; stageDataRecords = (JArray?)stagedata["records"]; rewardDataRecords = (JArray?)rewardData["records"]; userExpDataRecords = (JArray?)userExpTableData["records"]; + this.chapterCampaignData = (JArray?)chapterCampaignData["records"]; if (questDataRecords == null) throw new Exception("MainQuestTable.json does not contain records array"); if (stageDataRecords == null) throw new Exception("CampaignStageTable.json does not contain records array"); - if (rewardDataRecords == null) throw new Exception("CampaignChapterTable.json does not contain records array"); + if (rewardDataRecords == null) throw new Exception("RewardTable.json does not contain records array"); if (userExpDataRecords == null) throw new Exception("UserExpTable.json does not contain records array"); + if (this.chapterCampaignData == null) throw new Exception("CampaignChapterTable.json does not contain records array"); } public MainQuestCompletionData? GetMainQuestForStageClearCondition(int stage) @@ -292,7 +300,6 @@ namespace nksrv.StaticInfo return null; } - public RewardTableRecord? GetRewardTableEntry(int rewardId) { foreach (JObject item in rewardDataRecords) @@ -311,7 +318,6 @@ namespace nksrv.StaticInfo return null; } - public int GetUserLevelFromUserExp(int targetExp) { int prevLevel = 0; @@ -342,5 +348,30 @@ namespace nksrv.StaticInfo } return -1; } + public int GetNormalChapterNumberFromFieldName(string field) + { + foreach (JObject item in chapterCampaignData) + { + var id = item["field_id"]; + if (id == null) + { + throw new Exception("expected id field in reward data"); + } + + string value = id.ToObject(); + if (value == field) + { + var chapter = item["chapter"]; + if (chapter == null) + { + throw new Exception("expected id field in reward data"); + } + + return chapter.ToObject(); + } + } + + return -1; + } } } diff --git a/nksrv/Utils/JsonDb.cs b/nksrv/Utils/JsonDb.cs index 347520e..a68a8ee 100644 --- a/nksrv/Utils/JsonDb.cs +++ b/nksrv/Utils/JsonDb.cs @@ -83,6 +83,10 @@ namespace nksrv.Utils public int InfraCoreExp = 0; public int InfraCoreLvl = 1; public UserPointData userPointData = new(); + public DateTime LastLogin = DateTime.UtcNow; + public DateTime BattleTime = DateTime.UtcNow; + + public NetOutpostBattleLevel OutpostBattleLevel = new() { Level = 1 }; public void SetQuest(int tid, bool recieved) {