Initial commit

This commit is contained in:
Mikhail Thompson
2024-06-26 19:03:44 +03:00
commit 838240de58
72 changed files with 4171 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Antibot
{
[PacketPath("/antibot/battlereportdata")]
public class BattleReportData : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqBattleReportData>();
// I don't really care about reimplementing the server side anticheat, so return
var response = new ResBattleReportData();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,24 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Antibot
{
[PacketPath("/antibot/recvdata")]
public class RecieveAntibotData : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqAntibotRecvData>();
// I don't really care about reimplementing the server side anticheat, so return
var response = new ResAntibotRecvData();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,34 @@
using Google.Protobuf.WellKnownTypes;
using Google.Protobuf;
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Auth
{
[PacketPath("/auth/enterserver")]
public class GetUserOnlineStateLog : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<EnterServerRequest>();
var response = new EnterServerResponse();
var rsp = LobbyHandler.GenGameClientTok(req.ClientPublicKey, req.AuthToken);
response.GameClientToken = rsp.ClientAuthToken;
response.FeatureDataInfo = new NetFeatureDataInfo() { UseFeatureData = true };
response.Identifier = new NetLegacyUserIdentifier() { Server = 21769, Usn = 10984769 };
response.ShouldRestartAfter = Duration.FromTimeSpan(TimeSpan.FromSeconds(86400));
// This was probably the public key for communication at some point during the game's development
// But, the developers chose to hardcode server public key in the client, which prevents this
// private server from "just working", so thats why hex patch is required.
// The only point of encrypting packets is to make it harder for me to develop this and users to use this.
response.EncryptionToken = ByteString.CopyFromUtf8(rsp.ClientAuthToken);
WriteData(response);
}
}
}

View File

@@ -0,0 +1,18 @@
using nksrv.Utils;
namespace nksrv.LobbyServer.Msgs.Auth
{
[PacketPath("/auth/intl")]
public class DoIntlAuth : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<ReqAuthIntl>();
var response = new AuthIntlResponse();
//response.BanInfo = new NetBanInfo() { BanId = 123, Description = "The server admin is sad today because the hinge on his HP laptop broke which happened to be an HP Elitebook 8470p, and the RAM controller exploded and then fixed itself, please contact him", StartAt = Timestamp.FromDateTime(DateTime.UtcNow), EndAt = Timestamp.FromDateTime(DateTime.UtcNow.AddDays(256)) };
response.AuthSuccess = new NetAuthSuccess() { AuthToken = req.Token, CentauriZoneId = "84", FirstAuth = "", PurchaseRestriction = new NetUserPurchaseRestriction() { PurchaseRestriction = PurchaseRestriction.Unknown2, UpdatedAt = 638546758794611090 } };
WriteData(response);
}
}
}

View File

@@ -0,0 +1,22 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Badge
{
[PacketPath("/badge/delete")]
public class DeleteBadge : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqDeleteBadge>();
var response = new ResDeleteBadge();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,16 @@
using nksrv.Utils;
namespace nksrv.LobbyServer.Msgs.Badge
{
[PacketPath("/badge/sync")]
public class SyncBadge : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqSyncBadge>();
var response = new ResSyncBadge();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,21 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Campaign
{
[PacketPath("/campaign/getfield")]
public class GetCampaignField : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqGetCampaignFieldData>();
var response = new ResGetCampaignFieldData();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,24 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Character
{
[PacketPath("/character/get")]
public class GetCharacterData : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqGetCharacterData>();
var response = new ResGetCharacterData();
// TODO implement
WriteData(response);
}
}
}

View File

@@ -0,0 +1,22 @@
using Google.Protobuf.WellKnownTypes;
using nksrv.Utils;
namespace nksrv.LobbyServer.Msgs
{
[PacketPath("/now")]
public class GetCurrentTime : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqGetNow>();
var response = new ResGetNow();
response.Tick = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
response.ResetHour = 1;
response.CheatShiftDuration = Duration.FromTimeSpan(TimeSpan.FromSeconds(0));
// todo: validate response with actual server
WriteData(response);
}
}
}

View File

@@ -0,0 +1,23 @@
using Google.Protobuf.WellKnownTypes;
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs
{
[PacketPath("/Gacha/Get")]
public class GetGacha : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqGetGachaData>();
var response = new ResGetGachaData();
WriteData(response);
}
}
}

View File

@@ -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.Messenger
{
[PacketPath("/messenger/daily/pick")]
public class GetDailyMessage : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqPickTodayDailyMessage>();
// TODO: save these things
var response = new ResPickTodayDailyMessage();
WriteData(response);
}
}
}

