Init enter game

This commit is contained in:
Naruse
2025-06-14 11:15:32 +08:00
commit 6a03b39f07
568 changed files with 92872 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
using KianaBH.Database.Account;
using KianaBH.GameServer.Server;
using KianaBH.Internationalization;
namespace KianaBH.GameServer.Command;
public class CommandArg
{
public string RawArg { get; } = "";
public List<string> Args { get; } = [];
public List<string> Attributes { get; } = [];
public ICommandSender Sender { get; }
public int TargetUid { get; set; } = 0;
public Connection? Target { get; set; }
public CommandArg(string rawArg, ICommandSender sender)
{
Sender = sender;
RawArg = rawArg;
foreach (var arg in rawArg.Split(' '))
{
if (string.IsNullOrEmpty(arg)) continue;
Args.Add(arg);
}
}
public async ValueTask SendMsg(string msg)
{
await Sender.SendMsg(msg);
}
public int GetInt(int index)
{
if (Args.Count <= index) return 0;
if (int.TryParse(Args[index], out var res))
return res;
return 0;
}
public async ValueTask<int?> GetOption(char pre, string def = "1")
{
var opStr = Args.FirstOrDefault(x => x[0] == pre)?[1..] ?? def;
if (!int.TryParse(opStr, out var op))
{
await SendMsg(I18NManager.Translate("Game.Command.Notice.InvalidArguments"));
return null;
}
return op;
}
public async ValueTask<bool> CheckArgCnt(int start, int? end = null)
{
end ??= start;
if (Args.Count >= start && Args.Count <= end) return true;
await SendMsg(I18NManager.Translate("Game.Command.Notice.InvalidArguments"));
return false;
}
public async ValueTask<bool> CheckTarget()
{
if (AccountData.GetAccountByUid(TargetUid) == null)
{
await SendMsg(I18NManager.Translate("Game.Command.Notice.PlayerNotFound"));
return false;
}
return true;
}
public async ValueTask<bool> CheckOnlineTarget(bool sendMsg = true)
{
if (Target == null)
{
if (sendMsg)
await SendMsg(I18NManager.Translate("Game.Command.Notice.PlayerNotFound"));
return false;
}
return true;
}
}

View File

@@ -0,0 +1,25 @@
using KianaBH.Enums.Player;
namespace KianaBH.GameServer.Command;
[AttributeUsage(AttributeTargets.Class)]
public class CommandInfoAttribute(
string name, string desc, string usage, string[] alias, PermEnum[] perm) : Attribute
{
public string Name { get; } = name;
public string Description { get; } = desc;
public string Usage { get; } = usage;
public PermEnum[] Perm { get; } = perm;
public string[] Alias { get; } = alias;
}
[AttributeUsage(AttributeTargets.Method)]
public class CommandDefaultAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Method)]
public class CommandMethodAttribute(string method) : Attribute
{
public string MethodName { get; } = method;
}

View File

@@ -0,0 +1,19 @@

namespace KianaBH.GameServer.Command;
public static class CommandExecutor
{
public delegate void RunCommand(ICommandSender sender, string cmd);
public static event RunCommand? OnRunCommand;
public static void ExecuteCommand(ICommandSender sender, string cmd)
{
OnRunCommand?.Invoke(sender, cmd);
}
public static void ConsoleExcuteCommand(string input)
{
CommandManager.HandleCommand(input, new ConsoleCommandSender(CommandManager.Logger));
}
}

View File

@@ -0,0 +1,3 @@
namespace KianaBH.GameServer.Command;
public interface ICommands;

View File

