Accent System (#1892)

* First Accent Prototype

* -RegisterSystem
-Fixed addaccent cmd
-Spanish accent

* -list is now ?
-Checks if the accent is already added
-Made components public

* owo whats this

* special word filter

* Eeeeeeeeee

* Better?

* -Use a delegate func
-Made some funcs not static
-Moved SentenceRegex

* InjectDependencies

* Name change?

Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
This commit is contained in:
Exp
2020-08-25 17:09:39 +02:00
committed by GitHub
parent 34b2902641
commit c665e66318
10 changed files with 286 additions and 5 deletions

View File

@@ -1,11 +1,9 @@
using System.Linq; using Content.Server.GameObjects.Components.Observer;
using Content.Server.GameObjects.Components.Observer;
using Content.Server.GameObjects.EntitySystems; using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces; using Content.Server.Interfaces;
using Content.Server.Interfaces.Chat; using Content.Server.Interfaces.Chat;
using Content.Shared.Chat; using Content.Shared.Chat;
using Content.Shared.GameObjects.EntitySystems; using Content.Shared.GameObjects.EntitySystems;
using NFluidsynth;
using Robust.Server.Console; using Robust.Server.Console;
using Robust.Server.Interfaces.GameObjects; using Robust.Server.Interfaces.GameObjects;
using Robust.Server.Interfaces.Player; using Robust.Server.Interfaces.Player;
@@ -13,6 +11,10 @@ using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Network; using Robust.Shared.Interfaces.Network;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Localization; using Robust.Shared.Localization;
using System;
using System.Collections.Generic;
using System.Linq;
using static Content.Server.Interfaces.Chat.IChatManager;
namespace Content.Server.Chat namespace Content.Server.Chat
{ {
@@ -33,6 +35,9 @@ namespace Content.Server.Chat
/// </summary> /// </summary>
private const string MaxLengthExceededMessage = "Your message exceeded {0} character limit"; private const string MaxLengthExceededMessage = "Your message exceeded {0} character limit";
//TODO: make prio based?
private List<TransformChat> _chatTransformHandlers;
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
[Dependency] private readonly IServerNetManager _netManager = default!; [Dependency] private readonly IServerNetManager _netManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!;
@@ -49,6 +54,8 @@ namespace Content.Server.Chat
var msg = _netManager.CreateNetMessage<ChatMaxMsgLengthMessage>(); var msg = _netManager.CreateNetMessage<ChatMaxMsgLengthMessage>();
msg.MaxMessageLength = MaxMessageLength; msg.MaxMessageLength = MaxMessageLength;
_netManager.ServerSendToAll(msg); _netManager.ServerSendToAll(msg);
_chatTransformHandlers = new List<TransformChat>();
} }
public void DispatchServerAnnouncement(string message) public void DispatchServerAnnouncement(string message)
@@ -96,6 +103,12 @@ namespace Content.Server.Chat
return; return;
} }
foreach (var handler in _chatTransformHandlers)
{
//TODO: rather return a bool and use a out var?
message = handler(source, message);
}
var pos = source.Transform.GridPosition; var pos = source.Transform.GridPosition;
var clients = _playerManager.GetPlayersInRange(pos, VoiceRange).Select(p => p.ConnectedClient); var clients = _playerManager.GetPlayersInRange(pos, VoiceRange).Select(p => p.ConnectedClient);
@@ -215,5 +228,10 @@ namespace Content.Server.Chat
response.MaxMessageLength = MaxMessageLength; response.MaxMessageLength = MaxMessageLength;
_netManager.ServerSendMessage(response, msg.MsgChannel); _netManager.ServerSendMessage(response, msg.MsgChannel);
} }
public void RegisterChatTransform(TransformChat handler)
{
_chatTransformHandlers.Add(handler);
}
} }
} }

View File

@@ -15,6 +15,7 @@ using Robust.Shared.Interfaces.Log;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Log; using Robust.Shared.Log;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Content.Server.GameObjects.Components.Mobs.Speech;
namespace Content.Server namespace Content.Server
{ {
@@ -64,6 +65,7 @@ namespace Content.Server
IoCManager.Resolve<IServerPreferencesManager>().StartInit(); IoCManager.Resolve<IServerPreferencesManager>().StartInit();
IoCManager.Resolve<INodeGroupFactory>().Initialize(); IoCManager.Resolve<INodeGroupFactory>().Initialize();
IoCManager.Resolve<ISandboxManager>().Initialize(); IoCManager.Resolve<ISandboxManager>().Initialize();
IoCManager.Resolve<IAccentManager>().Initialize();
} }
public override void PostInit() public override void PostInit()

