Skip to content

Commit

Permalink
Chat fixes (#358)
Browse files Browse the repository at this point in the history
* Always use other character renderer for public/group chat
* Play sound effect when admin chat sent
* Make group chat handler use party members instead of map data
* Add PM Close clickable areas after tabs and fixed positions
* Add SFX for PM target not found
* Dispatch right-click handler to chat tab
      Solution: adjust coordinates (and child control offsets) so chat tabs are *only* the click area (and not the full panel size). 
      Fixes bug where right-clicking would always try to dispatch to the sys tab, which wouldn't have name data for the PM target.
* Reset PM targets in login
      Fixes bug where relogging and attempting to PM a character you'd previously PM'd would not show the chat tab for the PM session.

---------

Co-authored-by: Dan Oak <coderdan@protonmail.com>
Co-authored-by: Ethan Moffat <ethan@moffat.io>
  • Loading branch information
3 people authored Aug 30, 2024
1 parent 5866310 commit d37ba3e
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 52 deletions.
40 changes: 22 additions & 18 deletions EOLib/PacketHandlers/Chat/GroupChatHandler.cs
Original file line number Diff line number Diff line change
@@ -1,55 +1,59 @@
using System.Collections.Generic;
using AutomaticTypeMapper;
using EOLib.Domain.Character;
using EOLib.Domain.Chat;
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.Domain.Notifiers;
using EOLib.Domain.Party;
using EOLib.Net.Handlers;
using Moffat.EndlessOnline.SDK.Protocol.Net;
using Moffat.EndlessOnline.SDK.Protocol.Net.Server;
using Optional.Collections;

namespace EOLib.PacketHandlers.Chat
{
[AutoMappedType]
public class GroupChatHandler : PlayerChatByIDHandler<TalkOpenServerPacket>
public class GroupChatHandler : InGameOnlyPacketHandler<TalkOpenServerPacket>
{
private readonly IChatRepository _chatRepository;
private readonly IPartyDataProvider _partyDataProvider;
private readonly IEnumerable<IOtherCharacterEventNotifier> _otherCharacterEventNotifiers;
private readonly IEnumerable<IChatEventNotifier> _chatEventNotifiers;

public override PacketFamily Family => PacketFamily.Talk;
public override PacketAction Action => PacketAction.Open;

public GroupChatHandler(IPlayerInfoProvider playerInfoProvider,
ICurrentMapStateRepository currentMapStateRepository,
ICharacterProvider characterProvider,
IChatRepository chatRepository,
IPartyDataProvider partyDataProvider,
IEnumerable<IOtherCharacterEventNotifier> otherCharacterEventNotifiers,
IEnumerable<IChatEventNotifier> chatEventNotifiers)
: base(playerInfoProvider, currentMapStateRepository, characterProvider)
: base(playerInfoProvider)
{
_chatRepository = chatRepository;
_partyDataProvider = partyDataProvider;
_otherCharacterEventNotifiers = otherCharacterEventNotifiers;
_chatEventNotifiers = chatEventNotifiers;
}

public override bool HandlePacket(TalkOpenServerPacket packet)
{
return Handle(packet, packet.PlayerId);
}
_partyDataProvider.Members.SingleOrNone(member => member.CharacterID == packet.PlayerId)
.MatchSome(member =>
{
var localChatData = new ChatData(ChatTab.Local, member.Name, packet.Message, ChatIcon.PlayerPartyDark, ChatColor.PM);
_chatRepository.AllChat[ChatTab.Local].Add(localChatData);

protected override void DoTalk(TalkOpenServerPacket packet, Character character)
{
var localChatData = new ChatData(ChatTab.Local, character.Name, packet.Message, ChatIcon.PlayerPartyDark, ChatColor.PM);
_chatRepository.AllChat[ChatTab.Local].Add(localChatData);
var chatData = new ChatData(ChatTab.Group, member.Name, packet.Message, ChatIcon.PlayerPartyDark);
_chatRepository.AllChat[ChatTab.Group].Add(chatData);

var chatData = new ChatData(ChatTab.Group, character.Name, packet.Message, ChatIcon.PlayerPartyDark);
_chatRepository.AllChat[ChatTab.Group].Add(chatData);
foreach (var notifier in _otherCharacterEventNotifiers)
notifier.OtherCharacterSaySomethingToGroup(member.CharacterID, packet.Message);

foreach (var notifier in _otherCharacterEventNotifiers)
notifier.OtherCharacterSaySomethingToGroup(character.ID, packet.Message);
foreach (var notifier in _chatEventNotifiers)
notifier.NotifyChatReceived(ChatEventType.Group);
});

foreach (var notifier in _chatEventNotifiers)
notifier.NotifyChatReceived(ChatEventType.Group);
return true;
}
}
}
3 changes: 2 additions & 1 deletion EndlessClient/Audio/SoundEffectID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public enum SoundEffectID
PrivateMessageReceived,
PunchAttack,
UnknownWarpSound,
UnknownPingSound = 12,
PrivateMessageTargetNotFound = 12,
HudStatusBarClick,
AdminAnnounceReceived,
MeleeWeaponAttack,
Expand All @@ -43,6 +43,7 @@ public enum SoundEffectID
Craft,
UnknownBuzzSound = 28,
AdminChatReceived,
AdminChatSent = AdminChatReceived,
AlternateMeleeAttack,
PotionOfFlamesEffect,
AdminWarp = 32,
Expand Down
6 changes: 6 additions & 0 deletions EndlessClient/Controllers/ChatController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ public void SendChatAndClearTextBox()
}