@@ -0,0 +1,126 @@
using KianaBH.Database.Account;
using KianaBH.Enums.Player;
using KianaBH.GameServer.Server;
using KianaBH.Internationalization;
using KianaBH.KcpSharp;
using KianaBH.Util;
using System.Reflection;
namespace KianaBH.GameServer.Command;
public class CommandManager
{
public static Logger Logger { get; } = new("CommandManager");
public static Dictionary<string, ICommands> Commands { get; } = [];
public static Dictionary<string, CommandInfoAttribute> CommandInfo { get; } = [];
public static Dictionary<string, string> CommandAlias { get; } = []; // <aliaName, fullName>
public static void RegisterCommands()
{
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
if (typeof(ICommands).IsAssignableFrom(type) && !type.IsAbstract)
RegisterCommand(type);
Logger.Info(I18NManager.Translate("Server.ServerInfo.RegisterItem", Commands.Count.ToString(),
I18NManager.Translate("Word.Command")));
}
public static void RegisterCommand(Type type)
{
var attr = type.GetCustomAttribute<CommandInfoAttribute>();
if (attr == null) return;
var instance = Activator.CreateInstance(type);
if (instance is not ICommands command) return;
Commands.Add(attr.Name, command);
CommandInfo.Add(attr.Name, attr);
// register alias
foreach (var alias in attr.Alias) // add alias
CommandAlias.Add(alias, attr.Name);
}
public static async void HandleCommand(string input, ICommandSender sender)
{
try
{
var argInfo = new CommandArg(input, sender);
var target = sender.GetSender();
foreach (var arg in argInfo.Args.ToList()) // Copy
{
switch (arg[0])
{
case '-':
argInfo.Attributes.Add(arg[1..]);
break;
case '@':
_ = int.TryParse(arg[1..], out target);
argInfo.Args.Remove(arg);
break;
}
}
argInfo.TargetUid = target;
if (KcpListener.Connections.Values.ToList().Find(item =>
(item as Connection)?.Player?.Uid == target) is Connection con)
argInfo.Target = con;
// find register cmd
var cmdName = argInfo.Args[0];
if (CommandAlias.TryGetValue(cmdName, out var fullName)) cmdName = fullName;
if (!Commands.TryGetValue(cmdName, out var command))
{
await sender.SendMsg(I18NManager.Translate("Game.Command.Notice.CommandNotFound"));
return;
}
argInfo.Args.RemoveAt(0);
var cmdInfo = CommandInfo[cmdName];
// Check cmd perms
if (!AccountData.HasPerm(cmdInfo.Perm, sender.GetSender()))
{
await sender.SendMsg(I18NManager.Translate("Game.Command.Notice.NoPermission"));
return;
}
if (argInfo.Target?.Player?.Uid != sender.GetSender() && !AccountData.HasPerm([PermEnum.Other], sender.GetSender()))
{
await sender.SendMsg(I18NManager.Translate("Game.Command.Notice.NoPermission"));
return;
}
// find CommandMethodAttribute
var isFound = false;
foreach (var methodInfo in command.GetType().GetMethods())
{
var attr = methodInfo.GetCustomAttribute<CommandMethodAttribute>();
if (attr == null) continue;
if (argInfo.Args.Count > 0 && attr.MethodName == argInfo.Args[0])
{
argInfo.Args.RemoveAt(0);
isFound = true;
methodInfo.Invoke(command, [argInfo]);
break;
}
}
if (isFound) return;
// find CommandDefaultAttribute
foreach (var methodInfo in command.GetType().GetMethods())
{
var attr = methodInfo.GetCustomAttribute<CommandDefaultAttribute>();
if (attr == null) continue;
isFound = true;
methodInfo.Invoke(command, [argInfo]);
break;
}
if (isFound) return;
// failed to find method
await sender.SendMsg(I18NManager.Translate(cmdInfo.Usage));
}
catch (Exception ex)
{
Logger.Error(I18NManager.Translate("Game.Command.Notice.InternalError", ex.ToString()));
}
}
}

View File

@@ -0,0 +1,41 @@
using KianaBH.Enums.Player;
using KianaBH.GameServer.Game.Player;
using KianaBH.Util;
namespace KianaBH.GameServer.Command;
public interface ICommandSender
{
public ValueTask SendMsg(string msg);
public int GetSender();
}
public class ConsoleCommandSender(Logger logger) : ICommandSender
{
public async ValueTask SendMsg(string msg)
{
logger.Info(msg);
await Task.CompletedTask;
}
public int GetSender()
{
return (int)ServerEnum.Console;
}
}
public class PlayerCommandSender(PlayerInstance player) : ICommandSender
{
public PlayerInstance Player = player;
public async ValueTask SendMsg(string msg)
{
// TODO SEND MSG
}
public int GetSender()
{
return Player.Uid;
}
}

View File

@@ -0,0 +1,63 @@
using KianaBH.Data;
using KianaBH.Data.Excel;
using KianaBH.Database;
using KianaBH.Database.Avatar;
using KianaBH.Enums.Item;
using KianaBH.GameServer.Game.Player;
using KianaBH.GameServer.Server.Packet.Send.Avatar;
using KianaBH.Util.Extensions;
namespace KianaBH.GameServer.Game.Avatar;
public class AvatarManager(PlayerInstance player) : BasePlayerManager(player)
{
public AvatarData AvatarData { get; } = DatabaseHelper.GetInstanceOrCreateNew<AvatarData>(player.Uid);
public async ValueTask<AvatarDataExcel?> AddAvatar(int avatarId, bool sync = true)
{
GameData.AvatarData.TryGetValue(avatarId, out var avatarExcel);
if (avatarExcel == null) return null;
var avatar = new AvatarInfo
{
Level = 1,
Timestamp = Extensions.GetUnixSec(),
Star = avatarExcel.UnlockStar,
DressId = avatarExcel.DefaultDressId,
DressList = {avatarExcel.DefaultDressId},
AvatarId = avatarExcel.AvatarID,
};
foreach (var skill in avatarExcel.SkillList)
{
avatar.SkillList.Add(new AvatarSkill
{
SkillId = skill
});
};
var weapon = GameData.WeaponData.TryGetValue(avatarExcel.InitialWeapon, out var weaponConfig);
if (weaponConfig != null)
{
var item = await Player.InventoryManager!.AddItem(avatarExcel.InitialWeapon, 1, ItemMainTypeEnum.Weapon, weaponConfig.MaxLv, avatarId);
if (item != null)
{
avatar.WeaponUniqueId = item!.UniqueId;
};
};
AvatarData.Avatars.Add(avatar);
if (sync) await Player.SendPacket(new PacketGetAvatarDataRsp(new List<AvatarInfo> { avatar }, false));
return avatarExcel;
}
public AvatarInfo? GetAvatar(uint avatarId)
{
return AvatarData.Avatars.Find(avatar => avatar.AvatarId == avatarId);
}
}

