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 ;
2023-10-14 16:13:29 +00:00
using MessagePack ;
2023-11-15 12:18:44 +00:00
using System.Diagnostics ;
2023-10-10 09:56:08 +00:00
namespace AscNet.GameServer.Handlers
{
2023-11-14 14:12:15 +00:00
#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
{
}
2024-04-13 05:16:44 +00:00
[MessagePackObject(true)]
public class UseCdKeyRequest
{
public string Id ;
}
[MessagePackObject(true)]
public class UseCdKeyResponse
{
public int Code ;
}
2023-11-14 14:12:15 +00:00
#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
{
2023-10-14 13:00:56 +00:00
[RequestPacketHandler("HandshakeRequest")]
public static void HandshakeRequestHandler ( Session session , Packet . Request packet )
2023-10-10 09:56:08 +00:00
{
2023-10-11 21:15:35 +00:00
// TODO: make this somehow universal, look into better architecture to handle packets
// and automatically log their deserialized form
2023-10-14 15:05:58 +00:00
2023-10-10 09:56:08 +00:00
HandshakeResponse response = new ( )
{
Code = 0 ,
UtcOpenTime = 0 ,
Sha1Table = null
} ;
2023-10-14 13:00:56 +00:00
session . SendResponse ( response , packet . Id ) ;
2023-10-10 09:56:08 +00:00
}
2023-10-10 13:59:08 +00:00
2023-10-14 13:00:56 +00:00
[RequestPacketHandler("LoginRequest")]
public static void LoginRequestHandler ( Session session , Packet . Request packet )
2023-10-10 13:59:08 +00:00
{
2023-12-13 02:25:26 +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 ;
}
2023-11-14 14:12:15 +00:00
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 ( ) ;
2023-12-13 02:25:26 +00:00
// Player data will be outdated without refetching it after disconnecting the previous session.
goto start ;
2023-11-14 14:12:15 +00:00
}
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 ,
2023-10-14 13:00:56 +00:00
UtcServerTime = DateTimeOffset . UtcNow . ToUnixTimeSeconds ( )
} , packet . Id ) ;
2023-10-10 18:22:41 +00:00
2023-10-11 18:32:25 +00:00
DoLogin ( session ) ;
}
2023-10-14 18:01:21 +00:00
[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 ;
2023-10-14 18:01:21 +00:00
session . SendResponse ( new ReconnectResponse ( )
{
2023-10-16 09:50:49 +00:00
ReconnectToken = request . Token
2023-10-14 18:01:21 +00:00
} , packet . Id ) ;
}
2024-04-13 05:16:44 +00:00
2024-04-13 06:30:53 +00:00
/ * TODO Reconnection state resumption ?
2023-10-14 18:01:21 +00:00
[RequestPacketHandler("ReconnectAck")]
public static void ReconnectAckHandler ( Session session , Packet . Request packet )
{
}
* /
2024-04-13 06:30:53 +00:00
// TODO: Promo code
2024-04-13 05:16:44 +00:00
[RequestPacketHandler("UseCdKeyRequest")]
public static void UseCdKeyRequestHandler ( Session session , Packet . Request packet )
{
session . SendResponse ( new UseCdKeyResponse ( ) { Code = 1 } , packet . Id ) ;
}
2023-10-11 21:15:35 +00:00
// 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 ) ;
2023-11-12 01:58:59 +00:00
#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 ( )
} ;
2023-11-19 15:16:36 +00:00
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-11-12 01:58:59 +00:00
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 ) ;
2023-11-12 01:58:59 +00:00
NotifyAssistData notifyAssistData = new ( )
{
AssistData = new ( )
{
AssistCharacterId = session . character . Characters . First ( ) . Id
}
} ;
2023-11-15 12:18:44 +00:00
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-15 12:18:44 +00:00
} ;
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 ( )
} ;
2023-10-14 15:05:58 +00:00
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 ) ;
2023-11-12 01:58:59 +00:00
session . SendPush ( notifyAssistData ) ;
2023-11-15 12:18:44 +00:00
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 = # 8 b0000 > < 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 = # 8 b0000 > < b > AscNet < / b > < / color > , 我 们 很 高 兴 您 使 用 本 服 务 器 软 件 。
2023-11-19 07:44:27 +00:00
本 服 务 器 软 件 始 终 是 免 费 的 , 如 果 您 是 通 过 付 费 来 使 用 本 软 件 , 那 您 就 被 骗 了 , 我 们 鼓 励 您 告 诉 其 他 潜 在 用 户 , 以 防 止 再 有 像 您 这 样 的 买 家 。
2023-11-19 14:02:09 +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
}
}