ascnet/AscNet.GameServer/Handlers/AccountModule.cs

328 lines
13 KiB
C#
Raw Normal View History

2023-10-16 09:50:49 +00:00
using AscNet.Common.Database;
using AscNet.Common.MsgPack;
2023-11-15 01:01:16 +00:00
using AscNet.Common.Util;
2023-12-10 02:22:33 +00:00
using AscNet.Table.V2.share.chat;
using AscNet.Table.V2.share.guide;
2023-12-13 02:18:07 +00:00
using AscNet.Table.V2.share.photomode;
using MessagePack;
using System.Diagnostics;
2023-10-10 09:56:08 +00:00
namespace AscNet.GameServer.Handlers
{
#region MsgPackScheme
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
[MessagePackObject(true)]
public class ForceLogoutNotify
{
public int Code;
}
[MessagePackObject(true)]
public class ShutdownNotify
{
}
[MessagePackObject(true)]
public class UseCdKeyRequest
{
public string Id;
}
2024-04-14 12:09:44 +00:00
[MessagePackObject(true)]
public class CdKeyRewardGoods
{
public RewardType RewardType;
public int TemplateId;
}
[MessagePackObject(true)]
public class UseCdKeyResponse
{
public int Code;
2024-04-14 12:09:44 +00:00
public List<CdKeyRewardGoods>? RewardGoods;
}
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
#endregion
2023-10-10 09:56:08 +00:00
internal class AccountModule
{
[RequestPacketHandler("HandshakeRequest")]
public static void HandshakeRequestHandler(Session session, Packet.Request packet)
2023-10-10 09:56:08 +00:00
{
// TODO: make this somehow universal, look into better architecture to handle packets
// and automatically log their deserialized form
2023-10-10 09:56:08 +00:00
HandshakeResponse response = new()
{
Code = 0,
UtcOpenTime = 0,
Sha1Table = null
};
session.SendResponse(response, packet.Id);
2023-10-10 09:56:08 +00:00
}
2023-10-10 13:59:08 +00:00
[RequestPacketHandler("LoginRequest")]
public static void LoginRequestHandler(Session session, Packet.Request packet)
2023-10-10 13:59:08 +00:00
{
start:
2023-10-16 09:50:49 +00:00
LoginRequest request = MessagePackSerializer.Deserialize<LoginRequest>(packet.Content);
Player? player = Player.FromToken(request.Token);
if (player is null)
{
session.SendResponse(new LoginResponse
{
Code = 1007 // LoginInvalidLoginToken
}, packet.Id);
return;
}
Session? previousSession = Server.Instance.Sessions.Select(x => x.Value).Where(x => x.GetHashCode() != session.GetHashCode()).FirstOrDefault(x => x.player.PlayerData.Id == player.PlayerData.Id);
if (previousSession is not null)
{
// GateServerForceLogoutByAnotherLogin
previousSession.SendPush(new ForceLogoutNotify() { Code = 1018 });
previousSession.DisconnectProtocol();
// Player data will be outdated without refetching it after disconnecting the previous session.
goto start;
}
2023-10-16 09:53:53 +00:00
session.player = player;
2023-10-19 07:07:48 +00:00
session.character = Character.FromUid(player.PlayerData.Id);
session.stage = Stage.FromUid(player.PlayerData.Id);
2023-11-15 01:01:16 +00:00
session.inventory = Inventory.FromUid(player.PlayerData.Id);
2023-10-10 13:59:08 +00:00
session.SendResponse(new LoginResponse
{
Code = 0,
2023-10-16 09:50:49 +00:00
ReconnectToken = player.Token,
2023-10-10 13:59:08 +00:00
UtcOffset = 0,
UtcServerTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
}, packet.Id);
2023-10-10 18:22:41 +00:00
2023-10-11 18:32:25 +00:00
DoLogin(session);
}
[RequestPacketHandler("ReconnectRequest")]
public static void ReconnectRequestHandler(Session session, Packet.Request packet)
{
2023-10-16 09:50:49 +00:00
ReconnectRequest request = MessagePackSerializer.Deserialize<ReconnectRequest>(packet.Content);
2023-10-19 07:07:48 +00:00
Player? player;
if (session.player is not null)
player = session.player;
else
{
player = Player.FromToken(request.Token);
2023-11-24 13:01:26 +00:00
session.log.Debug("Player is reconnecting into new session...");
2023-11-15 01:01:16 +00:00
if (player is not null && (session.character is null || session.stage is null || session.inventory is null))
2023-10-19 07:07:48 +00:00
{
2023-11-24 13:01:26 +00:00
session.log.Debug("Reassigning player props...");
2023-10-19 07:07:48 +00:00
session.character = Character.FromUid(player.PlayerData.Id);
session.stage = Stage.FromUid(player.PlayerData.Id);
2023-11-15 01:01:16 +00:00
session.inventory = Inventory.FromUid(player.PlayerData.Id);
2023-10-19 07:07:48 +00:00
}
}
2023-10-16 09:50:49 +00:00
if (player?.PlayerData.Id != request.PlayerId)
{
session.SendResponse(new ReconnectResponse()
{
Code = 1029 // ReconnectInvalidToken
}, packet.Id);
return;
}
2023-10-16 09:53:53 +00:00
session.player = player;
session.SendResponse(new ReconnectResponse()
{
2023-10-16 09:50:49 +00:00
ReconnectToken = request.Token
}, packet.Id);
}
/* TODO Reconnection state resumption?
[RequestPacketHandler("ReconnectAck")]
public static void ReconnectAckHandler(Session session, Packet.Request packet)
{
}
*/
// TODO: Promo code
[RequestPacketHandler("UseCdKeyRequest")]
public static void UseCdKeyRequestHandler(Session session, Packet.Request packet)
{
2024-04-14 12:09:44 +00:00
session.SendResponse(new UseCdKeyResponse() { Code = 20054001 }, packet.Id);
}
// TODO: Move somewhere else, also split.
2023-10-11 18:32:25 +00:00
static void DoLogin(Session session)
{
2023-10-19 07:07:48 +00:00
NotifyLogin notifyLogin = new()
{
PlayerData = session.player.PlayerData,
TeamGroupData = session.player.TeamGroups,
BaseEquipLoginData = new(),
FubenData = new()
{
FubenBaseData = new()
},
FubenMainLineData = new(),
FubenChapterExtraLoginData = new(),
FubenUrgentEventData = new(),
2023-12-13 02:18:07 +00:00
UseBackgroundId = session.player.UseBackgroundId
2023-10-19 07:07:48 +00:00
};
2023-11-12 06:00:44 +00:00
if (notifyLogin.PlayerData.DisplayCharIdList.Count < 1)
notifyLogin.PlayerData.DisplayCharIdList.Add(notifyLogin.PlayerData.DisplayCharId);
2023-10-19 07:07:48 +00:00
notifyLogin.FashionList.AddRange(session.character.Fashions);
#if DEBUG
2023-12-10 02:22:33 +00:00
notifyLogin.PlayerData.GuideData = TableReaderV2.Parse<GuideGroupTable>().Select(x => (long)x.Id).ToList();
2023-11-29 14:01:00 +00:00
#endif
NotifyStageData notifyStageData = new()
{
StageList = session.stage.Stages.Values.ToList()
};
StageDatum stageForChat = new()
{
StageId = 10030201,
StarsMark = 7,
Passed = true,
PassTimesToday = 0,
PassTimesTotal = 1,
BuyCount = 0,
Score = 0,
LastPassTime = DateTimeOffset.Now.ToUnixTimeSeconds(),
RefreshTime = DateTimeOffset.Now.ToUnixTimeSeconds(),
CreateTime = DateTimeOffset.Now.ToUnixTimeSeconds(),
BestRecordTime = 0,
LastRecordTime = 0,
BestCardIds = new List<long> { 1021001 },
LastCardIds = new List<long> { 1021001 }
};
2023-11-29 14:01:00 +00:00
if (!notifyStageData.StageList.Any(x => x.StageId == stageForChat.StageId))
notifyStageData.StageList = notifyStageData.StageList.Append(stageForChat).ToList();
2023-10-19 07:07:48 +00:00
NotifyCharacterDataList notifyCharacterData = new();
notifyCharacterData.CharacterDataList.AddRange(session.character.Characters);
NotifyEquipDataList notifyEquipData = new();
notifyEquipData.EquipDataList.AddRange(session.character.Equips);
NotifyAssistData notifyAssistData = new()
{
AssistData = new()
{
AssistCharacterId = session.character.Characters.First().Id
}
};
NotifyChatLoginData notifyChatLoginData = new()
{
RefreshTime = ((DateTimeOffset)Process.GetCurrentProcess().StartTime).ToUnixTimeSeconds(),
2023-12-10 02:22:33 +00:00
UnlockEmojis = TableReaderV2.Parse<EmojiTable>().Select(x => new NotifyChatLoginData.NotifyChatLoginDataUnlockEmoji() { Id = (uint)x.Id }).ToList()
};
2023-11-25 11:56:53 +00:00
NotifyItemDataList notifyItemDataList = new()
{
/*ItemDataList = TableReaderV2.Parse<Table.V2.share.item.ItemTable>().Select(x => new Item()
{
Id = x.Id,
Count = x.MaxCount ?? 999_999_999,
RefreshTime = DateTimeOffset.Now.ToUnixTimeSeconds(),
CreateTime = DateTimeOffset.Now.ToUnixTimeSeconds()
}).ToList(),*/
ItemDataList = session.inventory.Items
};
2023-12-13 02:18:07 +00:00
NotifyBackgroundLoginData notifyBackground = new()
{
HaveBackgroundIds = TableReaderV2.Parse<BackgroundTable>().Select(x => (uint)x.Id).ToList()
};
session.SendPush(notifyLogin);
2023-11-29 14:01:00 +00:00
session.SendPush(notifyStageData);
2023-10-19 07:07:48 +00:00
session.SendPush(notifyCharacterData);
session.SendPush(notifyEquipData);
session.SendPush(notifyAssistData);
session.SendPush(notifyChatLoginData);
2023-11-25 11:56:53 +00:00
session.SendPush(notifyItemDataList);
2023-12-13 02:18:07 +00:00
session.SendPush(notifyBackground);
2023-12-18 14:20:02 +00:00
session.SendPush(new NotifyTRPGData()
{
CurTargetLink = 10001,
BaseInfo = new()
{
Level = 1
},
BossInfo = new()
});
2024-02-23 09:53:15 +00:00
session.SendPush(new NotifyTaskData()
{
TaskData = new()
{
NewbieHonorReward = false,
NewbieUnlockPeriod = 7
}
});
2023-10-14 17:16:45 +00:00
2023-11-19 07:44:27 +00:00
#region DisclamerMail
NotifyMails notifyMails = new();
notifyMails.NewMailList.Add(new NotifyMails.NotifyMailsNewMailList()
{
Id = "0",
Status = 0, // MAIL_STATUS_UNREAD
2023-11-27 13:19:52 +00:00
SendName = "<color=#8b0000><b>AscNet</b></color> Developers",
Title = "<b>[IMPORTANT]</b> Information Regarding This Server Software [有关本服务器软件的信息]",
2023-11-19 07:44:27 +00:00
Content = @"Hello Commandant!
2023-11-27 13:19:52 +00:00
Welcome to <color=#8b0000><b>AscNet</b></color>, we are happy that you are using this <b>Server Software</b>.
This <b>Server Software</b> is always free and if you are paying to gain access to this you are being SCAMMED, we encourage you to help prevent another buyer like you by making a PSA or telling others whom you may see as potential users.
2023-11-20 15:19:46 +00:00
Sorry for the inconvenience.
2023-11-19 07:44:27 +00:00
2023-11-27 13:19:52 +00:00
<color=#8b0000><b>AscNet</b></color>使
2023-11-19 07:44:27 +00:00
使
便
[",
2023-11-19 07:44:27 +00:00
CreateTime = ((DateTimeOffset)Process.GetCurrentProcess().StartTime).ToUnixTimeSeconds(),
SendTime = ((DateTimeOffset)Process.GetCurrentProcess().StartTime).ToUnixTimeSeconds(),
ExpireTime = DateTimeOffset.Now.ToUnixTimeSeconds() * 2,
IsForbidDelete = true
});
2023-11-20 15:19:46 +00:00
NotifyWorldChat notifyWorldChat = new();
2023-11-24 13:01:26 +00:00
notifyWorldChat.ChatMessages.Add(ChatModule.MakeLuciaMessage($"Hello {session.player.PlayerData.Name}! Welcome to AscNet, please read mails if you haven't already.\n如果您还没有阅读邮件请阅读邮件\n\nTry '/help' to get started"));
2023-11-20 15:19:46 +00:00
2023-11-19 07:44:27 +00:00
session.SendPush(notifyMails);
2023-11-20 15:19:46 +00:00
session.SendPush(notifyWorldChat);
2023-11-19 07:44:27 +00:00
#endregion
2023-11-11 11:08:20 +00:00
// NEEDED to not softlock!
session.SendPush(new NotifyFubenPrequelData() { FubenPrequelData = new() });
session.SendPush(new NotifyPrequelChallengeRefreshTime() { NextRefreshTime = (uint)DateTimeOffset.Now.ToUnixTimeSeconds() + 3600 * 24 });
session.SendPush(new NotifyMainLineActivity() { EndTime = 0 });
session.SendPush(new NotifyDailyFubenLoginData() { RefreshTime = (uint)DateTimeOffset.Now.ToUnixTimeSeconds() + 3600 * 24 });
session.SendPush(new NotifyBriefStoryData());
session.SendPush(new NotifyFubenBossSingleData()
{
FubenBossSingleData = new()
{
ActivityNo = 1,
TotalScore = 0,
MaxScore = 0,
OldLevelType = 0,
LevelType = 1,
ChallengeCount = 0,
RemainTime = 100000,
AutoFightCount = 0,
CharacterPoints = new {},
RankPlatform = 0
}
});
session.SendPush(new NotifyBfrtData() { BfrtData = new() });
2023-10-10 13:59:08 +00:00
}
2023-10-10 09:56:08 +00:00
}
}