View File

@@ -0,0 +1,8 @@
using KianaBH.GameServer.Game.Player;
namespace KianaBH.GameServer.Game;
public class BasePlayerManager(PlayerInstance player)
{
public PlayerInstance Player { get; private set; } = player;
}

View File

@@ -0,0 +1,86 @@
using KianaBH.Data;
using KianaBH.Database;
using KianaBH.Database.Inventory;
using KianaBH.Enums.Item;
using KianaBH.GameServer.Game.Player;
using KianaBH.Proto;
using KianaBH.Util;
using static KianaBH.Proto.MasterPupilRetcode.Types;
namespace KianaBH.GameServer.Game.Inventory;
public class InventoryManager(PlayerInstance player) : BasePlayerManager(player)
{
public InventoryData Data = DatabaseHelper.GetInstanceOrCreateNew<InventoryData>(player.Uid);
public async ValueTask<ItemData?> AddItem(int itemId, int count, ItemMainTypeEnum type, int level = 1, int equipAvatar = 0, bool notify = true,
bool sync = true)
{
ItemData? itemData = null;
switch (type)
{
case ItemMainTypeEnum.Material:
GameData.MaterialData.TryGetValue(itemId, out var materialConfig);
if (materialConfig == null) return null;
itemData = await PutItem(itemId, count, type);
break;
case ItemMainTypeEnum.Weapon:
GameData.WeaponData.TryGetValue(itemId, out var weaponConfig);
if (weaponConfig == null) return null;
itemData = await PutItem(itemId, 1, type, level, equipAvatar: equipAvatar, uniqueId: ++Data.NextUniqueId);
break;
default:
break;
}
return itemData;
}
public async ValueTask<ItemData> PutItem(int itemId, int count, ItemMainTypeEnum type, int level = 0,
int exp = 0, int equipAvatar = 0, int uniqueId = 0)
{
var item = new ItemData
{
ItemId = itemId,
Count = count,
Level = level,
Exp = exp,
EquipAvatar = equipAvatar,
};
if (uniqueId > 0) item.UniqueId = uniqueId;
switch (type)
{
case ItemMainTypeEnum.Material:
var oldItem = Data.MaterialItems.Find(x => x.ItemId == itemId);
if (oldItem != null)
{
oldItem.Count += count;
item = oldItem;
break;
}
Data.MaterialItems.Add(item);
break;
case ItemMainTypeEnum.Weapon:
if (Data.WeaponItems.Count + 1 > GameConstants.INVENTORY_MAX_EQUIPMENT)
{
return item;
}
Data.WeaponItems.Add(item);
break;
case ItemMainTypeEnum.Stigmata:
if (Data.StigmataItems.Count + 1 > GameConstants.INVENTORY_MAX_EQUIPMENT)
{
return item;
}
Data.StigmataItems.Add(item);
break;
}
return item;
}
}

View File

@@ -0,0 +1,110 @@
using KianaBH.Data;
using KianaBH.Database;
using KianaBH.Database.Account;
using KianaBH.Database.Client;
using KianaBH.Database.Player;
using KianaBH.GameServer.Game.Avatar;
using KianaBH.GameServer.Game.Inventory;
using KianaBH.GameServer.Server;
using KianaBH.KcpSharp;
using KianaBH.Util.Extensions;
namespace KianaBH.GameServer.Game.Player;
public class PlayerInstance(PlayerData data)
{
public AvatarManager? AvatarManager { get; private set; }
public InventoryManager? InventoryManager { get; private set; }
public static readonly List<PlayerInstance> _playerInstances = [];
public PlayerData Data { get; set; } = data;
public ClientData? ClientData { get; private set; }
public GuideData? GuideData { get; private set; }
public int Uid { get; set; }
public Connection? Connection { get; set; }
public bool Initialized { get; set; }
public bool IsNewPlayer { get; set; }
public int GetMissionDataRequestCount = 0;
#region Initializers
public PlayerInstance(int uid) : this(new PlayerData { Uid = uid })
{
// new player
IsNewPlayer = true;
Data.Name = AccountData.GetAccountByUid(uid)?.Username;
DatabaseHelper.CreateInstance(Data);
var t = Task.Run(async () =>
{
await InitialPlayerManager();
await AvatarManager!.AddAvatar(101);
GuideData?.GuideFinishList.AddRange(GameData.TutorialData.Values.Select(x => x.Id));
});
t.Wait();
Initialized = true;
}
private async ValueTask InitialPlayerManager()
{
Uid = Data.Uid;
AvatarManager = new AvatarManager(this);
InventoryManager = new InventoryManager(this);
ClientData = InitializeDatabase<ClientData>();
GuideData = InitializeDatabase<GuideData>();
Data.LastActiveTime = Extensions.GetUnixSec();
await Task.CompletedTask;
}
public T InitializeDatabase<T>() where T : BaseDatabaseDataHelper, new()
{
var instance = DatabaseHelper.GetInstanceOrCreateNew<T>(Uid);
return instance!;
}
#endregion
#region Network
public async ValueTask OnGetToken()
{
if (!Initialized) await InitialPlayerManager();
}
public async ValueTask OnLogin()
{
_playerInstances.Add(this);
await Task.CompletedTask;
}
public static PlayerInstance? GetPlayerInstanceByUid(long uid)
=> _playerInstances.FirstOrDefault(player => player.Uid == uid);
public void OnLogoutAsync()
{
_playerInstances.Remove(this);
}
public async ValueTask SendPacket(BasePacket packet)
{
if (Connection?.IsOnline == true) await Connection.SendPacket(packet);
}
#endregion
#region Actions
public async ValueTask OnHeartBeat()
{
DatabaseHelper.ToSaveUidList.SafeAdd(Uid);
await Task.CompletedTask;
}
#endregion
#region Serialization
public Proto.GetMainDataRsp ToProto()
{
return Data.ToProto();
}
#endregion
}

