From 62ae5eebad65da3e0fe339bd7d55079111476c5b Mon Sep 17 00:00:00 2001 From: Kaioru Date: Thu, 29 Aug 2024 00:02:30 +0800 Subject: [PATCH] Add SelectWorld handling --- .../Handling/Pipes/UserOnPacketSelectWorld.cs | 76 +++++++++++++------ .../Entities/CharacterExtensions.cs | 55 ++++++++++++++ 2 files changed, 106 insertions(+), 25 deletions(-) create mode 100644 src/protocol/Edelstein.Protocol.Gameplay/Entities/CharacterExtensions.cs diff --git a/src/common/Edelstein.Common.Gameplay.Login/Handling/Pipes/UserOnPacketSelectWorld.cs b/src/common/Edelstein.Common.Gameplay.Login/Handling/Pipes/UserOnPacketSelectWorld.cs index f6ad7c68e..d132b409d 100644 --- a/src/common/Edelstein.Common.Gameplay.Login/Handling/Pipes/UserOnPacketSelectWorld.cs +++ b/src/common/Edelstein.Common.Gameplay.Login/Handling/Pipes/UserOnPacketSelectWorld.cs @@ -1,46 +1,72 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Edelstein.Protocol.Gameplay.Contracts.Packets.Shared; +using Edelstein.Protocol.Gameplay.Entities; using Edelstein.Protocol.Gameplay.Handling; using Edelstein.Protocol.Gameplay.Login; using Edelstein.Protocol.Gameplay.Login.Contracts.Packets; using Edelstein.Protocol.Gameplay.Login.Contracts.Packets.Recv; using Edelstein.Protocol.Gameplay.Login.Contracts.Packets.Send; +using Edelstein.Protocol.Services.Server; +using Edelstein.Protocol.Services.Server.Contracts; using Edelstein.Protocol.Utilities.Pipelines; namespace Edelstein.Common.Gameplay.Login.Handling.Pipes; -public class UserOnPacketSelectWorld : IPipe> +public class UserOnPacketSelectWorld( + IServerService servers, + IAccountWorldDataRepository accountWorldDataRepository, + ICharacterRepository characterRepository +) : IPipe> { public async Task Handle(IPipelineContext ctx, PipedPacketMessage message) { if (message.User.State != LoginState.SelectWorld) return; - - await message.User.Dispatch(new SelectWorldResult + + try { - Result = LoginResultCode.Success, - Info = new SelectWorldResultSuccessInfo + var response = await servers.GetGameByWorldAndChannel(new ServerServiceGetByWorldAndChannelRequest + { + WorldID = message.Packet.WorldID, + ChannelID = message.Packet.ChannelID + }); + var accountWorldData = await accountWorldDataRepository.RetrieveByAccountAndWorld(message.User.Account!.ID, response.Info!.WorldID) ?? + await accountWorldDataRepository.Insert(new AccountWorldData + { + AccountID = message.User.Account.ID, + WorldID = response.Info.WorldID + }); + var characters = await characterRepository.RetrieveAllByAccountWorldData(accountWorldData.ID); + + message.User.AccountWorldData = accountWorldData; + message.User.State = LoginState.SelectCharacter; + message.User.SelectedWorldID = (byte)response.Info!.WorldID; + message.User.SelectedChannelID = (byte)response.Info!.ChannelID; + + await message.User.Dispatch(new SelectWorldResult { - Characters = new List + Result = LoginResultCode.Success, + Info = new SelectWorldResultSuccessInfo { - new() - { - CharacterStat = new StructuredCharacterStat + Characters = characters + .Select(c => new SelectWorldResultSuccessInfoCharacter { - ID = 1, - Name = "Beef", - Hair = 30000, - Face = 20724 - }, - AvatarLook = new StructuredAvatarLook - { - Hair = 30000, - Face = 20724 - } - } - }, - SlotCount = 3 - } - }); + CharacterStat = c.ToStructuredCharacterStat(), + AvatarLook = c.ToStructuredAvatarLook() + }) + .ToList(), + SlotCount = accountWorldData.CharacterSlotMax + } + }); + } + catch (Exception) + { + await message.User.Dispatch(new SelectWorldResult + { + Result = LoginResultCode.Unknown + }); + } } } diff --git a/src/protocol/Edelstein.Protocol.Gameplay/Entities/CharacterExtensions.cs b/src/protocol/Edelstein.Protocol.Gameplay/Entities/CharacterExtensions.cs new file mode 100644 index 000000000..4600d799b --- /dev/null +++ b/src/protocol/Edelstein.Protocol.Gameplay/Entities/CharacterExtensions.cs @@ -0,0 +1,55 @@ +using Edelstein.Protocol.Gameplay.Contracts.Packets.Shared; + +namespace Edelstein.Protocol.Gameplay.Entities; + +public static class CharacterExtensions +{ + public static StructuredCharacterStat ToStructuredCharacterStat(this Character character) + => new() + { + ID = character.ID, + Name = character.Name, + Gender = character.Gender, + Skin = character.Skin, + Face = character.Face, + Hair = character.Hair, + + Level = character.Level, + Job = character.Job, + STR = character.STR, + DEX = character.DEX, + INT = character.INT, + LUK = character.LUK, + HP = character.HP, + MaxHP = character.MaxHP, + MP = character.MP, + MaxMP = character.MaxMP, + + AP = character.AP, + SP = character.SP, + + EXP = character.EXP, + POP = character.POP, + TempEXP = character.TempEXP, + + PosMap = character.FieldID, + Portal = character.FieldPortal, + + Playtime = character.PlayTime, + + SubJob = character.SubJob + }; + + public static StructuredAvatarLook ToStructuredAvatarLook(this Character character) + { + // TODO inventories + + return new StructuredAvatarLook + { + Gender = character.Gender, + Skin = character.Skin, + Face = character.Face, + Hair = character.Hair + }; + } +}