var chatType = _chatTypeCalculator.CalculateChatType(localTypedText);

if (chatType == ChatType.Admin)
{
_sfxPlayer.PlaySfx(SoundEffectID.AdminChatSent);
}

var (result, updatedChat) = _chatActions.SendChatToServer(localTypedText, targetCharacter, chatType);
switch (result)
{
Expand Down
3 changes: 3 additions & 0 deletions EndlessClient/Controllers/LoginController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ private void ClearChat()
{
chat.Clear();
}

_chatRepository.PMTarget1 = string.Empty;
_chatRepository.PMTarget2 = string.Empty;
}

private void AddDefaultTextToChat()
Expand Down
2 changes: 2 additions & 0 deletions EndlessClient/HUD/Chat/ChatNotificationActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public void NotifyPrivateMessageRecipientNotFound(string recipientName)
var chatPanel = _hudControlProvider.GetComponent<ChatPanel>(HudControlIdentifier.ChatPanel);
chatPanel.ClosePMTab(tab);
});

_sfxPlayer.PlaySfx(SoundEffectID.PrivateMessageTargetNotFound);
}

public void NotifyPlayerMutedByAdmin(string adminName)
Expand Down
53 changes: 24 additions & 29 deletions EndlessClient/HUD/Chat/ChatPanelTab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using EOLib;
using EOLib.Domain.Chat;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using MonoGame.Extended.BitmapFonts;
using MonoGame.Extended.Input;
using MonoGame.Extended.Input.InputListeners;
Expand Down Expand Up @@ -83,29 +82,29 @@ public ChatPanelTab(IChatProvider chatProvider,
_tabSheetUnselected = tabSheetUnselected;
_chatFont = chatFont;

DrawArea = new Rectangle(0, 0, _parentPanel.DrawArea.Width, _parentPanel.DrawArea.Height);
DrawArea = GetTabClickableArea();

_tab = new ClickableArea(new Rectangle(0, 0, DrawArea.Width, DrawArea.Height));
_tab.OnClick += (_, _) => SelectThisTab();
_tab.SetParentControl(this);

if (Tab == ChatTab.Private1)
{
_closeButton = new ClickableArea(new Rectangle(23, 102, 11, 11));
_closeButton = new ClickableArea(new Rectangle(3, 3, 11, 11));
_closeButton.OnClick += (_, _) => CloseTab();
_closeButton.SetParentControl(this);
}
else if (Tab == ChatTab.Private2)
{
_closeButton = new ClickableArea(new Rectangle(156, 102, 11, 11));
_closeButton = new ClickableArea(new Rectangle(3, 3, 11, 11));
_closeButton.OnClick += (_, _) => CloseTab();
_closeButton.SetParentControl(this);
}

_tab = new ClickableArea(GetTabClickableArea());
_tab.OnClick += (_, _) => SelectThisTab();
_tab.SetParentControl(this);

_label = new XNALabel(Constants.FontSize08)
{
Text = GetTabTextLabel(),
DrawPosition = GetTabClickableArea().Location.ToVector2() + new Vector2(16, 2)
DrawPosition = new Vector2(16, 2)
};
_label.SetParentControl(this);

Expand All @@ -122,6 +121,21 @@ public override void Initialize()
base.Initialize();
}