View File

@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<CETCompat>false</CETCompat>
<RootNamespace>KianaBH.GameServer</RootNamespace>
<StartupObject></StartupObject>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AssemblyName>KianaGameServer</AssemblyName>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\KcpSharp\KcpSharp.csproj" />
<ProjectReference Include="..\Proto\Proto.csproj" />
<PackageReference Include="System.IO.Pipelines" Version="9.0.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,189 @@
using KianaBH.GameServer.Game.Player;
using KianaBH.GameServer.Server.Packet;
using KianaBH.KcpSharp;
using KianaBH.KcpSharp.Base;
using KianaBH.Proto;
using KianaBH.Util;
using KianaBH.Util.Extensions;
using KianaBH.Util.Security;
using Google.Protobuf;
using Google.Protobuf.Reflection;
using System.Buffers;
using System.Net;
using System.Reflection;
using Newtonsoft.Json.Linq;
using System.Reflection.PortableExecutable;
using System.Net.Sockets;
using System.Reflection.Emit;
namespace KianaBH.GameServer.Server;
public class Connection(KcpConversation conversation, IPEndPoint remote) : KcpConnection(conversation, remote)
{
private static readonly Logger Logger = new("GameServer");
public PlayerInstance? Player { get; set; }
private static readonly HashSet<string> DummyPacketNames =
[
"AddGoodfeelReq", "ArkPlusActivityGetDataReq", "BuffAssistGetActivityReq", "BwWorldCampActivityGetDataReq",
"ChatworldBeastGetActivityReq", "ChatworldGetPrayInfoReq", "ClientReportReq", "GetAdventureGroupReq",
"GetArmadaDataReq", "GetArmadaStageScoreActivityReq", "GetAskAddFriendListReq", "GetAssistantFrozenListReq",
"GetAvatarMissionActivityReq", "GetBattlePassMissionPanelReq", "GetBlackListReq", "GetCardProductInfoReq",
"GetChapterActivityDataReq", "GetChapterCompensationInfoReq", "GetChatgroupListReq", "GetClientMailDataReq",
"GetConsignedOrderDataReq", "GetCurrencyExchangeInfoReq", "GetExtractReforgeActivityReq",
"GetFarmActivityDataReq", "GetFriendListReq", "GetFriendRemarkListReq", "GetGachaDisplayReq",
"GetGardenScheduleReq", "GetGobackReq", "GetGratuityActivityReq", "GetMasterPupilCardReq",
"GetMasterPupilDataReq", "GetMasterPupilMainDataReq", "GetMosaicActivityReq", "GetNewbieActivityReq",
"GetNinjaActivityReq", "GetOfflineResourceDataReq", "GetOpenworldQuestActivityReq",
"GetRaffleActivityReq", "GetRankScheduleDataReq", "GetRecommendFriendListReq", "GetRecommendGoodsReq",
"GetRoomDataReq", "GetRpgTaleReq", "GetScratchTicketReq", "GetSecurityPasswordReq", "GetShoppingMallListReq",
"GetStageChapterReq", "GetSupportActivityReq", "GetSurveyDataReq",
"GetTradingCardActivityReq", "GetTvtActivityReq", "GetWeeklyRoutineActivityReq", "GrandKeyActivateSkillReq",
"MassiveWarGetActivityReq", "OpenworldGetMechaTeamReq", "OpenworldHuntActivityGetDataReq",
"PjmsGetAchievementDataReq", "PjmsGetConditionDataReq", "PjmsGetCurWorldReq", "PjmsGetStoryDataReq",
"ReunionCookGetActivityReq", "SimplifiedGodWarGetActivityReq",
"StageInnerDataReportReq", "SusannaTrialGetActivityReq", "ThemeWantedRefreshTicketReq",
"UpdateMissionProgressReq", "WaveRushGetActivityReq"
];
public override async void Start()
{
Logger.Info($"New connection from {RemoteEndPoint}.");
State = SessionStateEnum.WAITING_FOR_TOKEN;
await ReceiveLoop();
}
public override async void Stop(bool isServerStop = false)
{
//if (isServerStop) await Player!.SendPacket(new PacketPlayerKickOutScNotify(KickType.KickLoginWhiteTimeout));
Player?.OnLogoutAsync();
KcpListener.UnregisterConnection(this);
base.Stop(isServerStop);
}
protected async Task ReceiveLoop()
{
while (!CancelToken.IsCancellationRequested)
{
// WaitToReceiveAsync call completes when there is at least one message is received or the transport is closed.
var result = await Conversation.WaitToReceiveAsync(CancelToken.Token);
if (result.TransportClosed)
{
Logger.Debug("Connection was closed");
break;
}
var buffer = ArrayPool<byte>.Shared.Rent(result.BytesReceived);
try
{
// TryReceive should not return false here, unless the transport is closed.
// So we don't need to check for result.TransportClosed.
if (!Conversation.TryReceive(buffer, out result))
{
Logger.Error("Failed to receive packet");
break;
}
await ProcessMessageAsync(buffer.AsMemory(0, result.BytesReceived));
}
catch (Exception ex)
{
Logger.Error("Packet parse error", ex);
}
finally
{
ArrayPool<byte>.Shared.Return(buffer);
}
}
Stop();
}
// DO THE PROCESSING OF THE GAME PACKET
private async Task ProcessMessageAsync(Memory<byte> data)
{
var gamePacket = data.ToArray();
await using MemoryStream ms = new(gamePacket);
using BinaryReader br = new(ms);
// Handle
try
{
while (br.BaseStream.Position < br.BaseStream.Length)
{
// Length
if (br.BaseStream.Length - br.BaseStream.Position < 32) return;
// Packet sanity check
var headMagic = br.ReadUInt32BE();
if (headMagic != 0x01234567)
{
Logger.Error($"Bad Data Package Received: got 0x{headMagic:X}, expect 0x01234567");
return; // Bad packet
}
var packetVersion = br.ReadUInt16BE();
var ClientVersion = br.ReadUInt16BE();
var PacketId = br.ReadUInt32BE();
var UserId = br.ReadUInt32BE();
var UserIp = br.ReadUInt32BE();
var Sign = br.ReadUInt32BE();
var SignType = br.ReadUInt16BE();
var CmdId = br.ReadUInt16BE();
var HeaderLength = br.ReadUInt16BE();
var BodyLength = br.ReadUInt32BE();
// Data
var header = br.ReadBytes(HeaderLength);
var Body = br.ReadBytes((int)BodyLength);
var TailMagic = br.ReadUInt32BE();
LogPacket("Recv", CmdId, Body);
await HandlePacket(CmdId, header, Body);
}
}
catch (Exception e)
{
Logger.Error(e.Message, e);
}
}
private async Task HandlePacket(ushort opcode, byte[] header, byte[] payload)
{
var packetName = LogMap.GetValueOrDefault(opcode);
if (DummyPacketNames.Contains(packetName!))
{
await SendDummy(packetName!);
Logger.Info($"[Dummy] Send Dummy {packetName}");
return;
}
// Find the Handler for this opcode
var handler = HandlerManager.GetHandler(opcode);
if (handler != null)
{
// Handle
// Make sure session is ready for packets
var state = State;
try
{
await handler.OnHandle(this, header, payload);
}
catch (Exception e)
{
Logger.Error(e.Message, e);
}
return;
}
}
private async Task SendDummy(string packetName)
{
var respName = packetName.Replace("Req", "Rsp"); // Get the response packet name
if (respName == packetName) return; // do not send rsp when resp name = recv name
var respOpcode = LogMap.FirstOrDefault(x => x.Value == respName).Key; // Get the response opcode
// Send Rsp
await SendPacket(respOpcode);
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.KcpSharp;
namespace KianaBH.GameServer.Server;
public class Listener : KcpListener
{
public static Connection? GetActiveConnection(int uid)
{
var con = Connections.Values.FirstOrDefault(c =>
(c as Connection)?.Player?.Uid == uid && c.State == SessionStateEnum.ACTIVE) as Connection;
return con;
}
}

View File

@@ -0,0 +1,6 @@
namespace KianaBH.GameServer.Server.Packet;
public abstract class Handler
{
public abstract Task OnHandle(Connection connection, byte[] header, byte[] data);
}

View File

@@ -0,0 +1,31 @@
using System.Reflection;
namespace KianaBH.GameServer.Server.Packet;
public static class HandlerManager
{
public static Dictionary<int, Handler> handlers = [];
public static void Init()
{
var classes = Assembly.GetExecutingAssembly().GetTypes(); // Get all classes in the assembly
foreach (var cls in classes)
{
var attribute = (Opcode?)Attribute.GetCustomAttribute(cls, typeof(Opcode));
if (attribute != null) handlers.Add(attribute.CmdId, (Handler)Activator.CreateInstance(cls)!);
}
}
public static Handler? GetHandler(int cmdId)
{
try
{
return handlers[cmdId];
}
catch
{
return null;
}
}
}

View File

@@ -0,0 +1,7 @@
namespace KianaBH.GameServer.Server.Packet;
[AttributeUsage(AttributeTargets.Class)]
public class Opcode(int cmdId) : Attribute
{
public int CmdId = cmdId;
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.ArkPlusActivityGetDataReq)]
public class HandlerArkPlusActivityGetDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketArkPlusActivityGetDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.BuffAssistGetActivityReq)]
public class HandlerBuffAssistGetActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketBuffAssistGetActivityRsp());
}
}

