From 18b22db021c0bbd6bfb5739721e01710a86c6a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Sun, 26 Dec 2021 23:00:54 +0100 Subject: [PATCH] feat: add packet api for chat and skills --- .../Apis/NostaleChatPacketApi.cs | 107 ++++++++++ .../Apis/NostaleSkillsPacketApi.cs | 182 ++++++++++++++++++ .../Extensions/ServiceCollectionExtensions.cs | 5 + 3 files changed, 294 insertions(+) create mode 100644 Core/NosSmooth.Game/Apis/NostaleChatPacketApi.cs create mode 100644 Core/NosSmooth.Game/Apis/NostaleSkillsPacketApi.cs diff --git a/Core/NosSmooth.Game/Apis/NostaleChatPacketApi.cs b/Core/NosSmooth.Game/Apis/NostaleChatPacketApi.cs new file mode 100644 index 0000000..467f643 --- /dev/null +++ b/Core/NosSmooth.Game/Apis/NostaleChatPacketApi.cs @@ -0,0 +1,107 @@ +// +// NostaleChatPacketApi.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosCore.Packets.Enumerations; +using NosCore.Packets.ServerPackets.Chats; +using NosSmooth.Core.Client; +using NosSmooth.Game.Data.Entities; +using Remora.Results; + +namespace NosSmooth.Game.Apis; + +/// +/// Packet api for sending and receiving messages. +/// +public class NostaleChatPacketApi +{ + // TODO: check length of the messages + private readonly INostaleClient _client; + + /// + /// Initializes a new instance of the class. + /// + /// The nostale client. + public NostaleChatPacketApi(INostaleClient client) + { + _client = client; + } + + /// + /// Receive the given system message on the client. + /// + /// + /// Won't send anything to the server, it's just the client who will see the message. + /// + /// The content of the message. + /// The color of the message. + /// The cancellation token for cancelling the operation. + /// A result that may or may not have succeeded. + public Task ReceiveSystemMessageAsync(string content, SayColorType color = SayColorType.Yellow, CancellationToken ct = default) + { + return _client.ReceivePacketAsync( + new SayPacket + { + Message = content, Type = color + }, + ct + ); + } + + /// + /// Sends the given message to the public chat. + /// + /// The content of the message. + /// The cancellation token for cancelling the operation. + /// A result that may or may not have succeeded. + public Task SendMessageAsync(string content, CancellationToken ct = default) + { + return _client.SendPacketAsync( + new SayPacket + { + Message = content + }, + ct + ); + } + + /// + /// Sends the given message to the family chat. + /// + /// + /// Should be used only if the user is in a family. + /// + /// The content of the message. + /// The cancellation token for cancelling the operation. + /// A result that may or may not have succeeded. + public Task SendFamilyMessage(string content, CancellationToken ct = default) + => _client.SendPacketAsync(":" + content, ct); + + /// + /// Sends the given message to the group chat. + /// + /// + /// Should be used only if the user is in a group. (with people, not only pets). + /// + /// The content of the message. + /// The cancellation token for cancelling the operation. + /// A result that may or may not have succeeded. + public Task SendGroupMessage(string content, CancellationToken ct = default) + => _client.SendPacketAsync(";" + content, ct); + + /// + /// Sends the given message to the target only. + /// + /// + /// Won't return if the whisper has actually came through, event has to be hooked + /// up to know if the whisper has went through (and you can know only for messages that are sufficiently long). + /// + /// The name of the user you want to whisper to. + /// The content of the message. + /// The cancellation token for cancelling the operation. + /// A result that may or may not have succeeded. + public Task SendWhisper(string targetName, string content, CancellationToken ct = default) + => _client.SendPacketAsync($"/{targetName} {content}", ct); +} \ No newline at end of file diff --git a/Core/NosSmooth.Game/Apis/NostaleSkillsPacketApi.cs b/Core/NosSmooth.Game/Apis/NostaleSkillsPacketApi.cs new file mode 100644 index 0000000..46aa443 --- /dev/null +++ b/Core/NosSmooth.Game/Apis/NostaleSkillsPacketApi.cs @@ -0,0 +1,182 @@ +// +// NostaleSkillsPacketApi.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosCore.Packets.ClientPackets.Battle; +using NosCore.Shared.Enumerations; +using NosSmooth.Core.Client; +using NosSmooth.Game.Data.Characters; +using NosSmooth.Game.Data.Entities; +using NosSmooth.Game.Errors; +using Remora.Results; + +namespace NosSmooth.Game.Apis; + +/// +/// Packet api for using character skills. +/// +public class NostaleSkillsPacketApi +{ + private readonly INostaleClient _client; + + /// + /// Initializes a new instance of the class. + /// + /// The nostale client. + public NostaleSkillsPacketApi(INostaleClient client) + { + _client = client; + } + + /// + /// Use the given (targetable) skill on specified entity. + /// + /// + /// For skills that can be used only on self, use of the character. + /// For skills that cannot be targeted on an entity, proceed to . + /// + /// The id of the skill. + /// The id of the entity to use the skill on. + /// The type of the supplied entity. + /// The x coordinate on the map. (Used for non targeted dashes etc., says where the dash will be to.) + /// The y coordinate on the map. (Used for non targeted dashes etc., says where the dash will be to.) + /// A result that may or may not have succeeded. + public Task UseSkillOn(long skillVNum, long entityId, VisualType entityType, short? mapX = default, short? mapY = default) + { + return _client.SendPacketAsync(new UseSkillPacket + { + CastId = skillVNum, + MapX = mapX, + MapY = mapY, + TargetId = entityId, + TargetVisualType = entityType + }); + } + + /// + /// Use the given (targetable) skill on specified entity. + /// + /// + /// For skills that can be used only on self, use of the character. + /// For skills that cannot be targeted on an entity, proceed to . + /// + /// The id of the skill. + /// The entity to use the skill on. + /// The x coordinate on the map. (Used for non targeted dashes etc., says where the dash will be to.) + /// The y coordinate on the map. (Used for non targeted dashes etc., says where the dash will be to.) + /// A result that may or may not have succeeded. + public Task UseSkillOn(long skillVNum, ILivingEntity entity, short? mapX = default, short? mapY = default) + { + return _client.SendPacketAsync(new UseSkillPacket + { + CastId = skillVNum, + MapX = mapX, + MapY = mapY, + TargetId = entity.Id, + TargetVisualType = entity.Type + }); + } + + /// + /// Use the given (targetable) skill on specified entity. + /// + /// + /// The skill won't be used if it is on cooldown. + /// For skills that can be used only on self, use of the character. + /// For skills that cannot be targeted on an entity, proceed to . + /// + /// The skill to use. + /// The entity to use the skill on. + /// The x coordinate on the map. (Used for non targeted dashes etc., says where the dash will be to.) + /// The y coordinate on the map. (Used for non targeted dashes etc., says where the dash will be to.) + /// A result that may or may not have succeeded. + public Task UseSkillOn(Skill skill, ILivingEntity entity, short? mapX = default, short? mapY = default) + { + if (skill.IsOnCooldown) + { + return Task.FromResult(new SkillOnCooldownError(skill)); + } + + return _client.SendPacketAsync(new UseSkillPacket + { + CastId = skill.SkillVNum, + MapX = mapX, + MapY = mapY, + TargetId = entity.Id, + TargetVisualType = entity.Type + }); + } + + /// + /// Use the given (targetable) skill on specified entity. + /// + /// + /// For skills that can be used only on self, use of the character. + /// For skills that cannot be targeted on an entity, proceed to . + /// + /// The skill to use. + /// The id of the entity to use the skill on. + /// The type of the supplied entity. + /// The x coordinate on the map. (Used for non targeted dashes etc., says where the dash will be to.) + /// The y coordinate on the map. (Used for non targeted dashes etc., says where the dash will be to.) + /// A result that may or may not have succeeded. + public Task UseSkillOn(Skill skill, long entityId, VisualType entityType, short? mapX = default, short? mapY = default) + { + if (skill.IsOnCooldown) + { + return Task.FromResult(new SkillOnCooldownError(skill)); + } + + return _client.SendPacketAsync(new UseSkillPacket + { + CastId = skill.SkillVNum, + MapX = mapX, + MapY = mapY, + TargetId = entityId, + TargetVisualType = entityType + }); + } + + /// + /// Use the given (aoe) skill on the specified place. + /// + /// + /// For skills that can have targets, proceed to . + /// + /// The id of the skill. + /// The x coordinate to use the skill at. + /// The y coordinate to use the skill at. + /// A result that may or may not have succeeded. + public Task UseSkillAt(long skillVNum, short mapX, short mapY) + { + return _client.SendPacketAsync(new UseAoeSkillPacket + { + CastId = skillVNum, MapX = mapX, MapY = mapY + }); + } + + /// + /// Use the given (aoe) skill on the specified place. + /// + /// + /// For skills that can have targets, proceed to . + /// + /// The skill to use. + /// The x coordinate to use the skill at. + /// The y coordinate to use the skill at. + /// A result that may or may not have succeeded. + public Task UseSkillAt(Skill skill, short mapX, short mapY) + { + if (skill.IsOnCooldown) + { + return Task.FromResult(new SkillOnCooldownError(skill)); + } + + return _client.SendPacketAsync(new UseAoeSkillPacket + { + CastId = skill.SkillVNum, MapX = mapX, MapY = mapY + }); + } +} \ No newline at end of file diff --git a/Core/NosSmooth.Game/Extensions/ServiceCollectionExtensions.cs b/Core/NosSmooth.Game/Extensions/ServiceCollectionExtensions.cs index 6c8f02e..ee14349 100644 --- a/Core/NosSmooth.Game/Extensions/ServiceCollectionExtensions.cs +++ b/Core/NosSmooth.Game/Extensions/ServiceCollectionExtensions.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using NosSmooth.Core.Commands; using NosSmooth.Core.Extensions; using NosSmooth.Game.Events.Handlers; +using NosSmooth.Game.Apis; namespace NosSmooth.Game.Extensions; @@ -31,6 +32,10 @@ public static class ServiceCollectionExtensions serviceCollection.TryAddSingleton(); // TODO: add events + + serviceCollection + .AddTransient() + .AddTransient(); return serviceCollection; } -- 2.48.1