server-master/srcs/_plugins/WingsEmu.Plugins.BasicImplementation/Guri/InteractionGuriHandler.cs
2026-02-10 18:21:30 +01:00

306 lines
No EOL
11 KiB
C#

using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using WingsAPI.Game.Extensions.Groups;
using WingsAPI.Game.Extensions.ItemExtension.Inventory;
using WingsEmu.Game._enum;
using WingsEmu.Game._Guri;
using WingsEmu.Game._Guri.Event;
using WingsEmu.Game._i18n;
using WingsEmu.Game._ItemUsage.Configuration;
using WingsEmu.Game.Chat;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Extensions.Mates;
using WingsEmu.Game.Helpers.Damages;
using WingsEmu.Game.Inventory;
using WingsEmu.Game.Managers;
using WingsEmu.Game.Managers.StaticData;
using WingsEmu.Game.Mates;
using WingsEmu.Game.Networking;
using WingsEmu.Packets.ClientPackets;
using WingsEmu.Packets.Enums;
using WingsEmu.Packets.Enums.Chat;
using ChatType = WingsEmu.Game._playerActionLogs.ChatType;
namespace WingsEmu.Plugins.BasicImplementations.Guri;
public class InteractionGuriHandler : IGuriHandler
{
private readonly IForbiddenNamesManager _forbiddenNamesManager;
private readonly IItemsManager _itemsManager;
private readonly IGameLanguageService _languageService;
private readonly ISpPartnerConfiguration _spPartner;
public InteractionGuriHandler(IGameLanguageService languageService, IItemsManager itemsManager, ISpPartnerConfiguration spPartner, IForbiddenNamesManager forbiddenNamesManager)
{
_languageService = languageService;
_itemsManager = itemsManager;
_spPartner = spPartner;
_forbiddenNamesManager = forbiddenNamesManager;
}
public long GuriEffectId => 4;
public async Task ExecuteAsync(IClientSession session, GuriEvent guriPacket)
{
if (!long.TryParse(guriPacket.Packet[3], out long guriType))
{
return;
}
if (!long.TryParse(guriPacket.Packet[5], out long itemSpeaker))
{
return;
}
if (itemSpeaker == 999)
{
guriType = 999;
}
string message;
string[] valueSplit;
switch (guriType)
{
case 1:
if (session.CantPerformActionOnAct4())
{
return;
}
if (session.PlayerEntity.RainbowBattleComponent.IsInRainbowBattle)
{
return;
}
if (string.IsNullOrWhiteSpace(guriPacket.Value))
{
return;
}
if (!guriPacket.User.HasValue)
{
return;
}
IMateEntity mateEntity = session.PlayerEntity.MateComponent.GetMate(s => s.Id == guriPacket.User && s.MateType == MateType.Pet);
if (guriPacket.Value.Length > 15)
{
session.SendInfo(_languageService.GetLanguage(GameDialogKey.ITEM_INFO_PET_NAME_TOO_LONG, session.UserLanguage));
return;
}
if (mateEntity == null)
{
return;
}
var rg = new Regex(@"^[a-zA-Z0-9_\-\*]*$");
if (rg.Matches(guriPacket.Value).Count != 1)
{
return;
}
string expectedName = guriPacket.Value;
mateEntity.MateName = expectedName;
if (mateEntity.Position == default)
{
mateEntity.ChangePosition(session.PlayerEntity.Position);
}
mateEntity.MapInstance.Broadcast(s => mateEntity.GenerateIn(_languageService, s.UserLanguage, _spPartner));
session.RefreshParty(_spPartner);
session.SendScnPackets();
session.SendScpPackets();
await session.RemoveItemFromInventory((short)ItemVnums.NAME_TAG);
break;
// Presentation message
case 2:
if (guriPacket.Value == null)
{
return;
}
bool isLimitedItem = session.PlayerEntity.HasItem((short)ItemVnums.SELF_INTRODUCTION_LIMITED);
if (!session.PlayerEntity.HasItem((short)ItemVnums.SELF_INTRODUCTION) && !isLimitedItem)
{
return;
}
short itemVnumToRemove = isLimitedItem ? (short)ItemVnums.SELF_INTRODUCTION_LIMITED : (short)ItemVnums.SELF_INTRODUCTION;
message = string.Empty;
valueSplit = guriPacket.Value.Split(' ');
message = valueSplit.Aggregate(message, (current, t) => current + t + "^");
message = message[..^1]; // Remove the last ^
message = message.Trim();
if (message.Length > 60)
{
message = message.Substring(0, 60);
}
session.PlayerEntity.Biography = message;
session.SendChatMessage(_languageService.GetLanguage(GameDialogKey.INTERACTION_CHATMESSAGE_INTRODUCTION_SET, session.UserLanguage), ChatMessageColorType.Yellow);
await session.RemoveItemFromInventory(itemVnumToRemove);
break;
case 3:
bool haveLimitedSpeaker = session.PlayerEntity.HasItem((short)ItemVnums.SPEAKER_LIMITED);
bool haveSpeaker = session.PlayerEntity.HasItem((short)ItemVnums.SPEAKER);
if (!haveLimitedSpeaker && !haveSpeaker)
{
return;
}
if (session.PlayerEntity.RainbowBattleComponent.IsInRainbowBattle)
{
session.SendChatMessage(session.GetLanguage(GameDialogKey.ITEM_MESSAGE_CANT_USE), ChatMessageColorType.Yellow);
return;
}
if (guriPacket.Value == null)
{
return;
}
valueSplit = guriPacket.Value.Split(' ');
message = valueSplit.Aggregate("", (current, t) => current + t + " ");
if (session.IsMuted())
{
session.SendMuteMessage();
return;
}
await session.EmitEventAsync(new ChatSpeakerEvent(SpeakerType.Normal_Speaker, message));
if (haveLimitedSpeaker)
{
await session.RemoveItemFromInventory((short)ItemVnums.SPEAKER_LIMITED);
}
else
{
await session.RemoveItemFromInventory((short)ItemVnums.SPEAKER);
}
break;
case 4:
if (session.CantPerformActionOnAct4())
{
return;
}
bool haveLimitedBubble = session.PlayerEntity.HasItem((short)ItemVnums.BUBBLE_LIMITED);
bool haveBubble = session.PlayerEntity.HasItem((short)ItemVnums.BUBBLE);
if (!haveLimitedBubble && !haveBubble)
{
return;
}
if (session.PlayerEntity.RainbowBattleComponent.IsInRainbowBattle)
{
session.SendChatMessage(session.GetLanguage(GameDialogKey.ITEM_MESSAGE_CANT_USE), ChatMessageColorType.Yellow);
return;
}
if (session.IsMuted())
{
session.SendMuteMessage();
return;
}
session.PlayerEntity.Bubble = DateTime.UtcNow;
string bubbleMessage = guriPacket.Value;
if (bubbleMessage.Length > 60)
{
bubbleMessage = bubbleMessage.Substring(0, 60);
}
session.PlayerEntity.SaveBubble(bubbleMessage);
session.SendPacket(new CsprPacket { Message = bubbleMessage });
if (haveLimitedBubble)
{
await session.RemoveItemFromInventory((short)ItemVnums.BUBBLE_LIMITED);
}
else
{
await session.RemoveItemFromInventory((short)ItemVnums.BUBBLE);
}
await session.EmitEventAsync(new ChatGenericEvent
{
Message = bubbleMessage,
ChatType = ChatType.SpeechBubble
});
break;
case 999:
haveLimitedSpeaker = session.PlayerEntity.HasItem((short)ItemVnums.SPEAKER_LIMITED);
haveSpeaker = session.PlayerEntity.HasItem((short)ItemVnums.SPEAKER);
if (!haveLimitedSpeaker && !haveSpeaker)
{
return;
}
if (!Enum.TryParse(guriPacket.Packet[6], out InventoryType type))
{
return;
}
if (!short.TryParse(guriPacket.Packet[7], out short slot))
{
return;
}
if (session.PlayerEntity.RainbowBattleComponent.IsInRainbowBattle)
{
session.SendChatMessage(session.GetLanguage(GameDialogKey.ITEM_MESSAGE_CANT_USE), ChatMessageColorType.Yellow);
return;
}
if (session.IsMuted())
{
session.SendMuteMessage();
return;
}
InventoryItem item = session.PlayerEntity.GetItemBySlotAndType(slot, type);
if (item == null)
{
return;
}
string messageItem = $"{guriPacket.Value.Remove(0, 4).Replace(" ", "|")}";
// check, if itemName is the same as in {}
string itemName = _languageService.GetLanguage(GameDataType.Item, _itemsManager.GetItem(item.ItemInstance.ItemVNum).Name, session.UserLanguage).Replace(" ", "|");
int firstItem = messageItem.IndexOf("{", StringComparison.Ordinal) + "{".Length;
int lastItem = messageItem.LastIndexOf("}", StringComparison.Ordinal);
string result = messageItem.Substring(firstItem, lastItem - firstItem);
messageItem = messageItem.Replace(result, "%s");
messageItem = messageItem.Trim();
await session.EmitEventAsync(new ChatSpeakerEvent(SpeakerType.Items_Speaker, messageItem, item.ItemInstance));
if (haveLimitedSpeaker)
{
await session.RemoveItemFromInventory((short)ItemVnums.SPEAKER_LIMITED);
}
else
{
await session.RemoveItemFromInventory((short)ItemVnums.SPEAKER);
}
break;
}
}
}