View File

@@ -0,0 +1,14 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GeneralActivityGetMainInfoReq)]
public class HandlerGeneralActivityGetMainInfoReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = GeneralActivityGetMainInfoReq.Parser.ParseFrom(data);
await connection.SendPacket(new PacketGeneralActivityGetMainInfoRsp(req.ActivityIdList));
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GeneralActivityGetScheduleReq)]
public class HandlerGeneralActivityGetScheduleReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGeneralActivityGetScheduleRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetActivityMainDataReq)]
public class HandlerGetActivityMainDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetActivityMainDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetActivityRewardStatisticDataReq)]
public class HandlerGetActivityRewardStatisticDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetActivityRewardStatisticDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetBulletinActivityMissionReq)]
public class HandlerGetBulletinActivityMissionReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetBulletinActivityMissionRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetBulletinReq)]
public class HandlerGetBulletinReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetBulletinRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetChapterActivityDataReq)]
public class HandlerGetChapterActivityDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetChapterActivityDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetChapterCompensationInfoReq)]
public class HandlerGetChapterCompensationInfoReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetChapterCompensationInfoRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetDropLimitActivityReq)]
public class HandlerGetDropLimitActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetDropLimitActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetExtractReforgeActivityReq)]
public class HandlerGetExtractReforgeActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetExtractReforgeActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetFarmActivityDataReq)]
public class HandlerGetFarmActivityDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetFarmActivityDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetGardenScheduleReq)]
public class HandlerGetGardenScheduleReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetGardenScheduleRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetInviteActivityInviteeDataReq)]
public class HandlerGetInviteActivityInviteeDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetInviteActivityInviteeDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetInviteActivityInviterDataReq)]
public class HandlerGetInviteActivityInviterDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetInviteActivityInviterDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetLoginActivityReq)]
public class HandlerGetLoginActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetLoginActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetMosaicActivityReq)]
public class HandlerGetMosaicActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetMosaicActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetNewbieActivityReq)]
public class HandlerGetNewbieActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetNewbieActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetNinjaActivityReq)]
public class HandlerGetNinjaActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetNinjaActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Activity;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Activity;
[Opcode(CmdIds.GetThemeWantedReq)]
public class HandlerGetThemeWantedReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetThemeWantedRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Adventure;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Adventure;
[Opcode(CmdIds.GetAdventureGroupReq)]
public class HandlerGetAdventureGroupReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetAdventureGroupRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Adventure;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Adventure;
[Opcode(CmdIds.GetAdventureStorySweepInfoReq)]
public class HandlerGetAdventureStorySweepInfoReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetAdventureStorySweepInfoRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Adventure;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Adventure;
[Opcode(CmdIds.GetConsignedOrderDataReq)]
public class HandlerGetConsignedOrderDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetConsignedOrderDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Armada;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Armada;
[Opcode(CmdIds.GetArmadaActivityListReq)]
public class HandlerGetArmadaActivityListReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetArmadaActivityListRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Armada;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Armada;
[Opcode(CmdIds.GetArmadaDataReq)]
public class HandlerGetArmadaDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetArmadaDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Armada;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Armada;
[Opcode(CmdIds.GetArmadaStageScoreActivityReq)]
public class HandlerGetArmadaStageScoreActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetArmadaStageScoreActivityRsp());
}
}

