Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #310 from ethanmoffat/boards
Implement town board handling (Board packet family + dialog)
- Loading branch information
Showing
28 changed files
with
910 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using EOLib.IO.Map; | ||
|
||
namespace EOLib.IO.Extensions | ||
{ | ||
public static class TileSpecExtensions | ||
{ | ||
public static bool IsBoard(this TileSpec tileSpec) | ||
{ | ||
return tileSpec == TileSpec.Board1 || | ||
tileSpec == TileSpec.Board2 || | ||
tileSpec == TileSpec.Board3 || | ||
tileSpec == TileSpec.Board4 || | ||
tileSpec == TileSpec.Board5 || | ||
tileSpec == TileSpec.Board6 || | ||
tileSpec == TileSpec.Board7 || | ||
tileSpec == TileSpec.Board8; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
using AutomaticTypeMapper; | ||
using EOLib.Net; | ||
using EOLib.Net.Communication; | ||
|
||
namespace EOLib.Domain.Interact.Board | ||
{ | ||
[AutoMappedType] | ||
public class BoardActions : IBoardActions | ||
{ | ||
private readonly IPacketSendService _packetSendService; | ||
private readonly IBoardProvider _boardProvider; | ||
|
||
public BoardActions(IPacketSendService packetSendService, | ||
IBoardProvider boardProvider) | ||
{ | ||
_packetSendService = packetSendService; | ||
_boardProvider = boardProvider; | ||
} | ||
|
||
public void AddPost(string subject, string body) | ||
{ | ||
_boardProvider.BoardId.MatchSome(boardId => | ||
{ | ||
var packet = new PacketBuilder(PacketFamily.Board, PacketAction.Create) | ||
.AddShort(boardId) | ||
.AddByte(255) | ||
.AddBreakString(subject.Replace('y', (char)255)) // this is in EOSERV for some reason. Probably due to chunking (see Sanitization here: https://github.com/Cirras/eo-protocol/blob/master/docs/chunks.md) | ||
.AddBreakString(body.Replace('\n', '\r')) // original EO client uses \r as newline separator. XNAControls uses \n. | ||
.Build(); | ||
_packetSendService.SendPacket(packet); | ||
}); | ||
} | ||
|
||
public void DeletePost(int postId) | ||
{ | ||
_boardProvider.BoardId.MatchSome(boardId => | ||
{ | ||
var packet = new PacketBuilder(PacketFamily.Board, PacketAction.Remove) | ||
.AddShort(boardId) | ||
.AddShort(postId) | ||
.Build(); | ||
_packetSendService.SendPacket(packet); | ||
}); | ||
} | ||
|
||
public void ViewPost(int postId) | ||
{ | ||
_boardProvider.BoardId.MatchSome(boardId => | ||
{ | ||
var packet = new PacketBuilder(PacketFamily.Board, PacketAction.Take) | ||
.AddShort(boardId) | ||
.AddShort(postId) | ||
.Build(); | ||
_packetSendService.SendPacket(packet); | ||
}); | ||
} | ||
} | ||
|
||
public interface IBoardActions | ||
{ | ||
void AddPost(string subject, string body); | ||
|
||
void ViewPost(int postId); | ||
|
||
void DeletePost(int postId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using AutomaticTypeMapper; | ||
using Optional; | ||
using System.Collections.Generic; | ||
|
||
namespace EOLib.Domain.Interact.Board | ||
{ | ||
public interface IBoardRepository | ||
{ | ||
Option<int> BoardId { get; set; } | ||
|
||
HashSet<BoardPostInfo> Posts { get; set; } | ||
|
||
Option<BoardPostInfo> ActivePost { get; set; } | ||
|
||
Option<string> ActivePostMessage { get; set; } | ||
} | ||
|
||
public interface IBoardProvider | ||
{ | ||
Option<int> BoardId { get; } | ||
|
||
IReadOnlyCollection<BoardPostInfo> Posts { get; } | ||
|
||
Option<BoardPostInfo> ActivePost { get; } | ||
|
||
Option<string> ActivePostMessage { get; } | ||
} | ||
|
||
[AutoMappedType(IsSingleton = true)] | ||
public class BoardDataRepository : IBoardRepository, IBoardProvider, IResettable | ||
{ | ||
public Option<int> BoardId { get; set; } | ||
|
||
public HashSet<BoardPostInfo> Posts { get; set; } | ||
|
||
IReadOnlyCollection<BoardPostInfo> IBoardProvider.Posts => Posts; | ||
|
||
public Option<BoardPostInfo> ActivePost { get; set; } | ||
|
||
public Option<string> ActivePostMessage { get; set; } | ||
|
||
public BoardDataRepository() | ||
{ | ||
ResetState(); | ||
} | ||
|
||
public void ResetState() | ||
{ | ||
BoardId = Option.None<int>(); | ||
Posts = new HashSet<BoardPostInfo>(); | ||
ActivePost = Option.None<BoardPostInfo>(); | ||
ActivePostMessage = Option.None<string>(); | ||
} | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
EOLib/Domain/Board/BoardMapEntity.cs → ...b/Domain/Interact/Board/BoardMapEntity.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using Amadevus.RecordGenerator; | ||
|
||
namespace EOLib.Domain.Interact.Board | ||
{ | ||
[Record(Features.Default | Features.ObjectEquals | Features.EquatableEquals)] | ||
public sealed partial class BoardPostInfo | ||
{ | ||
public int PostId { get; } | ||
|
||
public string Author { get; } | ||
|
||
public string Subject { get; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using AutomaticTypeMapper; | ||
using EOLib.Domain.Interact.Board; | ||
using EOLib.Domain.Login; | ||
using EOLib.Domain.Notifiers; | ||
using EOLib.Net; | ||
using EOLib.Net.Handlers; | ||
using Optional; | ||
using System.Collections.Generic; | ||
|
||
namespace EOLib.PacketHandlers.Board | ||
{ | ||
/// <summary> | ||
/// Sent by the server when a board should be opened | ||
/// </summary> | ||
[AutoMappedType] | ||
public class BoardOpenHandler : InGameOnlyPacketHandler | ||
{ | ||
private readonly IBoardRepository _boardRepository; | ||
private readonly IEnumerable<IUserInterfaceNotifier> _userInterfaceNotifiers; | ||
|
||
public override PacketFamily Family => PacketFamily.Board; | ||
|
||
public override PacketAction Action => PacketAction.Open; | ||
|
||
public BoardOpenHandler(IPlayerInfoProvider playerInfoProvider, | ||
IBoardRepository boardRepository, | ||
IEnumerable<IUserInterfaceNotifier> userInterfaceNotifiers) | ||
: base(playerInfoProvider) | ||
{ | ||
_boardRepository = boardRepository; | ||
_userInterfaceNotifiers = userInterfaceNotifiers; | ||
} | ||
|
||
public override bool HandlePacket(IPacket packet) | ||
{ | ||
_boardRepository.BoardId = Option.Some(packet.ReadChar()); | ||
|
||
var numPosts = packet.ReadChar(); | ||
_boardRepository.Posts = new HashSet<BoardPostInfo>(); | ||
|
||
var chunks = new List<IPacket>(); | ||
while (packet.ReadPosition < packet.Length) | ||
{ | ||
var chunkData = new List<byte> { (byte)PacketFamily.Board, (byte)PacketAction.Open }; | ||
while (packet.ReadPosition < packet.Length && packet.PeekByte() != 255) | ||
chunkData.Add(packet.ReadByte()); | ||
|
||
if (packet.ReadPosition < packet.Length) | ||
packet.ReadByte(); | ||
|
||
chunks.Add(new Packet(chunkData)); | ||
} | ||
|
||
if (chunks.Count % 3 != 0 || chunks.Count / 3 != numPosts) | ||
throw new MalformedPacketException("Unexpected number of elements in BOARD_OPEN packet", packet); | ||
|
||
for (int i = 0; i < chunks.Count; i += 3) | ||
{ | ||
var postId = chunks[i].ReadShort(); | ||
var author = chunks[i + 1].ReadEndString(); | ||
var subject = chunks[i + 2].ReadEndString(); | ||
_boardRepository.Posts.Add(new BoardPostInfo(postId, author, subject)); | ||
} | ||
|
||
_boardRepository.ActivePost = Option.None<BoardPostInfo>(); | ||
_boardRepository.ActivePostMessage = Option.None<string>(); | ||
|
||
foreach (var notifier in _userInterfaceNotifiers) | ||
notifier.NotifyPacketDialog(PacketFamily.Board); | ||
|
||
return true; | ||
} | ||
} | ||
} |
Oops, something went wrong.