using Yuanshen.Gameserver.Controllers.Attributes; using Yuanshen.Gameserver.Controllers.Result; using Yuanshen.Gameserver.Game; using Yuanshen.Gameserver.Network.Session; using Yuanshen.Protocol; using Yuanshen.Gameserver.Database; using Microsoft.Extensions.Logging; namespace Yuanshen.Gameserver.Controllers; [NetController] internal sealed class AccountController : ControllerBase { [NetCommand(CmdType.GetPlayerTokenReq)] public async ValueTask OnGetPlayerTokenReq(Player player, IAccountRepository accounts) { GetPlayerTokenReq req = Packet!.DecodeBody(); uint uid = await accounts.GetOrCreateUidAsync(req.AccountUid); player.AssignUid(uid); GetPlayerTokenRsp rsp = new() { PlayerUid = player.Uid, AccountToken = req.AccountToken, AccountType = (int)req.AccountType, SecretKey = 1337 }; return Response(CmdType.GetPlayerTokenRsp, rsp); } [NetCommand(CmdType.PingReq)] public async ValueTask OnPingReq(SceneManager scene) { PingReq req = Packet!.DecodeBody(); await scene.SyncPendingMonsterLevelsAsync(); PingRsp rsp = new() { Seq = (uint)req.Seq, ClientTime = (uint)req.ClientTime }; return Response(CmdType.PingRsp, rsp); } [NetCommand(CmdType.PlayerLoginReq)] public async ValueTask OnPlayerLoginReq(NetSession session, Player player, GameState state, PlayerPersistence persistence, OpenStateTable openStates, ILogger logger) { player.InitDefault(); persistence.Acquire(); PlayerRecord? record = await persistence.LoadAsync(); if (record is not null) { player.ApplyRecord(record); if (record.PosX != 0f || record.PosY != 0f || record.PosZ != 0f) state.UpdatePosition(new Vector { X = record.PosX, Y = record.PosY, Z = record.PosZ }); logger.LogInformation("Loaded player {uid}: pos=({x}, {y}, {z}), team={team}, killed={killed}", player.Uid, state.CurrentPos.X, state.CurrentPos.Y, state.CurrentPos.Z, player.TeamAvatarGuids.Count, record.KilledNodes.Count); } else { logger.LogInformation("No saved record for player {uid}, starting fresh", player.Uid); } await session.NotifyAsync(CmdType.PlayerDataNotify, new PlayerDataNotify { NickName = player.Nickname, PropMap = { { 4001u, new PropValue { Type = 4001, Ival = 1, Val = 1 } }, { 10006u, new PropValue { Type = 10006, Ival = 1, Val = 1 } }, { 10009u, new PropValue { Type = 10009, Ival = 1, Val = 1 } }, { 10010u, new PropValue { Type = 10010, Ival = 24000, Val = 24000 } }, { 10011u, new PropValue { Type = 10011, Ival = 24000, Val = 24000 } }, { 10013u, new PropValue { Type = 10013, Ival = 60, Val = 60 } }, { 10015u, new PropValue { Type = 10015, Ival = player.Hcoin, Val = player.Hcoin } }, { 10016u, new PropValue { Type = 10016, Ival = player.Scoin, Val = player.Scoin } }, { 10019u, new PropValue { Type = 10019, Ival = 8, Val = 8 } }, { 10020u, new PropValue { Type = 10020, Ival = 160, Val = 160 } } } }); await session.NotifyAsync(CmdType.AvatarDataNotify, BuildAvatarData(player)); await session.NotifyAsync(CmdType.PlayerStoreNotify, BuildStore(player)); OpenStateUpdateNotify openStateNotify = new(); foreach (uint openStateId in openStates.Ids) openStateNotify.OpenStateMap[openStateId] = 1; await session.NotifyAsync(CmdType.OpenStateUpdateNotify, openStateNotify); await session.NotifyAsync(CmdType.PlayerEnterSceneNotify, new PlayerEnterSceneNotify { SceneId = GameState.SceneId, Pos = state.CurrentPos, SceneBeginTime = (ulong)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), Type = EnterType.EnterSelf, TargetUid = player.Uid, EnterSceneToken = state.NextEnterSceneToken(), IsFirstLoginEnterScene = true, WorldLevel = 0, EnterReason = 1 }); return Response(CmdType.PlayerLoginRsp, new PlayerLoginRsp { Retcode = Retcode.RET_SUCC, GameBiz = "hk4e_global" }); } private static AvatarDataNotify BuildAvatarData(Player player) { AvatarDataNotify data = new() { CurAvatarTeamId = player.CurrentTeamId, ChooseAvatarGuid = player.CurrentAvatarGuid }; foreach (uint flycloak in Player.Flycloaks) data.OwnedFlycloakList.Add(flycloak); foreach (GameAvatar avatar in player.Avatars) data.AvatarList.Add(avatar.AsAvatarInfo()); AvatarTeam team = new() { TeamName = "Team " + player.CurrentTeamId }; team.AvatarGuidList.AddRange(player.TeamAvatarGuids); data.AvatarTeamMap.Add(player.CurrentTeamId, team); return data; } private static PlayerStoreNotify BuildStore(Player player) { PlayerStoreNotify store = new() { StoreType = StoreType.StorePack, WeightLimit = 30000 }; foreach (GameWeapon weapon in player.Weapons) store.ItemList.Add(weapon.AsItem()); foreach (GameReliquary reliquary in player.Reliquaries) store.ItemList.Add(reliquary.AsItem()); foreach ((uint itemId, uint count) in player.Materials) store.ItemList.Add(new Item { ItemId = itemId, Guid = ((ulong)player.Uid << 32) | itemId, Material = new Material { Count = count } }); return store; } }