Skip to content

Commit

Permalink
Implement MESSAGE_ACCEPT handler. Allows for more player commands to …
Browse files Browse the repository at this point in the history
…work on BU

Note that the dialog text is currently hacked into multiple lines based on observations from BU using spaces to pad messages into multiple lines
  • Loading branch information
ethanmoffat committed Sep 14, 2022
1 parent 4f9842d commit 482bc66
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 0 deletions.
16 changes: 16 additions & 0 deletions EOLib/Domain/Notifiers/IUserInterfaceNotifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using AutomaticTypeMapper;
using System.Collections.Generic;

namespace EOLib.Domain.Notifiers
{
public interface IUserInterfaceNotifier
{
void NotifyMessageDialog(string title, IReadOnlyList<string> messages);
}

[AutoMappedType]
public class NoOpUserInterfaceNotifier : IUserInterfaceNotifier
{
public void NotifyMessageDialog(string title, IReadOnlyList<string> messages) { }
}
}
42 changes: 42 additions & 0 deletions EOLib/PacketHandlers/Message/MessageAcceptHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using AutomaticTypeMapper;
using EOLib.Domain.Login;
using EOLib.Domain.Notifiers;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;

namespace EOLib.PacketHandlers.Message
{
/// <summary>
/// Shows a message dialog (ScrollingListDialogSize.Large, ScrollingListDialog.ListItemStyle.Small)
/// </summary>
[AutoMappedType]
public class MessageAcceptHandler : InGameOnlyPacketHandler
{
private readonly IEnumerable<IUserInterfaceNotifier> _userInterfaceNotifiers;

public override PacketFamily Family => PacketFamily.Message;

public override PacketAction Action => PacketAction.Accept;

public MessageAcceptHandler(IPlayerInfoProvider playerInfoProvider,
IEnumerable<IUserInterfaceNotifier> userInterfaceNotifiers)
: base(playerInfoProvider)
{
_userInterfaceNotifiers = userInterfaceNotifiers;
}

public override bool HandlePacket(IPacket packet)
{
var title = packet.ReadBreakString();
var messages = new List<string>();
while (packet.ReadPosition < packet.Length)
messages.Add(packet.ReadBreakString());

foreach (var notifier in _userInterfaceNotifiers)
notifier.NotifyMessageDialog(title, messages);

return true;
}
}
}
36 changes: 36 additions & 0 deletions EndlessClient/Dialogs/Actions/InGameDialogActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using EOLib.Domain.Interact.Skill;
using Optional;
using System;
using System.Collections.Generic;
using System.Linq;

namespace EndlessClient.Dialogs.Actions
{
Expand All @@ -26,6 +28,7 @@ public class InGameDialogActions : IInGameDialogActions
private readonly IBankAccountDialogFactory _bankAccountDialogFactory;
private readonly ISkillmasterDialogFactory _skillmasterDialogFactory;
private readonly IBardDialogFactory _bardDialogFactory;
private readonly IScrollingListDialogFactory _scrollingListDialogFactory;
private readonly ISfxPlayer _sfxPlayer;
private readonly IShopDialogFactory _shopDialogFactory;
private readonly IQuestDialogFactory _questDialogFactory;
Expand All @@ -45,6 +48,7 @@ public InGameDialogActions(IFriendIgnoreListDialogFactory friendIgnoreListDialog
IBankAccountDialogFactory bankAccountDialogFactory,
ISkillmasterDialogFactory skillmasterDialogFactory,
IBardDialogFactory bardDialogFactory,
IScrollingListDialogFactory scrollingListDialogFactory,
ISfxPlayer sfxPlayer)
{
_friendIgnoreListDialogFactory = friendIgnoreListDialogFactory;
Expand All @@ -60,6 +64,7 @@ public InGameDialogActions(IFriendIgnoreListDialogFactory friendIgnoreListDialog
_bankAccountDialogFactory = bankAccountDialogFactory;
_skillmasterDialogFactory = skillmasterDialogFactory;
_bardDialogFactory = bardDialogFactory;
_scrollingListDialogFactory = scrollingListDialogFactory;
_sfxPlayer = sfxPlayer;
_shopDialogFactory = shopDialogFactory;
_questDialogFactory = questDialogFactory;
Expand Down Expand Up @@ -247,6 +252,35 @@ public void ShowBardDialog()
});
}