View File

@@ -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.Messenger
{
[PacketPath("/messenger/get")]
public class GetMessages : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqGetMessages>();
// TODO: save these things
var response = new ResGetMessages();
WriteData(response);
}
}
}

View File

@@ -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.Messenger
{
[PacketPath("/messenger/picked/get")]
public class GetPickedMessage : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqGetPickedMessageList>();
// TODO: get proper response
var response = new ResGetPickedMessageList();
WriteData(response);
}
}
}

View File

@@ -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.Messenger
{
[PacketPath("/messenger/random/pick")]
public class GetRandomPick : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqForcePickTodayRandomMessage>();
// TODO: get proper response
var response = new ResForcePickTodayRandomMessage();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,21 @@
using Google.Protobuf;
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Misc
{
[PacketPath("/maintenancenotice")]
public class GetMaintenanceNotice : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var r = new MaintenanceNoticeResponse();
WriteData(r);
}
}
}

View File

@@ -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.Misc
{
[PacketPath("/resourcehosts2")]
public class CheckClientVersion : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<ResourceHostRequest>();
var r = new ResourceHostResponse();
r.BaseUrl = "https://cloud.nikke-kr.com/prdenv/121-b0630db21d/{Platform}";
WriteData(r);
}
}
}

View File

@@ -0,0 +1,20 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Misc
{
[PacketPath("/system/sentry/getparams")]
public class GetSentryParams : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var r = new SentryDataResponse();
// TODO check proper response from real server
WriteData(r);
}
}
}

View File

@@ -0,0 +1,25 @@
using Google.Protobuf.WellKnownTypes;
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Misc
{
[PacketPath("/getserverinfo")]
public class GetServerInfo : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var r = new ResGetServerInfo();
// todo: reimplement this as well
r.MatchUrl = "https://global-match.nikke-kr.com";
r.WorldId = 84;
WriteData(r);
}
}
}

View File

@@ -0,0 +1,26 @@
using Google.Protobuf;
using nksrv.Utils;
namespace nksrv.LobbyServer.Msgs.Misc
{
[PacketPath("/staticdatapack")]
public class GetStaticDataPack : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<StaticDataPackRequest>();
var r = new StaticDataPackResponse();
r.Url = "https://cloud.nikke-kr.com/prdenv/121-c5e64b1a1b/staticdata/data/qa-240620-05b-p1/307748/StaticData.pack";
r.Version = "data/qa-240620-05b-p1/307748";
r.Size = 11575712;
// TODO: Read the file and compute these values
r.Sha256Sum = ByteString.CopyFrom(Convert.FromBase64String("PBcDa3PoHR2MJQ+4Xc3/FUSgkqx2gY25MBJ0ih9FMsM="));
r.Salt1 = ByteString.CopyFrom(Convert.FromBase64String("WqyrQ8MGtzwHN3AGPkqVKyjdfWZjBJXw9K7nGblv/SA="));
r.Salt2 = ByteString.CopyFrom(Convert.FromBase64String("6Gf2jEvAX2mt5OWIxIU5uDdbjKtIc+VgTjKKSLuYnsI="));
WriteData(r);
}
}
}

View File

