mirror of
https://github.com/EpinelPS/EpinelPS.git
synced 2025-12-13 23:44:45 +01:00
commit code from airplane
This commit is contained in:
@@ -27,7 +27,8 @@ NOTE: Make sure to undo these modifications (especially change back sodium.dll)
|
|||||||
After doing the following steps, you can register an account in the launcher (enter anything into email verification code section), and play like normal.
|
After doing the following steps, you can register an account in the launcher (enter anything into email verification code section), and play like normal.
|
||||||
|
|
||||||
## Progress
|
## Progress
|
||||||
Stage, character, and story information is saved, as well as player nickname. Lobby UI kind of works. Nothing else works though, such as rewards.
|
Stage, character, and story information is saved and works, as well as player nickname.
|
||||||
|
TODO: Gacha system, reward system, xp system, sim room, outpost, etc
|
||||||
|
|
||||||
TODO: Provide screenshots
|
TODO: Provide screenshots
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using EmbedIO;
|
|||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
using nksrv.Utils;
|
using nksrv.Utils;
|
||||||
using Swan.Logging;
|
using Swan.Logging;
|
||||||
|
using static Google.Rpc.Context.AttributeContext.Types;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer
|
namespace nksrv.LobbyServer
|
||||||
{
|
{
|
||||||
@@ -105,6 +106,47 @@ namespace nksrv.LobbyServer
|
|||||||
{
|
{
|
||||||
// By calling this function, we force .NET to initialize handler dictanary to catch errors early on.
|
// By calling this function, we force .NET to initialize handler dictanary to catch errors early on.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static NetUserData CreateNetUserDataFromUser(User user)
|
||||||
|
{
|
||||||
|
NetUserData ret = new()
|
||||||
|
{
|
||||||
|
Lv = 1,
|
||||||
|
CommanderRoomJukebox = 5,
|
||||||
|
CostumeLv = 1,
|
||||||
|
Frame = 1,
|
||||||
|
Icon = user.ProfileIconId,
|
||||||
|
IconPrism = user.ProfileIconIsPrism,
|
||||||
|
LobbyJukebox = 2,
|
||||||
|
InfraCoreExp = user.InfraCoreExp,
|
||||||
|
InfraCoreLv = user.InfraCoreLvl,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Restore completed tutorials. GroupID is the first 4 digits of the Table ID.
|
||||||
|
foreach (var item in user.ClearedTutorials)
|
||||||
|
{
|
||||||
|
var groupId = int.Parse(item.ToString().Substring(0, 4));
|
||||||
|
int tutorialVersion = item == 1020101 ? 1 : 0; // TODO: Read from static data
|
||||||
|
ret.Tutorials.Add(new NetTutorialData() { GroupId = groupId, LastClearedTid = item, LastClearedVersion = tutorialVersion });
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
public static NetWholeUserData CreateWholeUserDataFromDbUser(User user)
|
||||||
|
{
|
||||||
|
var ret = new NetWholeUserData()
|
||||||
|
{
|
||||||
|
Lv = 1,
|
||||||
|
Frame = 1,
|
||||||
|
Icon = user.ProfileIconId,
|
||||||
|
IconPrism = user.ProfileIconIsPrism,
|
||||||
|
Nickname = user.Nickname,
|
||||||
|
Usn = (long)user.ID
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GameClientInfo
|
public class GameClientInfo
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace nksrv.LobbyServer.Msgs.Campaign
|
|||||||
|
|
||||||
// todo save this data
|
// todo save this data
|
||||||
response.Team = new NetUserTeamData() { LastContentsTeamNumber = 1, Type = 1 };
|
response.Team = new NetUserTeamData() { LastContentsTeamNumber = 1, Type = 1 };
|
||||||
if (user.LastStageCleared >= 6000003)
|
if (user.LastNormalStageCleared >= 6000003)
|
||||||
{
|
{
|
||||||
var team = new NetTeamData() { TeamNumber = 1 };
|
var team = new NetTeamData() { TeamNumber = 1 };
|
||||||
team.Slots.Add(new NetTeamSlot() { Slot = 1, Value = 47263455 });
|
team.Slots.Add(new NetTeamSlot() { Slot = 1, Value = 47263455 });
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace nksrv.LobbyServer.Msgs.Character
|
|||||||
|
|
||||||
var response = new ResGetAttractiveList();
|
var response = new ResGetAttractiveList();
|
||||||
response.CounselAvailableCount = 3; // TODO
|
response.CounselAvailableCount = 3; // TODO
|
||||||
|
|
||||||
// TODO: Validate response from real server and pull info from user info
|
// TODO: Validate response from real server and pull info from user info
|
||||||
WriteData(response);
|
WriteData(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ namespace nksrv.LobbyServer.Msgs.Gacha
|
|||||||
|
|
||||||
var response = new ResExecuteGacha();
|
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
|
||||||
response.Reward = new NetRewardData();
|
response.Reward = new NetRewardData();
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
|
|||||||
21
nksrv/LobbyServer/Msgs/Shop/GetShopProductList.cs
Normal file
21
nksrv/LobbyServer/Msgs/Shop/GetShopProductList.cs
Normal 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.Shop
|
||||||
|
{
|
||||||
|
[PacketPath("/shop/productlist")]
|
||||||
|
public class GetShopProductList : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqShopProductList>();
|
||||||
|
var response = new ResShopProductList();
|
||||||
|
|
||||||
|
WriteData(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,7 @@ namespace nksrv.LobbyServer.Msgs.Stage
|
|||||||
var clearedStage = StaticDataParser.Instance.GetStageData(req.StageId);
|
var clearedStage = StaticDataParser.Instance.GetStageData(req.StageId);
|
||||||
if (clearedStage == null) throw new Exception("cleared stage cannot be null");
|
if (clearedStage == null) throw new Exception("cleared stage cannot be null");
|
||||||
|
|
||||||
user.LastStageCleared = req.StageId;
|
user.LastNormalStageCleared = req.StageId;
|
||||||
|
|
||||||
if (user.FieldInfo.Count == 0)
|
if (user.FieldInfo.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -35,59 +35,86 @@ namespace nksrv.LobbyServer.Msgs.Stage
|
|||||||
}
|
}
|
||||||
|
|
||||||
DoQuestSpecificUserOperations(user, req.StageId);
|
DoQuestSpecificUserOperations(user, req.StageId);
|
||||||
|
var rewardData = StaticDataParser.Instance.GetRewardTableEntry(clearedStage.reward_id);
|
||||||
|
|
||||||
// TODO: figure out how stageid corresponds to chapter
|
|
||||||
user.FieldInfo[clearedStage.chapter_id - 1].CompletedStages.Add(new NetFieldStageData() { StageId = req.StageId });
|
user.FieldInfo[clearedStage.chapter_id - 1].CompletedStages.Add(new NetFieldStageData() { StageId = req.StageId });
|
||||||
JsonDb.Save();
|
if (rewardData != null)
|
||||||
|
response.Reward = RegisterRewardsForUser(user, rewardData);
|
||||||
|
|
||||||
|
|
||||||
// assign rewards
|
|
||||||
if (StageCompletionReward.RewardData.ContainsKey(req.StageId))
|
|
||||||
{
|
|
||||||
var reward = StageCompletionReward.RewardData[req.StageId];
|
|
||||||
|
|
||||||
Dictionary<CurrencyType, int> current = new Dictionary<CurrencyType, int>();
|
|
||||||
|
|
||||||
// add all currencies that users has to current dictionary
|
|
||||||
foreach (var currentReward in user.Currency)
|
|
||||||
{
|
|
||||||
if (!current.ContainsKey(currentReward.Key))
|
|
||||||
current.Add(currentReward.Key, 0);
|
|
||||||
|
|
||||||
current[currentReward.Key] = (int)currentReward.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// add currency reward to response
|
|
||||||
response.StageClearReward = new NetRewardData();
|
|
||||||
foreach (var item in reward.Currency)
|
|
||||||
{
|
|
||||||
if (!current.ContainsKey((CurrencyType)item.Type))
|
|
||||||
current.Add((CurrencyType)item.Type, 0);
|
|
||||||
var val = current[(CurrencyType)item.Type];
|
|
||||||
response.StageClearReward.Currency.Add(new NetCurrencyData() { Type = item.Type, Value = item.Value, FinalValue = val + item.Value });
|
|
||||||
}
|
|
||||||
|
|
||||||
// add currency reward to user info
|
|
||||||
foreach (var item in reward.Currency)
|
|
||||||
{
|
|
||||||
if (!user.Currency.ContainsKey((CurrencyType)item.Type))
|
|
||||||
user.Currency.Add((CurrencyType)item.Type, item.Value);
|
|
||||||
else
|
|
||||||
user.Currency[(CurrencyType)item.Type] += item.Value;
|
|
||||||
}
|
|
||||||
JsonDb.Save();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
Logger.Warn("rewardId is null for stage " + req.StageId);
|
||||||
Logger.Warn("TODO - Reward for stage ID " + req.StageId);
|
JsonDb.Save();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteData(response);
|
WriteData(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NetRewardData RegisterRewardsForUser(Utils.User user, RewardTableRecord rewardData)
|
||||||
|
{
|
||||||
|
NetRewardData ret = new();
|
||||||
|
if (rewardData.rewards == null) return ret;
|
||||||
|
|
||||||
|
if (rewardData.user_exp != 0)
|
||||||
|
{
|
||||||
|
var newXp = rewardData.character_exp + user.userPointData.ExperiencePoint;
|
||||||
|
var newLevel = StaticDataParser.Instance.GetUserLevelFromUserExp(newXp);
|
||||||
|
if (newLevel == -1)
|
||||||
|
{
|
||||||
|
Logger.Warn("Unknown user level value for xp " + newXp);
|
||||||
|
}
|
||||||
|
//ret.UserExp = new NetIncreaseExpData()
|
||||||
|
//{
|
||||||
|
// BeforeExp = user.userPointData.ExperiencePoint,
|
||||||
|
// BeforeLv = user.userPointData.UserLevel,
|
||||||
|
// IncreaseExp = rewardData.character_exp,
|
||||||
|
// CurrentExp = rewardData.character_exp + newXp,
|
||||||
|
// CurrentLv = newLevel,
|
||||||
|
// GainExp = rewardData.character_exp
|
||||||
|
//};
|
||||||
|
user.userPointData.ExperiencePoint += rewardData.character_exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var item in rewardData.rewards)
|
||||||
|
{
|
||||||
|
if (item.reward_id != 0)
|
||||||
|
{
|
||||||
|
if (item.reward_type == "Currency")
|
||||||
|
{
|
||||||
|
Dictionary<CurrencyType, int> current = new Dictionary<CurrencyType, int>();
|
||||||
|
|
||||||
|
// add all currencies that users has to current dictionary
|
||||||
|
foreach (var currentReward in user.Currency)
|
||||||
|
{
|
||||||
|
if (!current.ContainsKey(currentReward.Key))
|
||||||
|
current.Add(currentReward.Key, 0);
|
||||||
|
|
||||||
|
current[currentReward.Key] = (int)currentReward.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add currency reward to response
|
||||||
|
CurrencyType t = (CurrencyType)item.reward_id;
|
||||||
|
int val = item.reward_value;
|
||||||
|
if (!current.ContainsKey(t))
|
||||||
|
current.Add(t, 0);
|
||||||
|
var val2 = current[t];
|
||||||
|
ret.Currency.Add(new NetCurrencyData() { Type = (int)t, Value = val, FinalValue = val2 + val });
|
||||||
|
|
||||||
|
|
||||||
|
// add currency reward to user info
|
||||||
|
if (!user.Currency.ContainsKey(t))
|
||||||
|
user.Currency.Add(t, val);
|
||||||
|
else
|
||||||
|
user.Currency[t] += val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Warn("TODO: Reward type " + item.reward_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
private static void DoQuestSpecificUserOperations(Utils.User user, int clearedStageId)
|
private static void DoQuestSpecificUserOperations(Utils.User user, int clearedStageId)
|
||||||
{
|
{
|
||||||
var quest = StaticDataParser.Instance.GetMainQuestForStageClearCondition(clearedStageId);
|
var quest = StaticDataParser.Instance.GetMainQuestForStageClearCondition(clearedStageId);
|
||||||
@@ -99,21 +126,38 @@ namespace nksrv.LobbyServer.Msgs.Stage
|
|||||||
// TODO: Is this the right place to copy over default characters?
|
// TODO: Is this the right place to copy over default characters?
|
||||||
// TODO: What is CSN and TID? Also need to add names for these
|
// TODO: What is CSN and TID? Also need to add names for these
|
||||||
// Note: TID is table index, not sure what CSN is
|
// Note: TID is table index, not sure what CSN is
|
||||||
|
|
||||||
|
// create a squad with first 5 characters
|
||||||
|
var team1 = new NetUserTeamData();
|
||||||
|
team1.Type = 1;
|
||||||
|
team1.LastContentsTeamNumber = 1;
|
||||||
|
|
||||||
|
var team1Sub = new NetTeamData();
|
||||||
|
team1Sub.TeamNumber = 1;
|
||||||
|
for (int i = 1; i < 6; i++)
|
||||||
|
{
|
||||||
|
var character = user.Characters[i - 1];
|
||||||
|
team1Sub.Slots.Add(new NetTeamSlot() { Slot = i, Value = character.Csn });
|
||||||
|
}
|
||||||
|
team1.Teams.Add(team1Sub);
|
||||||
|
user.UserTeams.Add(1, team1);
|
||||||
|
|
||||||
user.Characters.Add(new Utils.Character() { Csn = 47263455, Tid = 201001 });
|
user.Characters.Add(new Utils.Character() { Csn = 47263455, Tid = 201001 });
|
||||||
user.Characters.Add(new Utils.Character() { Csn = 47273456, Tid = 330501 });
|
user.Characters.Add(new Utils.Character() { Csn = 47273456, Tid = 330501 });
|
||||||
user.Characters.Add(new Utils.Character() { Csn = 47263457, Tid = 130201 });
|
user.Characters.Add(new Utils.Character() { Csn = 47263457, Tid = 130201 });
|
||||||
user.Characters.Add(new Utils.Character() { Csn = 47263458, Tid = 230101 });
|
user.Characters.Add(new Utils.Character() { Csn = 47263458, Tid = 230101 });
|
||||||
user.Characters.Add(new Utils.Character() { Csn = 47263459, Tid = 301201 });
|
user.Characters.Add(new Utils.Character() { Csn = 47263459, Tid = 301201 });
|
||||||
|
|
||||||
user.TeamData.TeamNumber = 1;
|
user.RepresentationTeamData.TeamNumber = 1;
|
||||||
user.TeamData.TeamCombat = 1446; // TODO: Don't hardcode this
|
user.RepresentationTeamData.TeamCombat = 1446; // TODO: Don't hardcode this
|
||||||
user.TeamData.Slots.Clear();
|
user.RepresentationTeamData.Slots.Clear();
|
||||||
user.TeamData.Slots.Add(new NetWholeTeamSlot { Slot = 1, Csn = 47263455, Tid = 201001, Lvl = 1 });
|
user.RepresentationTeamData.Slots.Add(new NetWholeTeamSlot { Slot = 1, Csn = 47263455, Tid = 201001, Lvl = 1 });
|
||||||
user.TeamData.Slots.Add(new NetWholeTeamSlot { Slot = 2, Csn = 47273456, Tid = 330501, Lvl = 1 });
|
user.RepresentationTeamData.Slots.Add(new NetWholeTeamSlot { Slot = 2, Csn = 47273456, Tid = 330501, Lvl = 1 });
|
||||||
user.TeamData.Slots.Add(new NetWholeTeamSlot { Slot = 3, Csn = 47263457, Tid = 130201, Lvl = 1 });
|
user.RepresentationTeamData.Slots.Add(new NetWholeTeamSlot { Slot = 3, Csn = 47263457, Tid = 130201, Lvl = 1 });
|
||||||
user.TeamData.Slots.Add(new NetWholeTeamSlot { Slot = 4, Csn = 47263458, Tid = 230101, Lvl = 1 });
|
user.RepresentationTeamData.Slots.Add(new NetWholeTeamSlot { Slot = 4, Csn = 47263458, Tid = 230101, Lvl = 1 });
|
||||||
user.TeamData.Slots.Add(new NetWholeTeamSlot { Slot = 5, Csn = 47263459, Tid = 301201, Lvl = 1 });
|
user.RepresentationTeamData.Slots.Add(new NetWholeTeamSlot { Slot = 5, Csn = 47263459, Tid = 301201, Lvl = 1 });
|
||||||
}
|
}
|
||||||
|
// TODO: add neon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,22 +21,10 @@ namespace nksrv.LobbyServer.Msgs.Team
|
|||||||
// NOTE: Keep this in sync with EnterLobbyServer code
|
// NOTE: Keep this in sync with EnterLobbyServer code
|
||||||
if (user.Characters.Count > 0)
|
if (user.Characters.Count > 0)
|
||||||
{
|
{
|
||||||
var team1 = new NetUserTeamData();
|
foreach (var item in user.UserTeams)
|
||||||
team1.Type = 1;
|
|
||||||
team1.LastContentsTeamNumber = 1;
|
|
||||||
|
|
||||||
var team1Sub = new NetTeamData();
|
|
||||||
team1Sub.TeamNumber = 1;
|
|
||||||
|
|
||||||
// TODO: Save this properly. Right now return first 5 characters as a squad.
|
|
||||||
for (int i = 1; i < 6; i++)
|
|
||||||
{
|
{
|
||||||
var character = user.Characters[i - 1];
|
response.TypeTeams.Add(item.Value);
|
||||||
team1Sub.Slots.Add(new NetTeamSlot() { Slot = i, Value = character.Csn });
|
|
||||||
}
|
}
|
||||||
team1.Teams.Add(team1Sub);
|
|
||||||
|
|
||||||
response.TypeTeams.Add(team1);
|
|
||||||
}
|
}
|
||||||
WriteData(response);
|
WriteData(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,24 @@ namespace nksrv.LobbyServer.Msgs.Team
|
|||||||
var req = await ReadData<ReqSetTeam>();
|
var req = await ReadData<ReqSetTeam>();
|
||||||
var user = GetUser();
|
var user = GetUser();
|
||||||
|
|
||||||
|
// TODO is this right
|
||||||
var response = new ResSetTeam();
|
var response = new ResSetTeam();
|
||||||
response.Type = req.Type;
|
response.Type = req.Type;
|
||||||
response.Teams.AddRange(req.Teams.ToArray());
|
response.Teams.AddRange(req.Teams.ToArray());
|
||||||
|
|
||||||
// TODO
|
// Add team data to user data
|
||||||
|
var teamData = new NetUserTeamData() { LastContentsTeamNumber = req.ContentsId, Type = req.Type };
|
||||||
|
teamData.Teams.AddRange(req.Teams);
|
||||||
|
|
||||||
|
if (user.UserTeams.ContainsKey(req.Type))
|
||||||
|
{
|
||||||
|
user.UserTeams[req.Type] = teamData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
user.UserTeams.Add(req.Type, teamData);
|
||||||
|
}
|
||||||
|
JsonDb.Save();
|
||||||
|
|
||||||
WriteData(response);
|
WriteData(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,31 +18,25 @@ namespace nksrv.LobbyServer.Msgs.User
|
|||||||
// NOTE: Keep this in sync with GetUser code
|
// NOTE: Keep this in sync with GetUser code
|
||||||
|
|
||||||
var response = new ResEnterLobbyServer();
|
var response = new ResEnterLobbyServer();
|
||||||
response.User = new NetUserData();
|
response.User = LobbyHandler.CreateNetUserDataFromUser(user);
|
||||||
response.User.Lv = 1;
|
|
||||||
response.User.CommanderRoomJukebox = 5;
|
|
||||||
response.User.CostumeLv = 1;
|
|
||||||
response.User.Frame = 1;
|
|
||||||
response.User.Icon = user.ProfileIconId;
|
|
||||||
response.User.IconPrism = user.ProfileIconIsPrism;
|
|
||||||
response.User.LobbyJukebox = 2;
|
|
||||||
response.ResetHour = 20;
|
response.ResetHour = 20;
|
||||||
response.Nickname = user.Nickname;
|
response.Nickname = user.Nickname;
|
||||||
response.SynchroLv = 1;
|
response.SynchroLv = 1;
|
||||||
response.OutpostBattleLevel = new NetOutpostBattleLevel() { Level = 1 };
|
response.OutpostBattleLevel = new NetOutpostBattleLevel() { Level = 1 };
|
||||||
response.OutpostBattleTime = new NetOutpostBattleTime() { MaxBattleTime = 864000000000, MaxOverBattleTime = 12096000000000 };
|
response.OutpostBattleTime = new NetOutpostBattleTime() { MaxBattleTime = 864000000000, MaxOverBattleTime = 12096000000000 };
|
||||||
|
|
||||||
if (user.TeamData.Slots.Count == 0)
|
// Add default slot data
|
||||||
|
if (user.RepresentationTeamData.Slots.Count == 0)
|
||||||
{
|
{
|
||||||
user.TeamData = new NetWholeUserTeamData() { TeamNumber = 1, Type = 2 };
|
user.RepresentationTeamData = new NetWholeUserTeamData() { TeamNumber = 1, Type = 2 };
|
||||||
user.TeamData.Slots.Add(new NetWholeTeamSlot() { Slot = 1 });
|
user.RepresentationTeamData.Slots.Add(new NetWholeTeamSlot() { Slot = 1 });
|
||||||
user.TeamData.Slots.Add(new NetWholeTeamSlot() { Slot = 2 });
|
user.RepresentationTeamData.Slots.Add(new NetWholeTeamSlot() { Slot = 2 });
|
||||||
user.TeamData.Slots.Add(new NetWholeTeamSlot() { Slot = 3 });
|
user.RepresentationTeamData.Slots.Add(new NetWholeTeamSlot() { Slot = 3 });
|
||||||
user.TeamData.Slots.Add(new NetWholeTeamSlot() { Slot = 4 });
|
user.RepresentationTeamData.Slots.Add(new NetWholeTeamSlot() { Slot = 4 });
|
||||||
user.TeamData.Slots.Add(new NetWholeTeamSlot() { Slot = 5 });
|
user.RepresentationTeamData.Slots.Add(new NetWholeTeamSlot() { Slot = 5 });
|
||||||
JsonDb.Save();
|
JsonDb.Save();
|
||||||
}
|
}
|
||||||
response.RepresentationTeam = user.TeamData;
|
response.RepresentationTeam = user.RepresentationTeamData;
|
||||||
|
|
||||||
foreach (var item in user.Currency)
|
foreach (var item in user.Currency)
|
||||||
{
|
{
|
||||||
@@ -53,24 +47,11 @@ namespace nksrv.LobbyServer.Msgs.User
|
|||||||
response.Character.Add(new NetUserCharacterData() { Default = new() { Csn = item.Csn, Skill1Lv = item.Skill1Lvl, Skill2Lv = item.Skill2Lvl, CostumeId = item.CostumeId, Lv = item.Level, Grade = item.Grade, Tid = item.Tid, UltiSkillLv = item.UltimateLevel } });
|
response.Character.Add(new NetUserCharacterData() { Default = new() { Csn = item.Csn, Skill1Lv = item.Skill1Lvl, Skill2Lv = item.Skill2Lvl, CostumeId = item.CostumeId, Lv = item.Level, Grade = item.Grade, Tid = item.Tid, UltiSkillLv = item.UltimateLevel } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add squad data if there are characters
|
||||||
if (user.Characters.Count > 0)
|
if (user.Characters.Count > 0)
|
||||||
{
|
{
|
||||||
var team1 = new NetUserTeamData();
|
foreach (var teamInfo in user.UserTeams)
|
||||||
team1.Type = 1;
|
response.TypeTeams.Add(teamInfo.Value);
|
||||||
team1.LastContentsTeamNumber = 1;
|
|
||||||
|
|
||||||
var team1Sub = new NetTeamData();
|
|
||||||
team1Sub.TeamNumber = 1;
|
|
||||||
|
|
||||||
// TODO: Save this properly. Right now return first 5 characters as a squad.
|
|
||||||
for (int i = 1; i < 6; i++)
|
|
||||||
{
|
|
||||||
var character = user.Characters[i - 1];
|
|
||||||
team1Sub.Slots.Add(new NetTeamSlot() { Slot = i, Value = character.Csn });
|
|
||||||
}
|
|
||||||
team1.Teams.Add(team1Sub);
|
|
||||||
|
|
||||||
response.TypeTeams.Add(team1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Save outpost data
|
// TODO: Save outpost data
|
||||||
@@ -86,15 +67,7 @@ namespace nksrv.LobbyServer.Msgs.User
|
|||||||
response.Outposts.Add(new NetUserOutpostData() { SlotId = 10, BuildingId = 23501, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 });
|
response.Outposts.Add(new NetUserOutpostData() { SlotId = 10, BuildingId = 23501, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 });
|
||||||
response.Outposts.Add(new NetUserOutpostData() { SlotId = 38, BuildingId = 33601, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 });
|
response.Outposts.Add(new NetUserOutpostData() { SlotId = 38, BuildingId = 33601, IsDone = true, StartAt = 638549982076760660, CompleteAt = 638549982076760660 });
|
||||||
|
|
||||||
response.LastClearedNormalMainStageId = user.LastStageCleared;
|
response.LastClearedNormalMainStageId = user.LastNormalStageCleared;
|
||||||
|
|
||||||
// Restore completed tutorials. GroupID is the first 4 digits of the Table ID.
|
|
||||||
foreach (var item in user.ClearedTutorials)
|
|
||||||
{
|
|
||||||
var groupId = int.Parse(item.ToString().Substring(0, 4));
|
|
||||||
int tutorialVersion = item == 1020101 ? 1 : 0; // TODO
|
|
||||||
response.User.Tutorials.Add(new NetTutorialData() { GroupId = groupId, LastClearedTid = item, LastClearedVersion = tutorialVersion });
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteData(response);
|
WriteData(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace nksrv.LobbyServer.Msgs.User
|
|||||||
var req = await ReadData<ReqGetProfileFrame>();
|
var req = await ReadData<ReqGetProfileFrame>();
|
||||||
var response = new ResGetProfileFrame();
|
var response = new ResGetProfileFrame();
|
||||||
|
|
||||||
|
|
||||||
WriteData(response);
|
WriteData(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,14 +19,7 @@ namespace nksrv.LobbyServer.Msgs.User
|
|||||||
|
|
||||||
var user = GetUser();
|
var user = GetUser();
|
||||||
|
|
||||||
response.User = new NetUserData();
|
response.User = LobbyHandler.CreateNetUserDataFromUser(user);
|
||||||
response.User.Lv = 1;
|
|
||||||
response.User.CommanderRoomJukebox = 5;
|
|
||||||
response.User.CostumeLv = 1;
|
|
||||||
response.User.Frame = 1;
|
|
||||||
response.User.Icon = user.ProfileIconId;
|
|
||||||
response.User.IconPrism = user.ProfileIconIsPrism;
|
|
||||||
response.User.LobbyJukebox = 2;
|
|
||||||
response.ResetHour = 20;
|
response.ResetHour = 20;
|
||||||
response.OutpostBattleTime = new NetOutpostBattleTime() { MaxBattleTime = 864000000000, MaxOverBattleTime = 12096000000000 };
|
response.OutpostBattleTime = new NetOutpostBattleTime() { MaxBattleTime = 864000000000, MaxOverBattleTime = 12096000000000 };
|
||||||
response.IsSimple = req.IsSimple;
|
response.IsSimple = req.IsSimple;
|
||||||
@@ -35,9 +28,9 @@ namespace nksrv.LobbyServer.Msgs.User
|
|||||||
{
|
{
|
||||||
response.Currency.Add(new NetUserCurrencyData() { Type = (int)item.Key, Value = item.Value });
|
response.Currency.Add(new NetUserCurrencyData() { Type = (int)item.Key, Value = item.Value });
|
||||||
}
|
}
|
||||||
response.RepresentationTeam = user.TeamData;
|
response.RepresentationTeam = user.RepresentationTeamData;
|
||||||
|
|
||||||
response.LastClearedNormalMainStageId = user.LastStageCleared;
|
response.LastClearedNormalMainStageId = user.LastNormalStageCleared;
|
||||||
|
|
||||||
// Restore completed tutorials. GroupID is the first 4 digits of the Table ID.
|
// Restore completed tutorials. GroupID is the first 4 digits of the Table ID.
|
||||||
foreach (var item in user.ClearedTutorials)
|
foreach (var item in user.ClearedTutorials)
|
||||||
|
|||||||
@@ -20,9 +20,7 @@ namespace nksrv.LobbyServer.Msgs.User
|
|||||||
Console.WriteLine("GET USER PROFILE NOT IMPLEMENTED: " + req.TargetUsn);
|
Console.WriteLine("GET USER PROFILE NOT IMPLEMENTED: " + req.TargetUsn);
|
||||||
if (user.ID == (ulong)req.TargetUsn)
|
if (user.ID == (ulong)req.TargetUsn)
|
||||||
{
|
{
|
||||||
response.Data.User = new NetWholeUserData();
|
response.Data.User = LobbyHandler.CreateWholeUserDataFromDbUser(user);
|
||||||
response.Data.User.Icon = user.ProfileIconId;
|
|
||||||
response.Data.User.IconPrism = user.ProfileIconIsPrism;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,11 +13,18 @@ namespace nksrv.LobbyServer.Msgs.Wallet
|
|||||||
protected override async Task HandleAsync()
|
protected override async Task HandleAsync()
|
||||||
{
|
{
|
||||||
var req = await ReadData<ReqGetCurrencyData>();
|
var req = await ReadData<ReqGetCurrencyData>();
|
||||||
|
var user = GetUser();
|
||||||
|
|
||||||
var response = new ResGetCurrencyData();
|
var response = new ResGetCurrencyData();
|
||||||
foreach (var item in req.Currencies)
|
foreach (var item in req.Currencies)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Request currency " + (CurrencyType)item);
|
Console.WriteLine("Request currency " + (CurrencyType)item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var currency in user.Currency)
|
||||||
|
{
|
||||||
|
response.Currency.Add(new NetUserCurrencyData() { Type = (int)currency.Key, Value = currency.Value });
|
||||||
|
}
|
||||||
|
|
||||||
WriteData(response);
|
WriteData(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,18 +33,17 @@ namespace nksrv
|
|||||||
Logger.Info("Initializing database");
|
Logger.Info("Initializing database");
|
||||||
JsonDb.Save();
|
JsonDb.Save();
|
||||||
|
|
||||||
Logger.Info("Load static data");
|
Logger.Info("Loading static data");
|
||||||
await StaticDataParser.Load();
|
await StaticDataParser.Load();
|
||||||
|
|
||||||
Logger.Info("Parse static data");
|
Logger.Info("Parsing static data");
|
||||||
await StaticDataParser.Instance.Parse();
|
await StaticDataParser.Instance.Parse();
|
||||||
|
|
||||||
Logger.Info("Initialize handlers");
|
Logger.Info("Initialize handlers");
|
||||||
LobbyHandler.Init();
|
LobbyHandler.Init();
|
||||||
|
|
||||||
Logger.Info("Start server");
|
Logger.Info("Starting server");
|
||||||
|
|
||||||
// Start Webserver
|
|
||||||
using var server = CreateWebServer();
|
using var server = CreateWebServer();
|
||||||
await server.RunAsync();
|
await server.RunAsync();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1663,4 +1663,13 @@ message ResExecuteGacha {
|
|||||||
repeated NetUserCharacterDefaultData characters = 6;
|
repeated NetUserCharacterDefaultData characters = 6;
|
||||||
repeated NetUserItemData items = 5;
|
repeated NetUserItemData items = 5;
|
||||||
NetRewardData reward = 9;
|
NetRewardData reward = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NetShopProductData {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReqShopProductList{}
|
||||||
|
message ResShopProductList {
|
||||||
|
repeated NetShopProductData shops = 2;
|
||||||
}
|
}
|
||||||
@@ -23,4 +23,23 @@ namespace nksrv.StaticInfo
|
|||||||
public string stage_category = "";
|
public string stage_category = "";
|
||||||
public int reward_id = 0;
|
public int reward_id = 0;
|
||||||
}
|
}
|
||||||
|
public class RewardTableRecord
|
||||||
|
{
|
||||||
|
public int id;
|
||||||
|
public int user_exp;
|
||||||
|
public int character_exp;
|
||||||
|
public RewardEntry[]? rewards;
|
||||||
|
}
|
||||||
|
public class RewardEntry
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// example: 1000000
|
||||||
|
/// </summary>
|
||||||
|
public int reward_percent;
|
||||||
|
public string percent_display_type = "";
|
||||||
|
public string reward_type = "";
|
||||||
|
public int reward_id;
|
||||||
|
public int reward_value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace nksrv.StaticInfo
|
|||||||
private JArray questDataRecords;
|
private JArray questDataRecords;
|
||||||
private JArray stageDataRecords;
|
private JArray stageDataRecords;
|
||||||
private JArray rewardDataRecords;
|
private JArray rewardDataRecords;
|
||||||
|
private JArray userExpDataRecords;
|
||||||
public StaticDataParser(string filePath)
|
public StaticDataParser(string filePath)
|
||||||
{
|
{
|
||||||
if (!File.Exists(filePath)) throw new ArgumentException("Static data file must exist", nameof(filePath));
|
if (!File.Exists(filePath)) throw new ArgumentException("Static data file must exist", nameof(filePath));
|
||||||
@@ -202,11 +202,13 @@ namespace nksrv.StaticInfo
|
|||||||
var mainQuestData = MainZip.GetEntry("MainQuestTable.json");
|
var mainQuestData = MainZip.GetEntry("MainQuestTable.json");
|
||||||
var campaignStageData = MainZip.GetEntry("CampaignStageTable.json");
|
var campaignStageData = MainZip.GetEntry("CampaignStageTable.json");
|
||||||
var rewardDataEntry = MainZip.GetEntry("RewardTable.json");
|
var rewardDataEntry = MainZip.GetEntry("RewardTable.json");
|
||||||
|
var userExpTable = MainZip.GetEntry("UserExpTable.json");
|
||||||
|
|
||||||
|
|
||||||
if (mainQuestData == null) throw new Exception("MainQuestTable.json does not exist in static data");
|
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 (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 (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");
|
||||||
|
|
||||||
using StreamReader mainQuestReader = new StreamReader(MainZip.GetInputStream(mainQuestData));
|
using StreamReader mainQuestReader = new StreamReader(MainZip.GetInputStream(mainQuestData));
|
||||||
var mainQuestDataString = await mainQuestReader.ReadToEndAsync();
|
var mainQuestDataString = await mainQuestReader.ReadToEndAsync();
|
||||||
@@ -217,16 +219,23 @@ namespace nksrv.StaticInfo
|
|||||||
using StreamReader rewardDataReader = new StreamReader(MainZip.GetInputStream(rewardDataEntry));
|
using StreamReader rewardDataReader = new StreamReader(MainZip.GetInputStream(rewardDataEntry));
|
||||||
var rewardJsonString = await rewardDataReader.ReadToEndAsync();
|
var rewardJsonString = await rewardDataReader.ReadToEndAsync();
|
||||||
|
|
||||||
|
using StreamReader userExpTableReader = new StreamReader(MainZip.GetInputStream(userExpTable));
|
||||||
|
var userExpTableString = await userExpTableReader.ReadToEndAsync();
|
||||||
|
|
||||||
var questdata = JObject.Parse(mainQuestDataString);
|
var questdata = JObject.Parse(mainQuestDataString);
|
||||||
var stagedata = JObject.Parse(campaignStageDataString);
|
var stagedata = JObject.Parse(campaignStageDataString);
|
||||||
var rewardData = JObject.Parse(rewardJsonString);
|
var rewardData = JObject.Parse(rewardJsonString);
|
||||||
|
var userExpTableData = JObject.Parse(userExpTableString);
|
||||||
|
|
||||||
questDataRecords = (JArray?)questdata["records"];
|
questDataRecords = (JArray?)questdata["records"];
|
||||||
stageDataRecords = (JArray?)stagedata["records"];
|
stageDataRecords = (JArray?)stagedata["records"];
|
||||||
rewardDataRecords = (JArray?)rewardData["records"];
|
rewardDataRecords = (JArray?)rewardData["records"];
|
||||||
|
userExpDataRecords = (JArray?)userExpTableData["records"];
|
||||||
|
|
||||||
if (questDataRecords == null) throw new Exception("MainQuestTable.json does not contain records array");
|
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 (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("CampaignChapterTable.json does not contain records array");
|
||||||
|
if (userExpDataRecords == null) throw new Exception("UserExpTable.json does not contain records array");
|
||||||
}
|
}
|
||||||
|
|
||||||
public MainQuestCompletionData? GetMainQuestForStageClearCondition(int stage)
|
public MainQuestCompletionData? GetMainQuestForStageClearCondition(int stage)
|
||||||
@@ -283,5 +292,55 @@ namespace nksrv.StaticInfo
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RewardTableRecord? GetRewardTableEntry(int rewardId)
|
||||||
|
{
|
||||||
|
foreach (JObject item in rewardDataRecords)
|
||||||
|
{
|
||||||
|
var id = item["id"];
|
||||||
|
if (id == null) throw new Exception("expected id field in reward data");
|
||||||
|
|
||||||
|
int value = id.ToObject<int>();
|
||||||
|
if (value == rewardId)
|
||||||
|
{
|
||||||
|
RewardTableRecord? data = JsonConvert.DeserializeObject<RewardTableRecord>(item.ToString());
|
||||||
|
if (data == null) throw new Exception("failed to deserialize reward data");
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetUserLevelFromUserExp(int targetExp)
|
||||||
|
{
|
||||||
|
int prevLevel = 0;
|
||||||
|
int prevValue = 0;
|
||||||
|
for (int i = 0; i < userExpDataRecords.Count; i++)
|
||||||
|
{
|
||||||
|
var item = userExpDataRecords[i];
|
||||||
|
|
||||||
|
var level = item["level"];
|
||||||
|
if (level == null) throw new Exception("expected level field in user exp table data");
|
||||||
|
|
||||||
|
int levelValue = level.ToObject<int>();
|
||||||
|
|
||||||
|
var exp = item["exp"];
|
||||||
|
if (exp == null) throw new Exception("expected exp field in user exp table data");
|
||||||
|
|
||||||
|
int expValue = exp.ToObject<int>();
|
||||||
|
|
||||||
|
if (prevValue < targetExp)
|
||||||
|
{
|
||||||
|
prevLevel = levelValue;
|
||||||
|
prevValue = expValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return prevLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ namespace nksrv.Utils
|
|||||||
public bool IsReceieved = false;
|
public bool IsReceieved = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class UserPointData
|
||||||
|
{
|
||||||
|
public int UserLevel = 1;
|
||||||
|
public int ExperiencePoint = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class User
|
public class User
|
||||||
{
|
{
|
||||||
@@ -50,29 +56,33 @@ namespace nksrv.Utils
|
|||||||
public string PlayerName = "";
|
public string PlayerName = "";
|
||||||
public ulong ID;
|
public ulong ID;
|
||||||
public long RegisterTime;
|
public long RegisterTime;
|
||||||
public int LastStageCleared;
|
public int LastNormalStageCleared;
|
||||||
public string Nickname = "SomePLayer";
|
public int LastHardStageCleared;
|
||||||
|
public string Nickname = "SomePlayer";
|
||||||
public int ProfileIconId = 39900;
|
public int ProfileIconId = 39900;
|
||||||
public bool ProfileIconIsPrism = false;
|
public bool ProfileIconIsPrism = false;
|
||||||
|
|
||||||
|
|
||||||
// Game data
|
// Game data
|
||||||
public List<string> CompletedScenarios = [];
|
public List<string> CompletedScenarios = [];
|
||||||
public Dictionary<int, FieldInfo> FieldInfo = [];
|
public Dictionary<int, FieldInfo> FieldInfo = [];
|
||||||
public Dictionary<string, string> MapJson = [];
|
public Dictionary<string, string> MapJson = [];
|
||||||
public Dictionary<CurrencyType, long> Currency = new() {
|
public Dictionary<CurrencyType, long> Currency = new() {
|
||||||
{ CurrencyType.ContentStamina, 2 },
|
{ CurrencyType.ContentStamina, 2 },
|
||||||
{ CurrencyType.CharPremiumTicket, 23422 }
|
{ CurrencyType.CharPremiumTicket, 999999 }
|
||||||
};
|
};
|
||||||
|
|
||||||
public List<Character> Characters = [];
|
public List<Character> Characters = [];
|
||||||
public NetWholeUserTeamData TeamData = new();
|
public NetWholeUserTeamData RepresentationTeamData = new();
|
||||||
public List<int> ClearedTutorials = [];
|
public List<int> ClearedTutorials = [];
|
||||||
public NetWallpaperData[] WallpaperList = [];
|
public NetWallpaperData[] WallpaperList = [];
|
||||||
|
public Dictionary<int, NetUserTeamData> UserTeams = new Dictionary<int, NetUserTeamData>();
|
||||||
public Dictionary<int, bool> MainQuestData = new()
|
public Dictionary<int, bool> MainQuestData = new()
|
||||||
{
|
{
|
||||||
{1, false }
|
{1, false }
|
||||||
};
|
};
|
||||||
|
public int InfraCoreExp = 0;
|
||||||
|
public int InfraCoreLvl = 1;
|
||||||
|
public UserPointData userPointData = new();
|
||||||
|
|
||||||
public void SetQuest(int tid, bool recieved)
|
public void SetQuest(int tid, bool recieved)
|
||||||
{
|
{
|
||||||
@@ -86,11 +96,6 @@ namespace nksrv.Utils
|
|||||||
MainQuestData.Add(tid, recieved);
|
MainQuestData.Add(tid, recieved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RmQuest(int tid)
|
|
||||||
{
|
|
||||||
MainQuestData.Remove(tid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public class CoreInfo
|
public class CoreInfo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ namespace nksrv.Utils
|
|||||||
var x = SecretAeadXChaCha20Poly1305.Decrypt(bytes, nonce, key.Keys.ReadSharedSecret, [.. additionalData]);
|
var x = SecretAeadXChaCha20Poly1305.Decrypt(bytes, nonce, key.Keys.ReadSharedSecret, [.. additionalData]);
|
||||||
|
|
||||||
var ms = new MemoryStream(x);
|
var ms = new MemoryStream(x);
|
||||||
// File.WriteAllBytes("fullPkt-decr", ms.ToArray());
|
|
||||||
|
|
||||||
var unkVal1 = ms.ReadByte();
|
var unkVal1 = ms.ReadByte();
|
||||||
var unkVal2 = ms.ReadByte();
|
var unkVal2 = ms.ReadByte();
|
||||||
@@ -65,7 +64,6 @@ namespace nksrv.Utils
|
|||||||
|
|
||||||
|
|
||||||
var startPos = (int)ms.Position;
|
var startPos = (int)ms.Position;
|
||||||
//Console.WriteLine("seg #: " + seqNum + ",actual:" + bytes.Length + "cntlen:" + ctx.Request.ContentLength64);
|
|
||||||
|
|
||||||
var contents = x.Skip(startPos).ToArray();
|
var contents = x.Skip(startPos).ToArray();
|
||||||
if (contents.Length != 0 && contents[0] == 31)
|
if (contents.Length != 0 && contents[0] == 31)
|
||||||
|
|||||||
Reference in New Issue
Block a user