public void ShowMessageDialog(string title, IReadOnlyList<string> messages)
{
_activeDialogRepository.MessageDialog.MatchNone(() =>
{
var dlg = _scrollingListDialogFactory.Create(ScrollingListDialogSize.Large);
dlg.DialogClosed += (_, _) => _activeDialogRepository.MessageDialog = Option.None<ScrollingListDialog>();

dlg.ListItemType = ListDialogItem.ListItemStyle.Small;
dlg.Buttons = ScrollingListDialogButtons.Cancel;
dlg.Title = title;

var _75spaces = new string(Enumerable.Repeat(' ', 75).ToArray());
var items = messages
// BU hack - assume that 75 spaces or more indicates an extra line break
.Select(x => x.Replace(_75spaces, " \n"))
// BU hack - assume that 3 spaces or more indicates extra padding and should split the message into multiple lines
.SelectMany(x => x.Split(" ", StringSplitOptions.RemoveEmptyEntries))
.Select(x => new ListDialogItem(dlg, ListDialogItem.ListItemStyle.Small) { PrimaryText = x == "\n" ? string.Empty : x.Trim() }).ToList();

dlg.SetItemList(items);

_activeDialogRepository.MessageDialog = Option.Some(dlg);

UseDefaultDialogSounds(dlg);

dlg.Show();
});
}

private void UseDefaultDialogSounds(ScrollingListDialog dialog)
{
UseDefaultDialogSounds((BaseEODialog)dialog);
Expand Down Expand Up @@ -298,5 +332,7 @@ public interface IInGameDialogActions
void ShowSkillmasterDialog();

void ShowBardDialog();

void ShowMessageDialog(string title, IReadOnlyList<string> messages);
}
}
8 changes: 8 additions & 0 deletions EndlessClient/Dialogs/ActiveDialogRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public interface IActiveDialogProvider : IDisposable

Option<BardDialog> BardDialog { get; }

Option<ScrollingListDialog> MessageDialog { get; }

IReadOnlyList<Option<IXNADialog>> ActiveDialogs { get; }
}

Expand Down Expand Up @@ -58,6 +60,8 @@ public interface IActiveDialogRepository : IDisposable

Option<BardDialog> BardDialog { get; set; }

Option<ScrollingListDialog> MessageDialog { get; set; }

IReadOnlyList<Option<IXNADialog>> ActiveDialogs { get; }
}

Expand Down Expand Up @@ -86,6 +90,8 @@ public class ActiveDialogRepository : IActiveDialogRepository, IActiveDialogProv

public Option<BardDialog> BardDialog { get; set; }

public Option<ScrollingListDialog> MessageDialog { get; set; }

IReadOnlyList<Option<IXNADialog>> ActiveDialogs
{
get
Expand All @@ -103,6 +109,7 @@ IReadOnlyList<Option<IXNADialog>> ActiveDialogs
BankAccountDialog.Map(d => (IXNADialog)d),
SkillmasterDialog.Map(d => (IXNADialog)d),
BardDialog.Map(d => (IXNADialog)d),
MessageDialog.Map(d => (IXNADialog)d),
}.ToList();
}
}
Expand All @@ -127,6 +134,7 @@ public void Dispose()
BankAccountDialog = Option.None<BankAccountDialog>();
SkillmasterDialog = Option.None<SkillmasterDialog>();
BardDialog = Option.None<BardDialog>();
MessageDialog = Option.None<ScrollingListDialog>();
}
}
}
30 changes: 30 additions & 0 deletions EndlessClient/Dialogs/Factories/ScrollingListDialogFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using AutomaticTypeMapper;
using EndlessClient.Dialogs.Services;
using EOLib.Graphics;

namespace EndlessClient.Dialogs.Factories
{
[AutoMappedType]
public class ScrollingListDialogFactory : IScrollingListDialogFactory
{
private readonly INativeGraphicsManager _nativeGraphicsManager;
private readonly IEODialogButtonService _dialogButtonService;

public ScrollingListDialogFactory(INativeGraphicsManager nativeGraphicsManager,
IEODialogButtonService dialogButtonService)
{
_nativeGraphicsManager = nativeGraphicsManager;
_dialogButtonService = dialogButtonService;
}

public ScrollingListDialog Create(ScrollingListDialogSize size)
{
return new ScrollingListDialog(_nativeGraphicsManager, _dialogButtonService, size);
}
}

public interface IScrollingListDialogFactory
{
ScrollingListDialog Create(ScrollingListDialogSize size);
}
}
23 changes: 23 additions & 0 deletions EndlessClient/HUD/ServerMessageActions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using AutomaticTypeMapper;
using EndlessClient.Dialogs.Actions;
using EOLib.Domain.Notifiers;
using System.Collections.Generic;

namespace EndlessClient.HUD
{
[AutoMappedType]
public class ServerMessageActions : IUserInterfaceNotifier
{
private readonly IInGameDialogActions _inGameDialogActions;

public ServerMessageActions(IInGameDialogActions inGameDialogActions)
{
_inGameDialogActions = inGameDialogActions;
}

public void NotifyMessageDialog(string title, IReadOnlyList<string> messages)
{
_inGameDialogActions.ShowMessageDialog(title, messages);
}
}
}

0 comments on commit 482bc66

Please sign in to comment.