View File

@@ -0,0 +1,14 @@
using KianaBH.GameServer.Server.Packet.Send.Auth;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Auth;
[Opcode(CmdIds.GetAuthkeyReq)]
public class HandlerGetAuthkeyReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = GetAuthkeyReq.Parser.ParseFrom(data);
await connection.SendPacket(new PacketGetAuthkeyRsp(req.AuthAppid));
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Avatar;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Avatar;
[Opcode(CmdIds.AddCustomAvatarTeamReq)]
public class HandlerAddCustomAvatarTeamReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketAddCustomAvatarTeamRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Avatar;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Avatar;
[Opcode(CmdIds.AvatarSubSkillLevelUpReq)]
public class HandlerAvatarSubSkillLevelUpReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketAvatarSubSkillLevelUpRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Avatar;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Avatar;
[Opcode(CmdIds.DelCustomAvatarTeamReq)]
public class HandlerDelCustomAvatarTeamReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketDelCustomAvatarTeamRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Avatar;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Avatar;
[Opcode(CmdIds.DressEquipmentReq)]
public class HandlerDressEquipmentReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketDressEquipmentRsp());
}
}

View File

@@ -0,0 +1,25 @@
using KianaBH.Database.Avatar;
using KianaBH.GameServer.Game.Player;
using KianaBH.GameServer.Server.Packet.Send.Avatar;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Avatar;
[Opcode(CmdIds.GetAvatarDataReq)]
public class HandlerGetAvatarDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = GetAvatarDataReq.Parser.ParseFrom(data);
var player = connection.Player!;
var avatars = req.AvatarIdList.Any(id => id != 0)
? req.AvatarIdList
.Select(id => player.AvatarManager!.GetAvatar(id))
.Where(avatar => avatar != null)
.ToList()!
: player.AvatarManager?.AvatarData?.Avatars?.ToList();
bool isAll = !req.AvatarIdList.Any(id => id != 0);
await connection.SendPacket(new PacketGetAvatarDataRsp(avatars!, isAll));
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Avatar;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Avatar;
[Opcode(CmdIds.GetAvatarMissionActivityReq)]
public class HandlerGetAvatarMissionActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetAvatarMissionActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Avatar;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Avatar;
[Opcode(CmdIds.GetAvatarRollDataReq)]
public class HandlerGetAvatarRollDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetAvatarRollDataRsp(connection.Player!));
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Avatar;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Avatar;
[Opcode(CmdIds.GetAvatarTeamDataReq)]
public class HandlerGetAvatarTeamDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetAvatarTeamDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Avatar;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Avatar;
[Opcode(CmdIds.UpdateCustomAvatarTeamReq)]
public class HandlerUpdateCustomAvatarTeamReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketUpdateCustomAvatarTeamRsp());
}
}