View File

@@ -0,0 +1,41 @@
using Content.Server.Interfaces.Chat;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Content.Server.GameObjects.Components.Mobs.Speech
{
public interface IAccentManager
{
public void Initialize();
}
public class AccentManager : IAccentManager
{
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IComponentManager _componentManager = default!;
public static readonly Regex SentenceRegex = new Regex(@"(?<=[\.!\?])");
public void Initialize()
{
IoCManager.InjectDependencies(this);
_chatManager.RegisterChatTransform(AccentHandler);
}
public string AccentHandler(IEntity player, string message)
{
//TODO: give accents a prio?
var accents = _componentManager.GetComponents<IAccentComponent>(player.Uid);
foreach (var accent in accents)
{
message = accent.Accentuate(message);
}
return message;
}
}
}

View File

@@ -0,0 +1,18 @@
using Robust.Shared.GameObjects;
using System;
namespace Content.Server.GameObjects.Components.Mobs.Speech
{
[RegisterComponent]
public class BackwardsAccentComponent : Component, IAccentComponent
{
public override string Name => "BackwardsAccent";
public string Accentuate(string message)
{
var arr = message.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
}
}

View File

@@ -0,0 +1,36 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC;
using Robust.Shared.Random;
using System.Collections.Generic;
namespace Content.Server.GameObjects.Components.Mobs.Speech
{
[RegisterComponent]
public class OwOAccentComponent : Component, IAccentComponent
{
public override string Name => "OwOAccent";
private static readonly IReadOnlyList<string> Faces = new List<string>{
" (・`ω´・)", " ;;w;;", " owo", " UwU", " >w<", " ^w^"
}.AsReadOnly();
private string RandomFace => IoCManager.Resolve<IRobustRandom>().Pick(Faces);
private static readonly Dictionary<string, string> SpecialWords = new Dictionary<string, string>
{
{ "you", "wu" },
};
public string Accentuate(string message)
{
foreach ((var word,var repl) in SpecialWords)
{
message = message.Replace(word, repl);
}
return message.Replace("!", RandomFace)
.Replace("r", "w").Replace("R", "W")
.Replace("l", "w").Replace("L", "W");
}
}
}

View File

@@ -0,0 +1,64 @@
using Microsoft.CodeAnalysis.Operations;
using Microsoft.EntityFrameworkCore.Internal;
using Robust.Shared.GameObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Content.Server.GameObjects.Components.Mobs.Speech
{
[RegisterComponent]
public class SpanishAccentComponent : Component, IAccentComponent
{
public override string Name => "SpanishAccent";
public string Accentuate(string message)
{
// Insert E before every S
message = InsertS(message);
// If a sentence ends with ?, insert a reverse ? at the beginning of the sentence
message = ReplaceQuestionMark(message);
return message;
}
private string InsertS(string message)
{
// Replace every new Word that starts with s/S
var msg = message.Replace(" s", " es").Replace(" S", "Es");
// Still need to check if the beginning of the message starts
if (msg.StartsWith("s"))
{
return msg.Remove(0, 1).Insert(0, "es");
}
else if (msg.StartsWith("S"))
{
return msg.Remove(0, 1).Insert(0, "Es");
}
return msg;
}
private string ReplaceQuestionMark(string message)
{
var sentences = AccentManager.SentenceRegex.Split(message);
var msg = "";
foreach (var s in sentences)
{
if (s.EndsWith("?")) // We've got a question => add ¿ to the beginning
{
// Because we don't split by whitespace, we may have some spaces in front of the sentence.
// So we add the symbol before the first non space char
msg += s.Insert(s.Length - s.TrimStart().Length, "¿");
}
else
{
msg += s;
}
}
return msg;
}
}
}

View File

@@ -0,0 +1,94 @@
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using System;
using System.Linq;
namespace Content.Server.GameObjects.Components.Mobs.Speech
{
internal interface IAccentComponent
{
/// <summary>
/// Transforms a message with the given Accent
/// </summary>
/// <param name="message">The spoken message</param>
/// <returns>The message after the transformation</returns>
public string Accentuate(string message);
}
public class AddAccent : IClientCommand
{
public string Command => "addaccent";
public string Description => "Add a speech component to the current player";
public string Help => $"{Command} <component>/?";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length == 0)
{
shell.SendText(player, Help);
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "You don't have a player!");
return;
}
var compFactory = IoCManager.Resolve<IComponentFactory>();
if (args[0] == "?")
{
// Get all components that implement the ISpeechComponent except
var speeches = compFactory.GetAllRefTypes()
.Where(c => typeof(IAccentComponent).IsAssignableFrom(c) && c.IsClass);
var msg = "";
foreach(var s in speeches)
{
msg += $"{compFactory.GetRegistration(s).Name}\n";
}
shell.SendText(player, msg);
}
else
{
var name = args[0];
// Try to get the Component
Type type;
try
{
var comp = compFactory.GetComponent(name);
type = comp.GetType();
}
catch (Exception)
{
shell.SendText(player, $"Accent {name} not found. Try {Command} ? to get a list of all appliable accents.");
return;
}
// Check if that already exists
try
{
var comp = player.AttachedEntity.GetComponent(type);
shell.SendText(player, "You already have this accent!");
return;
}
catch (Exception)
{
// Accent not found
}
// Generic fuckery
var ensure = typeof(IEntity).GetMethod("AddComponent");
if (ensure == null)
return;
var method = ensure.MakeGenericMethod(type);
method.Invoke(player.AttachedEntity, null);
}
}
}
}

