diff --git a/.gitignore b/.gitignore index 50d62c5..fe4b94c 100644 --- a/.gitignore +++ b/.gitignore @@ -455,4 +455,5 @@ $RECYCLE.BIN/ # Allow pregenerated ssl cert !nksrv/site.pfx -!ServerSelector/myCA.pfx \ No newline at end of file +!ServerSelector/myCA.pfx +!ServerSelector/sodium.dll \ No newline at end of file diff --git a/README.md b/README.md index 3cf704d..d2f4678 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # nikke-server -Private/local server for Nikke. NOTE: This project is in a very early state. +Private/local server for Nikke. NOTE: This project is in a very early state so many features in the game do not work. ## Usage Download the latest release/GitHub actions build, and run ServerSelector.Desktop.exe as administrator (to modify DNS hosts file and install a CA cert). Make sure to close the game and launcher first. Select Local server, and then click save. @@ -10,7 +10,7 @@ You should be able to register an new account in the launcher (you can enter any If the game does not get past the title screen, open an issue and send %appdata%\..\LocalLow\com.proximabeta\NIKKE\player.log file. - +Note that this was tested with the latest version (122.8.20c) ## Progress Stage, character, and story information is saved and works, as well as player nickname. diff --git a/nksrv/IntlServer/IntlLogin1Endpoint.cs b/nksrv/IntlServer/IntlLogin1Endpoint.cs index 1cd3872..43f4603 100644 --- a/nksrv/IntlServer/IntlLogin1Endpoint.cs +++ b/nksrv/IntlServer/IntlLogin1Endpoint.cs @@ -25,6 +25,8 @@ namespace nksrv.IntlServer if (item.Username == ep.account && item.Password == ep.password) { var tok = IntlHandler.CreateLauncherTokenForUser(item); + item.LastLogin = DateTime.UtcNow; + JsonDb.Save(); WriteJsonString("{\"expire\":" + tok.ExpirationTime + ",\"is_login\":true,\"msg\":\"Success\",\"register_time\":" + item.RegisterTime + ",\"ret\":0,\"seq\":\"" + Seq + "\",\"token\":\"" + tok.Token + "\",\"uid\":\"" + item.ID + "\"}"); return; diff --git a/nksrv/LobbyServer/Msgs/Gacha/ExecGacha.cs b/nksrv/LobbyServer/Msgs/Gacha/ExecGacha.cs index 4e320a0..73f72f5 100644 --- a/nksrv/LobbyServer/Msgs/Gacha/ExecGacha.cs +++ b/nksrv/LobbyServer/Msgs/Gacha/ExecGacha.cs @@ -19,19 +19,24 @@ namespace nksrv.LobbyServer.Msgs.Gacha var response = new ResExecuteGacha(); // TODO: Pick random character that player does not have unless it supports limit break. - // TODO: Write character to user info. - // TODO implement + // TODO implement reward response.Reward = new NetRewardData(); - foreach (var c in StaticDataParser.Instance.GetAllCharacterTids()) + + if (user.GachaTutorialPlayCount == 0) { - response.Gacha.Add(new NetGachaEntityData() { Corporation = 0, PieceCount = 1, CurrencyValue = 5, Sn = 130201, Tid = c, Type = 1 }); + foreach (var c in StaticDataParser.Instance.GetAllCharacterTids()) + { + response.Gacha.Add(new NetGachaEntityData() { Corporation = 0, PieceCount = 1, CurrencyValue = 5, Sn = 130201, Tid = c, Type = 1 }); - user.Characters.Add(new Utils.Character() { CostumeId = 0, Csn = c, Grade = 0, Level = 1, Skill1Lvl = 1, Skill2Lvl= 1, Tid = c, UltimateLevel = 1 }); + user.Characters.Add(new Utils.Character() { CostumeId = 0, Csn = c, Grade = 0, Level = 1, Skill1Lvl = 1, Skill2Lvl = 1, Tid = c, UltimateLevel = 1 }); - // response.Characters.Add(new NetUserCharacterDefaultData() { Lv = 1, Skill1Lv = 1, Grade = 0, Csn = 1, Tid = 130201 }); + // response.Characters.Add(new NetUserCharacterDefaultData() { Lv = 1, Skill1Lv = 1, Grade = 0, Csn = 1, Tid = 130201 }); + } + user.GachaTutorialPlayCount++; } + JsonDb.Save(); diff --git a/nksrv/LobbyServer/Msgs/Outpost/GetOutpostData.cs b/nksrv/LobbyServer/Msgs/Outpost/GetOutpostData.cs index 4aa03a3..418c564 100644 --- a/nksrv/LobbyServer/Msgs/Outpost/GetOutpostData.cs +++ b/nksrv/LobbyServer/Msgs/Outpost/GetOutpostData.cs @@ -22,7 +22,7 @@ namespace nksrv.LobbyServer.Msgs.Outpost var response = new ResGetOutpostData { OutpostBattleLevel = new NetOutpostBattleLevel() { Level = 1 }, - CommanderBgm = new NetUserJukeboxDataV2(), + CommanderBgm = new NetUserJukeboxDataV2() { CommandBgm = new() { Type = NetJukeboxBgmType.JukeboxTableId, JukeboxTableId = 3012 } }, BattleTime = 864000000000, Jukebox = new(), MaxBattleTime = 864000000000 }; diff --git a/nksrv/LobbyServer/Msgs/User/GetContentsData.cs b/nksrv/LobbyServer/Msgs/User/GetContentsData.cs index e7b5c2a..96ddfba 100644 --- a/nksrv/LobbyServer/Msgs/User/GetContentsData.cs +++ b/nksrv/LobbyServer/Msgs/User/GetContentsData.cs @@ -30,6 +30,7 @@ namespace nksrv.LobbyServer.Msgs.User } response.MaxGachaCount = 10; // todo tutorial playcount of gacha + response.TutorialGachaPlayCount = user.GachaTutorialPlayCount; WriteData(response); } diff --git a/nksrv/Utils/JsonDb.cs b/nksrv/Utils/JsonDb.cs index a68a8ee..de3f65a 100644 --- a/nksrv/Utils/JsonDb.cs +++ b/nksrv/Utils/JsonDb.cs @@ -87,6 +87,7 @@ namespace nksrv.Utils public DateTime BattleTime = DateTime.UtcNow; public NetOutpostBattleLevel OutpostBattleLevel = new() { Level = 1 }; + public int GachaTutorialPlayCount = 0; public void SetQuest(int tid, bool recieved) { @@ -107,14 +108,13 @@ namespace nksrv.Utils public List LauncherAccessTokens = []; - public Dictionary GameClientTokens = []; } internal class JsonDb { public static CoreInfo Instance { get; internal set; } public static byte[] ServerPrivateKey = Convert.FromBase64String("FSUY8Ohd942n5LWAfxn6slK3YGwc8OqmyJoJup9nNos="); - public static byte[] ServerPublicKey = Convert.FromBase64String("04hFDd1e/BOEF2h4b0MdkX2h6W5REeqyW+0r9+eSeh0="); + public static byte[] ServerPublicKey = Convert.FromBase64String("04hFDd1e/BOEF2h4b0MdkX2h6W5REeqyW+0r9+eSeh0="); // Note: change this in sodium static JsonDb() {