@@ -0,0 +1,22 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Misc
{
[PacketPath("/useronlinestatelog")]
public class GetUserOnlineStateLog : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<ReqUserOnlineStateLog>();
var response = new ResUserOnlineStateLog();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,18 @@
using nksrv.Utils;
namespace nksrv.LobbyServer.Msgs.Outpost
{
[PacketPath("/mission/getrewarded/jukebox")]
public class GetJukeboxRewards : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqGetJukeboxRewardedData>();
// TODO: save these things
var response = new ResGetJukeboxRewardedData();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,18 @@
using nksrv.Utils;
namespace nksrv.LobbyServer.Msgs.Outpost
{
[PacketPath("/outpost/recycleroom/get")]
public class GetRecycleRoomData : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqGetRecycleRoomData>();
// TODO: save these things
var response = new ResGetRecycleRoomData();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using EmbedIO;
using nksrv.Utils;
using Sodium;
using System.IO.Compression;
namespace nksrv.LobbyServer.Msgs
{
public class RedirectionHandler : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
byte[] reqBody = ctx == null ? Contents : (await DecryptOrReturnContentAsync(ctx)).Contents;
HttpClientHandler handler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
AllowAutoRedirect = true // from gameassembly dll
};
HttpClient client = new HttpClient(new LoggingHandler(handler));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/octet-stream+protobuf"));
client.BaseAddress = new Uri("https://global-lobby.nikke-kr.com");
client.DefaultRequestVersion = HttpVersion.Version20;
var systemContent = new ByteArrayContent(reqBody);
systemContent.Headers.Remove("Content-Type");
if (ctx.Request.ContentLength64 != 0)
systemContent.Headers.Add("Content-Type", "application/octet-stream+protobuf");
systemContent.Headers.Add("Content-Length", ctx.Request.ContentLength64.ToString());
// request.Content = systemContent;// CONTENT-TYPE header
var result = await client.PostAsync(ctx.Request.RawUrl, systemContent);
var bt = await result.Content.ReadAsByteArrayAsync();
ctx.Response.ContentEncoding = null;
ctx.Response.ContentType = result.Content.Headers.GetValues("Content-Type").First();
ctx.Response.ContentLength64 = bt.Length;
ctx.Response.OutputStream.Write(bt, 0, bt.Length);
ctx.Response.OutputStream.Flush();
}
public static async Task<PacketDecryptResponse> DecryptOrReturnContentAsync(IHttpContext ctx, bool decompress = false)
{
byte[] bin = Array.Empty<byte>();
using MemoryStream buffer = new MemoryStream();
var stream = ctx.Request.InputStream;
var encoding = ctx.Request.Headers[HttpHeaderNames.ContentEncoding]?.Trim();
Stream decryptedStream;
switch (encoding)
{
case CompressionMethodNames.Gzip:
decryptedStream = new GZipStream(stream, CompressionMode.Decompress);
break;
case CompressionMethodNames.Deflate:
decryptedStream = new DeflateStream(stream, CompressionMode.Decompress);
break;
case CompressionMethodNames.None:
case null:
decryptedStream = stream;
break;
case "gzip,enc":
decryptedStream = stream;
break;
default:
throw HttpException.BadRequest($"Unsupported content encoding \"{encoding}\"");
}
await stream.CopyToAsync(buffer, 81920, ctx.CancellationToken).ConfigureAwait(continueOnCapturedContext: false);
return new PacketDecryptResponse() { Contents = buffer.ToArray() };
}
}
}

View File

@@ -0,0 +1,32 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Shop
{
[PacketPath("/inappshop/jupiter/getproductlist")]
public class GetProductList : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
try
{
var x = await ReadData<ReqGetJupiterProductList>(); //todo: causes crash
var response = new ResGetJupiterProductList();
foreach (var item in x.ProductIdList)
{
response.ProductInfoList.Add(new NetJupiterProductInfo() { CurrencyCode = "US", CurrencySymbol = "$", MicroPrice = 212, Price = "22", ProductId = item });
}
WriteData(response);
}
catch
{
;
}
}
}
}

View File

@@ -0,0 +1,25 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Stage
{
[PacketPath("/stage/clearstage")]
public class ClearStage : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<ReqClearStage>();
var response = new ResClearStage();
// TOOD: save to user info
Console.WriteLine($"Stage " + req.StageId + " completed, result is "+req.BattleResult);
WriteData(response);
}
}
}

View File

@@ -0,0 +1,22 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Stage
{
[PacketPath("/stage/enterstage")]
public class EnterStage : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqEnterStage>();
var response = new ResEnterStage();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,22 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Stage
{
[PacketPath("/stage/get")]
public class GetStage : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqGetStageData>();
var response = new ResGetStageData();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,17 @@
using nksrv.Utils;
namespace nksrv.LobbyServer.Msgs.System
{
[PacketPath("/system/checkversion")]
public class CheckClientVersion : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<CheckVersionRequest>();
var r = new CheckVersionResponse();
r.Availability = 0; // None = 0, Available = 1, Mandatory = 2
WriteData(r);
}
}
}

View File

@@ -0,0 +1,25 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.Team
{
[PacketPath("/team/support-character/list-used-count")]
public class ListSupportCharacterCount : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<ReqListSupportCharacterUsedCount>();
var response = new ResListSupportCharacterUsedCount();
foreach (var item in req.TeamTypeList)
{
Console.WriteLine("support character used: " + item);
}
WriteData(response);
}
}
}

View File

@@ -0,0 +1,17 @@
using nksrv.Utils;
namespace nksrv.LobbyServer.Msgs.Trigger
{
[PacketPath("/Trigger/GetMainQuestData")]
public class GetMainQuestData : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<ReqGetMainQuestData>();
var response = new ResGetMainQuestData();
response.MainQuestList.Add(new NetMainQuestData() { IsReceived = true, Tid = 1 });
WriteData(response);
}
}
}

