306 lines
No EOL
11 KiB
C#
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;
|
|
}
|
|
}
|
|
} |