public void HandleRightClick(MouseEventArgs eventArgs)
{
var clickedYRelativeToTopOfPanel = eventArgs.Position.Y - _parentPanel.DrawAreaWithParentOffset.Y;
var clickedChatRow = (int)Math.Round(clickedYRelativeToTopOfPanel / 13.0) - 1;

if (clickedChatRow >= 0 && _scrollBar.ScrollOffset + clickedChatRow < _cachedChat.Count)
{
var who = _chatProvider.AllChat[Tab][_scrollBar.ScrollOffset + clickedChatRow].Who;
if (!string.IsNullOrEmpty(who))
{
_hudControlProvider.GetComponent<ChatTextBox>(HudControlIdentifier.ChatTextBox).Text = $"!{who} ";
}
}
}

public void CloseTab()
{
if (Tab != ChatTab.Private1 && Tab != ChatTab.Private2)
Expand Down Expand Up @@ -170,7 +184,7 @@ protected override void OnDrawControl(GameTime gameTime)
_spriteBatch.Begin();

var sheet = Active ? _tabSheetSelected : _tabSheetUnselected;
_spriteBatch.Draw(sheet.SheetTexture, _tab.ClickArea.Location.ToVector2() + ImmediateParent.DrawPositionWithParentOffset, sheet.SourceRectangle, Color.White);
_spriteBatch.Draw(sheet.SheetTexture, DrawAreaWithParentOffset, sheet.SourceRectangle, Color.White);

if (Active)
{
Expand All @@ -190,25 +204,6 @@ protected override void OnDrawControl(GameTime gameTime)
base.OnDrawControl(gameTime);
}

protected override bool HandleClick(IXNAControl control, MouseEventArgs eventArgs)
{
if (eventArgs.Button == MouseButton.Right)
{
var clickedYRelativeToTopOfPanel = eventArgs.Position.Y - DrawAreaWithParentOffset.Y;
var clickedChatRow = (int)Math.Round(clickedYRelativeToTopOfPanel / 13.0) - 1;

if (clickedChatRow >= 0 && _scrollBar.ScrollOffset + clickedChatRow < _cachedChat.Count)
{
var who = _chatProvider.AllChat[Tab][_scrollBar.ScrollOffset + clickedChatRow].Who;
_hudControlProvider.GetComponent<ChatTextBox>(HudControlIdentifier.ChatTextBox).Text = $"!{who} ";
}

return true;
}

return false;
}

private void SelectThisTab()
{
if (!_closeButtonClicked)
Expand Down
12 changes: 12 additions & 0 deletions EndlessClient/HUD/Panels/ChatPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using EOLib.Graphics;
using Microsoft.Xna.Framework;
using MonoGame.Extended.BitmapFonts;
using MonoGame.Extended.Input;
using MonoGame.Extended.Input.InputListeners;
using XNAControls;

namespace EndlessClient.HUD.Panels
Expand Down Expand Up @@ -132,5 +134,15 @@ public void ClosePMTab(ChatTab whichTab)
{
_tabs[whichTab].CloseTab();
}

protected override bool HandleClick(IXNAControl control, MouseEventArgs eventArgs)
{
if (eventArgs.Button == MouseButton.Right)
{
_tabs[CurrentTab].HandleRightClick(eventArgs);
}

return base.HandleClick(control, eventArgs);
}
}
}
5 changes: 1 addition & 4 deletions EndlessClient/Subscribers/OtherCharacterEventSubscriber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,8 @@ public void AdminAnnounce(string message)

private void SaySomethingShared(int characterID, string message, bool isGroupChat)
{
if (_characterRendererProvider.CharacterRenderers.TryGetValue(characterID, out var characterRenderer) ||
_characterRendererProvider.MainCharacterRenderer.HasValue)
if (_characterRendererProvider.CharacterRenderers.TryGetValue(characterID, out var characterRenderer))
{
_characterRendererProvider.MainCharacterRenderer.MatchSome(x => characterRenderer = x);

var name = characterRenderer.Character.Name;

var ignoreList = _friendIgnoreListService.LoadList(Constants.IgnoreListFile);
Expand Down

0 comments on commit d37ba3e

Please sign in to comment.