diff --git a/FactorioWebInterface/Services/FactorioBanService.cs b/FactorioWebInterface/Services/FactorioBanService.cs index 1636644..e392078 100644 --- a/FactorioWebInterface/Services/FactorioBanService.cs +++ b/FactorioWebInterface/Services/FactorioBanService.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace FactorioWebInterface.Services @@ -26,8 +27,11 @@ public interface IFactorioBanService Task BuildBanList(string serverBanListPath); } - public class FactorioBanService : IFactorioBanService + public partial class FactorioBanService : IFactorioBanService { + [GeneratedRegex("(\n|\r)+")] + private static partial Regex LineEndingRegex(); + private static readonly JsonSerializerSettings banListSerializerSettings = new JsonSerializerSettings() { Formatting = Formatting.Indented, @@ -124,6 +128,8 @@ public async Task DoBanFromGameOutput(FactorioServerData serverData, string cont public async Task AddBan(Ban ban, string serverId, bool synchronizeWithServers, string? actor) { ban.Username = ban.Username.ToLowerInvariant(); + ban.Username = LineEndingRegex().Replace(ban.Username, ""); + ban.Reason = LineEndingRegex().Replace(ban.Reason ?? "", " "); bool added = await AddBanToDatabase(ban); if (added) diff --git a/FactorioWebInterfaceTests/Services/FactorioBanServiceTests/AddBan.cs b/FactorioWebInterfaceTests/Services/FactorioBanServiceTests/AddBan.cs index 6219c45..4057670 100644 --- a/FactorioWebInterfaceTests/Services/FactorioBanServiceTests/AddBan.cs +++ b/FactorioWebInterfaceTests/Services/FactorioBanServiceTests/AddBan.cs @@ -119,6 +119,54 @@ void Callback(LogLevel l, object state) Assert.Equal(expected, message); } + [Theory] + [InlineData("name\n", "reason", "name", "reason")] + [InlineData("name\n\r", "reason", "name", "reason")] + [InlineData("name\r", "reason", "name", "reason")] + [InlineData("name\r\n", "reason", "name", "reason")] + [InlineData("name\n\n", "reason", "name", "reason")] + [InlineData("name", "reason", "name", "reason")] + [InlineData("name", "reason\n", "name", "reason ")] + [InlineData("name", "reason\n\r", "name", "reason ")] + [InlineData("name", "reason\r", "name", "reason ")] + [InlineData("name", "reason\r\n", "name", "reason ")] + [InlineData("name", "reason\n\n", "name", "reason ")] + [InlineData("name", "reason\nline2", "name", "reason line2")] + [InlineData("name", "reason\nline2\nline3", "name", "reason line2 line3")] + public async Task ReplacesLineEndingsInUsernameAndReasonWithSpace(string username, string reason, string expectedName, string expectedReason) + { + // Arrange. + var ban = new Ban() { Username = username, Admin = "admin", Reason = reason }; + const string serverId = "serverId"; + const bool sync = true; + + var eventRaised = new AsyncManualResetEvent(); + FactorioBanEventArgs? eventArgs = null; + void FactorioBanService_BanChanged(IFactorioBanService sender, FactorioBanEventArgs ev) + { + eventArgs = ev; + eventRaised.Set(); + } + + factorioBanService.BanChanged += FactorioBanService_BanChanged; + + // Act. + await factorioBanService.AddBan(ban, serverId, sync, ""); + await eventRaised.WaitAsyncWithTimeout(5000); + + // Assert. + Assert.NotNull(eventArgs); + Assert.Equal(serverId, eventArgs!.Source); + Assert.Equal(sync, eventArgs.SynchronizeWithServers); + + var changeData = eventArgs.ChangeData; + + Assert.Equal(CollectionChangeType.Add, changeData.Type); + Assert.Single(changeData.NewItems); + Assert.Equal(expectedName, changeData.NewItems[0].Username); + Assert.Equal(expectedReason, changeData.NewItems[0].Reason); + } + [Fact] public async Task DoesNotAddDuplicateBan() { diff --git a/FactorioWrapper/MainLoop.cs b/FactorioWrapper/MainLoop.cs index 722b7a0..4af72b0 100644 --- a/FactorioWrapper/MainLoop.cs +++ b/FactorioWrapper/MainLoop.cs @@ -450,7 +450,7 @@ private async void FactorioProcess_OutputDataReceived(object sender, DataReceive string line = match.Groups[1].Value; #if WINDOWS - if (line == "Info UDPSocket.cpp:45: Opening socket for broadcast") + if (line == "Info UDPSocket.cpp:44: Opening socket for broadcast") { await ConnectRCON();