View File

@@ -0,0 +1,16 @@
using nksrv.Utils;
namespace nksrv.LobbyServer.Msgs.Trigger
{
[PacketPath("/trigger/sync")]
public class TriggerSync : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = ReadData<ReqSyncTrigger>();
var response = new ResSyncTrigger();
WriteData(response);
}
}
}

View File

@@ -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.User
{
[PacketPath("/enterlobbyserver")]
public class EnterLobbyServer : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<ReqEnterLobbyServer>();
var response = new ResEnterLobbyServer();
response.User = new NetUserData();
response.User.Lv = 1;
response.User.CommanderRoomJukebox = 5;
response.User.CostumeLv = 1;
response.User.Frame = 1;
response.User.Icon = 39900;
response.User.LobbyJukebox = 2;
response.ResetHour = 20;
response.Nickname = "USER11143417";
response.OutpostBattleTime = new NetOutpostBattleTime() { MaxBattleTime = 864000000000 ,MaxOverBattleTime = 12096000000000 };
response.RepresentationTeam = new NetWholeUserTeamData() { TeamNumber = 1, Type = 2};
response.RepresentationTeam.Slots.Add(new NetWholeTeamSlot() { Slot = 1 });
response.RepresentationTeam.Slots.Add(new NetWholeTeamSlot() { Slot = 2 });
response.RepresentationTeam.Slots.Add(new NetWholeTeamSlot() { Slot = 3 });
response.RepresentationTeam.Slots.Add(new NetWholeTeamSlot() { Slot = 4 });
response.RepresentationTeam.Slots.Add(new NetWholeTeamSlot() { Slot = 5 });
response.Currency.Add(new NetUserCurrencyData() { Type = 6100, Value = 2 });
//var tTeams = new NetUserTeamData();
//var tTeam = new NetTeamData() { TeamNumber = 1 };
//tTeam.Slots.Add(new NetTeamSlot() { Slot = 1, ValueType = 1, Value = 2 });
//tTeams.Teams.Add(tTeam);
//response.TypeTeams.Add(tTeams);
// response.Character.Add(new NetUserCharacterData() { Default = new NetUserCharacterDefaultData() { Tid = 1 } });
WriteData(response);
}
}
}

View File

@@ -0,0 +1,17 @@
using nksrv.Utils;
namespace nksrv.LobbyServer.Msgs.User
{
[PacketPath("/user/getcontentsdata")]
public class GetContentsData : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<ReqGetContentsOpenData>();
var response = new ResGetContentsOpenData();
WriteData(response);
}
}
}

View File

@@ -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.User
{
[PacketPath("/User/Get")]
public class GetUser : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<GetUserDataRequest>();
var response = new UserDataResponse();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,40 @@
using nksrv.Utils;
using Swan.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.User
{
[PacketPath("/user/scenario/exist")]
public class GetUserScenarioExist : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<ReqExistScenario>();
// TODO: Check response from real server
var response = new ResExistScenario();
var user = GetUser();
foreach (var item in req.ScenarioGroupIds)
{
Logger.Info("check scenario " + item);
foreach (var completed in user.CompletedScenarios)
{
// story thingy was completed
if (completed == item)
{
Logger.Info(item + " is completed");
response.ExistGroupIds.Add(item);
}
}
}
WriteData(response);
}
}
}

View File

@@ -0,0 +1,35 @@
using nksrv.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nksrv.LobbyServer.Msgs.User
{
[PacketPath("/User/SetScenarioComplete")]
public class SetScenarioCompleted : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<ReqSetScenarioComplete>();
var response = new ResSetScenarioComplete();
// Mark the story "scenario" as completed.
// TODO: Get rewards by making a database of them from actual server.
response.Reward = new NetRewardData();
var user = JsonDb.GetUser(UserId);
if (user == null)
{
throw new Exception("null user in SetScenarioComplete command");
}
user.CompletedScenarios.Add(req.ScenarioId);
JsonDb.Save();
WriteData(response);
}
}
}

View File

@@ -0,0 +1,17 @@
using nksrv.Utils;
namespace nksrv.LobbyServer.Msgs.Wallet
{
[PacketPath("/wallet/refreshcharge")]
public class WalletRefreshCharge : LobbyMsgHandler
{
protected override async Task HandleAsync()
{
var req = await ReadData<ReqRefreshChargeCurrencyData>();
var response = new ResRefreshChargeCurrencyData();
WriteData(response);
}
}
}