View File

@@ -0,0 +1,14 @@
using KianaBH.GameServer.Server.Packet.Send.Battle;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Battle;
[Opcode(CmdIds.GetBuffEffectReq)]
public class HandlerGetBuffEffectReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = GetBuffEffectReq.Parser.ParseFrom(data);
await connection.SendPacket(new PacketGetBuffEffectRsp(req.EffectIdList));
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.BattlePass;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.BattlePass;
[Opcode(CmdIds.GetBattlePassMissionPanelReq)]
public class HandlerGetBattlePassMissionPanelReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetBattlePassMissionPanelRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Challenge;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Challenge;
[Opcode(CmdIds.GetChallengeStepCompensationInfoReq)]
public class HandlerGetChallengeStepCompensationInfoReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetChallengeStepCompensationInfoRsp());
}
}

View File

@@ -0,0 +1,14 @@
using KianaBH.GameServer.Server.Packet.Send.Chapter;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Chapter;
[Opcode(CmdIds.ChapterArkGetDataReq)]
public class HandlerChapterArkGetDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = ChapterArkGetDataReq.Parser.ParseFrom(data);
await connection.SendPacket(new PacketChapterArkGetDataRsp(req.ChapterId));
}
}

View File

@@ -0,0 +1,14 @@
using KianaBH.GameServer.Server.Packet.Send.Chapter;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Chapter;
[Opcode(CmdIds.ChapterBwWorldGetDataReq)]
public class HandlerChapterBwWorldGetDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = ChapterBwWorldGetDataReq.Parser.ParseFrom(data);
await connection.SendPacket(new PacketChapterBwWorldGetDataRsp(req.ChapterId));
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Chapter;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Chapter;
[Opcode(CmdIds.ChapterGroupGetDataReq)]
public class HandlerChapterGroupGetDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketChapterGroupGetDataRsp());
}
}

View File

@@ -0,0 +1,14 @@
using KianaBH.GameServer.Server.Packet.Send.Chapter;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Chapter;
[Opcode(CmdIds.ChapterKnightRichManGetDataReq)]
public class HandlerChapterKnightRichManGetDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = ChapterKnightRichManGetDataReq.Parser.ParseFrom(data);
await connection.SendPacket(new PacketChapterKnightRichManGetDataRsp(req.RichManId));
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Chapter;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Chapter;
[Opcode(CmdIds.GetEliteChapterCompensationInfoReq)]
public class HandlerGetEliteChapterCompensationInfoReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetEliteChapterCompensationInfoRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Chat;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Chat;
[Opcode(CmdIds.ChatworldBeastGetActivityReq)]
public class HandlerChatworldBeastGetActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketChatworldBeastGetActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Chat;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Chat;
[Opcode(CmdIds.ChatworldGetActivityScheduleReq)]
public class HandlerChatworldGetActivityScheduleReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketChatworldGetActivityScheduleRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Chat;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Chat;
[Opcode(CmdIds.ChatworldGetPrayInfoReq)]
public class HandlerChatworldGetPrayInfoReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketChatworldGetPrayInfoRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Chat;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Chat;
[Opcode(CmdIds.EnterWorldChatroomReq)]
public class HandlerEnterWorldChatroomReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketEnterWorldChatroomRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Chat;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Chat;
[Opcode(CmdIds.GetChatgroupListReq)]
public class HandlerGetChatgroupListReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetChatgroupListRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Client;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Client;
[Opcode(CmdIds.ClientReportReq)]
public class HandlerClientReportReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketClientReportRsp());
}
}

View File

@@ -0,0 +1,15 @@
using KianaBH.GameServer.Server.Packet.Send.Client;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Client;
[Opcode(CmdIds.GetClientDataReq)]
public class HandlerGetClientDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = GetClientDataReq.Parser.ParseFrom(data);
await connection.SendPacket(new PacketGetClientDataRsp(req.Id,req.Type, connection.Player!));
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Client;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Client;
[Opcode(CmdIds.GetClientMailDataReq)]
public class HandlerGetClientMailDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetClientMailDataRsp());
}
}

View File