View File

@@ -1,5 +1,6 @@
using Robust.Server.Interfaces.Player; using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.GameObjects;
using System;
namespace Content.Server.Interfaces.Chat namespace Content.Server.Interfaces.Chat
{ {
@@ -28,5 +29,8 @@ namespace Content.Server.Interfaces.Chat
void SendDeadChat(IPlayerSession player, string message); void SendDeadChat(IPlayerSession player, string message);
void SendHookOOC(string sender, string message); void SendHookOOC(string sender, string message);
delegate string TransformChat(IEntity speaker, string message);
void RegisterChatTransform(TransformChat handler);
} }
} }

View File

@@ -1,8 +1,9 @@
using Content.Server.AI.Utility.Considerations; using Content.Server.AI.Utility.Considerations;
using Content.Server.AI.WorldState; using Content.Server.AI.WorldState;
using Content.Server.Body.Network; using Content.Server.Body.Network;
using Content.Server.Cargo; using Content.Server.Cargo;
using Content.Server.Chat; using Content.Server.Chat;
using Content.Server.GameObjects.Components.Mobs.Speech;
using Content.Server.GameObjects.Components.NodeContainer.NodeGroups; using Content.Server.GameObjects.Components.NodeContainer.NodeGroups;
using Content.Server.GameObjects.Components.Power.PowerNetComponents; using Content.Server.GameObjects.Components.Power.PowerNetComponents;
using Content.Server.GameTicking; using Content.Server.GameTicking;
@@ -41,6 +42,7 @@ namespace Content.Server
IoCManager.Register<BlackboardManager, BlackboardManager>(); IoCManager.Register<BlackboardManager, BlackboardManager>();
IoCManager.Register<ConsiderationsManager, ConsiderationsManager>(); IoCManager.Register<ConsiderationsManager, ConsiderationsManager>();
IoCManager.Register<IBodyNetworkFactory, BodyNetworkFactory>(); IoCManager.Register<IBodyNetworkFactory, BodyNetworkFactory>();
IoCManager.Register<IAccentManager, AccentManager>();
} }
} }
} }

View File

@@ -97,6 +97,7 @@
- tilewalls - tilewalls
- events - events
- destroymechanism - destroymechanism
- addaccent
- readyall - readyall
- factions - factions
CanViewVar: true CanViewVar: true
@@ -189,6 +190,7 @@
- tilewalls - tilewalls
- events - events
- destroymechanism - destroymechanism
- addaccent
- readyall - readyall
- factions - factions
CanViewVar: true CanViewVar: true