@@ -0,0 +1,14 @@
using KianaBH.GameServer.Server.Packet.Send.Client;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Client;
[Opcode(CmdIds.GetClientSettingReq)]
public class HandlerGetClientSettingReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = GetClientSettingReq.Parser.ParseFrom(data);
await connection.SendPacket(new PacketGetClientSettingRsp(req.ClientSettingType));
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Client;
[Opcode(CmdIds.KeepAliveNotify)]
public class HandlerKeepAliveNotify : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.Player!.OnHeartBeat();
await connection.SendPacket(CmdIds.KeepAliveNotify);
}
}

View File

@@ -0,0 +1,14 @@
using KianaBH.GameServer.Server.Packet.Send.Client;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Client;
[Opcode(CmdIds.ReportClientDataVersionReq)]
public class HandlerReportClientDataVersionReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = ReportClientDataVersionReq.Parser.ParseFrom(data);
await connection.SendPacket(new PacketReportClientDataVersionRsp(req.Version));
}
}

View File

@@ -0,0 +1,27 @@
using KianaBH.GameServer.Game.Player;
using KianaBH.GameServer.Server.Packet.Send.Client;
using KianaBH.Proto;
using KianaBH.Database.Client;
namespace KianaBH.GameServer.Server.Packet.Recv.Client;
[Opcode(CmdIds.SetClientDataReq)]
public class HandlerSetClientDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = SetClientDataReq.Parser.ParseFrom(data);
PlayerInstance player = connection.Player!;
var clientData = player.ClientData!.Clients.FirstOrDefault(c => c.Id == req.ClientData.Id && c.Type == req.ClientData.Type);
if (clientData == null)
{
player.ClientData.Clients.Add(new ClientDBData
{
Id = req.ClientData.Id,
Type = req.ClientData.Type,
Data = req.ClientData.Data.ToByteArray(),
});
}
await connection.SendPacket(new PacketSetClientDataRsp(req.ClientData.Id,req.ClientData.Type));
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Collection;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Collection;
[Opcode(CmdIds.GetCollectionListReq)]
public class HandlerGetCollectionListReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetCollectionListRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.DLC;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.DLC;
[Opcode(CmdIds.GetDLCAvatarReq)]
public class HandlerGetDLCAvatarReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetDLCAvatarRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.DLC;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.DLC;
[Opcode(CmdIds.GetDLCReq)]
public class HandlerGetDLCReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetDLCRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.DLC;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.DLC;
[Opcode(CmdIds.GetDLCTowerReq)]
public class HandlerGetDLCTowerReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetDLCTowerRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dorm;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dorm;
[Opcode(CmdIds.GetDormDataReq)]
public class HandlerGetDormDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetDormDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetPlotListReq)]
public class HandlerGetPlotListReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetPlotListRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetPrivilegeInfoReq)]
public class HandlerGetPrivilegeInfoReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetPrivilegeInfoRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetProductListReq)]
public class HandlerGetProductListReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetProductListRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetProductRecommendListReq)]
public class HandlerGetProductRecommendListReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetProductRecommendListRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetRaffleActivityReq)]
public class HandlerGetRaffleActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetRaffleActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetRankScheduleDataReq)]
public class HandlerGetRankScheduleDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetRankScheduleDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetRecommendFriendListReq)]
public class HandlerGetRecommendFriendListReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetRecommendFriendListRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetRecommendGoodsReq)]
public class HandlerGetRecommendGoodsReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetRecommendGoodsRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetRewardLineActivityReq)]
public class HandlerGetRewardLineActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetRewardLineActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetRoomDataReq)]
public class HandlerGetRoomDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetRoomDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetRpgTaleReq)]
public class HandlerGetRpgTaleReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetRpgTaleRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetScratchTicketReq)]
public class HandlerGetScratchTicketReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetScratchTicketRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetSecurityPasswordReq)]
public class HandlerGetSecurityPasswordReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetSecurityPasswordRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetShopListReq)]
public class HandlerGetShopListReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetShopListRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetShoppingMallListReq)]
public class HandlerGetShoppingMallListReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetShoppingMallListRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetSupportActivityReq)]
public class HandlerGetSupportActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetSupportActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetSurveyDataReq)]
public class HandlerGetSurveyDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetSurveyDataRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetTowerRaidActivityReq)]
public class HandlerGetTowerRaidActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetTowerRaidActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetTradingCardActivityReq)]
public class HandlerGetTradingCardActivityReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetTradingCardActivityRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetTrialAvatarReq)]
public class HandlerGetTrialAvatarReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetTrialAvatarRsp());
}
}

View File

@@ -0,0 +1,13 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetVipRewardDataReq)]
public class HandlerGetVipRewardDataReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
await connection.SendPacket(new PacketGetVipRewardDataRsp());
}
}

View File

@@ -0,0 +1,14 @@
using KianaBH.GameServer.Server.Packet.Send.Dummy;
using KianaBH.Proto;
namespace KianaBH.GameServer.Server.Packet.Recv.Dummy;
[Opcode(CmdIds.GetVirtualAvatarGroupDetailReq)]
public class HandlerGetVirtualAvatarGroupDetailReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = GetVirtualAvatarGroupDetailReq.Parser.ParseFrom(data);
await connection.SendPacket(new PacketGetVirtualAvatarGroupDetailRsp(req.GroupId));
}
}

Some files were not shown because too many files have changed in this diff Show More