Skip to content

Commit

Permalink
Cerberus muting properly, and allow plugins to modify params, also mu…
Browse files Browse the repository at this point in the history
…te command
  • Loading branch information
Enovale committed Oct 18, 2020
1 parent e1dc604 commit 43c7784
Show file tree
Hide file tree
Showing 16 changed files with 329 additions and 131 deletions.
3 changes: 3 additions & 0 deletions .idea/.idea.Alibi/.idea/contentModel.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

137 changes: 76 additions & 61 deletions .idea/.idea.Alibi/.idea/workspace.xml

Large diffs are not rendered by default.

14 changes: 10 additions & 4 deletions Alibi.Plugins.API/IServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,19 @@ public interface IServer
public void ReloadConfig();
public void Broadcast(IAOPacket message);
public void BroadcastOocMessage(string message);
/// <summary>
/// Find a client using an id, ooc name, character name, or hwid. (IPs dont work)
/// </summary>
/// <param name="str">an id, ooc name, char name, or HWID to search for.</param>
/// <returns></returns>
public IClient? FindUser(string str);

public void OnAllPluginsLoaded();
public bool OnIcMessage(IClient client, string message);
public bool OnOocMessage(IClient client, string message);
public bool OnMusicChange(IClient client, string song);
public void OnPlayerJoined(IClient client);
public bool OnIcMessage(IClient client, ref string message);
public bool OnOocMessage(IClient client, ref string message);
public bool OnMusicChange(IClient client, ref string song);
public bool OnModCall(IClient client, IAOPacket packet);
public bool OnBan(IClient client, string reason, TimeSpan? expires = null);
public bool OnBan(IClient client, ref string reason, TimeSpan? expires = null);
}
}
9 changes: 5 additions & 4 deletions Alibi.Plugins.API/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ public abstract class Plugin
public abstract void Initialize();

public virtual void OnAllPluginsLoaded() { }
public virtual bool OnIcMessage(IClient client, string message) { return true; }
public virtual bool OnOocMessage(IClient client, string message) { return true; }
public virtual bool OnMusicChange(IClient client, string song) { return true; }
public virtual void OnPlayerJoined(IClient client) { }
public virtual bool OnIcMessage(IClient client, ref string message) { return true; }
public virtual bool OnOocMessage(IClient client, ref string message) { return true; }
public virtual bool OnMusicChange(IClient client, ref string song) { return true; }
public virtual bool OnModCall(IClient caller, string reason) { return true; }
public virtual bool OnBan(IClient banned, string reason, TimeSpan? expires = null) { return true; }
public virtual bool OnBan(IClient banned, ref string reason, TimeSpan? expires = null) { return true; }

public void Log(LogSeverity severity, string message, bool verbose = false)
{
Expand Down
6 changes: 5 additions & 1 deletion Alibi.Plugins.Cerberus/Alibi.Plugins.Cerberus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>..\Alibi\bin\Debug\</OutputPath>
<OutputPath>bin\Debug\</OutputPath>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Alibi.Plugins.API\Alibi.Plugins.API.csproj" />
</ItemGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="XCOPY &quot;$(TargetPath)&quot; &quot;$(SolutionDir)\$(SolutionName)\bin\$(ConfigurationName)\netcoreapp3.1\win-x64\Plugins\&quot; /S /Y" />
</Target>

</Project>
6 changes: 6 additions & 0 deletions Alibi.Plugins.Cerberus/CerberusConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
{
public class CerberusConfiguration
{
public bool StripZalgo { get; set; } = true;

public int MaxIcMessagesPerSecond { get; set; } = 3;
public int IcMuteLengthInSeconds { get; set; } = 5;
public int MaxOocMessagesPerSecond { get; set; } = 3;
public int OocMuteLengthInSeconds { get; set; } = 5;
public int MaxMusicMessagesPerSecond { get; set; } = 2;
public int MusicMuteLengthInSeconds { get; set; } = 5;
}
}
153 changes: 125 additions & 28 deletions Alibi.Plugins.Cerberus/MainPlugin.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Alibi.Plugins.API;

Expand All @@ -17,65 +18,161 @@ public class MainPlugin : Plugin

private string _configPath;

private Dictionary<IClient, Tuple<DateTime, int>> _icTimeDict;
private Dictionary<IClient, MuteInfo> _clientDict;

public override void Initialize()
{
_configPath = Path.Combine(PluginManager.GetConfigFolder(ID), "config.json");
if (!File.Exists(_configPath))
if (!File.Exists(_configPath) || new FileInfo(_configPath).Length <= 0)
File.WriteAllText(_configPath, JsonSerializer.Serialize(new CerberusConfiguration(),
new JsonSerializerOptions {WriteIndented = true}));

Config = JsonSerializer.Deserialize<CerberusConfiguration>(File.ReadAllText(_configPath));

_icTimeDict = new Dictionary<IClient, Tuple<DateTime, int>>(Server.ClientsConnected.Count);
_clientDict = new Dictionary<IClient, MuteInfo>();
foreach (var client in Server.ClientsConnected)
_clientDict.Add(client, new MuteInfo());

MutedClientsCheck();
}

// ReSharper disable once FunctionRecursiveOnAllPaths
private async void MutedClientsCheck()
{
foreach (var client in _icTimeDict.Keys)
if (client.Muted
&& _icTimeDict[client].Item1.AddSeconds(Config.IcMuteLengthInSeconds).CompareTo(DateTime.Now) <
var queue = new Queue<IClient>(_clientDict.Keys);
while (queue.Count > 0)
{
var client = queue.Dequeue();
if (_clientDict[client].IcMuted
&& _clientDict[client].IcTimer.AddSeconds(Config.IcMuteLengthInSeconds).CompareTo(DateTime.Now) <
0)
{
client.SendOocMessage("You have been un-muted in IC.");
_clientDict[client].IcMuted = false;
}

if (_clientDict[client].OocMuted
&& _clientDict[client].OocTimer.AddSeconds(Config.OocMuteLengthInSeconds).CompareTo(DateTime.Now) <
0)
{
client.SendOocMessage("You have been un-muted in OOC.");
_clientDict[client].OocMuted = false;
}

if (_clientDict[client].MusicMuted
&& _clientDict[client].MusicTimer.AddSeconds(Config.MusicMuteLengthInSeconds)
.CompareTo(DateTime.Now) <
0)
{
client.SendOocMessage("You have been un-muted.");
client.Muted = false;
client.SendOocMessage("You have been un-muted from changing Music.");
_clientDict[client].MusicMuted = false;
}
}

await Task.Delay(1000);
MutedClientsCheck();
}

public override bool OnIcMessage(IClient client, string message)
public override void OnPlayerJoined(IClient client)
{
if (_icTimeDict.ContainsKey(client))
_clientDict[client] = new MuteInfo();
}

private string StripZalgo(string message)
{
if (!Config.StripZalgo)
return message;
StringBuilder sb = new StringBuilder();
foreach (char c in message.Normalize(NormalizationForm.FormC))
{
if (DateTime.Now.CompareTo(_icTimeDict[client].Item1) >= 0)
{
_icTimeDict[client] = new Tuple<DateTime, int>(DateTime.Now.AddSeconds(1), 0);
}
else
{
var tuple = _icTimeDict[client];
_icTimeDict[client] = new Tuple<DateTime, int>(tuple.Item1, tuple.Item2 + 1);
}
if (char.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
sb.Append(c);
}

if (_icTimeDict[client].Item2 > Config.MaxIcMessagesPerSecond)
{
client.Muted = true;
client.SendOocMessage($"You have been muted for {Config.IcMuteLengthInSeconds} seconds.");
_icTimeDict[client] = new Tuple<DateTime, int>(DateTime.Now, 0);
return false;
}
return sb.ToString();
}

public override bool OnIcMessage(IClient client, ref string message)
{
message = StripZalgo(message);
if (Config.IcMuteLengthInSeconds < 0 || Config.MaxIcMessagesPerSecond < 0)
return true;
if (_clientDict[client].IcMuted)
return false;
if (DateTime.Now.CompareTo(_clientDict[client].IcTimer) >= 0)
{
_clientDict[client].IcTimer = DateTime.Now.AddSeconds(1);
_clientDict[client].IcMessages = 0;
}
else
{
_clientDict[client].IcMessages++;
}

if (_clientDict[client].IcMessages > Config.MaxIcMessagesPerSecond)
{
client.SendOocMessage($"You have been IC muted for {Config.IcMuteLengthInSeconds} seconds.");
_clientDict[client].IcTimer = DateTime.Now;
_clientDict[client].IcMessages = 0;
_clientDict[client].IcMuted = true;
return false;
}

return true;
}

public override bool OnOocMessage(IClient client, ref string message)
{
message = StripZalgo(message);
if (Config.OocMuteLengthInSeconds < 0 || Config.MaxOocMessagesPerSecond < 0)
return true;
if (_clientDict[client].OocMuted)
return false;
if (DateTime.Now.CompareTo(_clientDict[client].OocTimer) >= 0)
{
_clientDict[client].OocTimer = DateTime.Now.AddSeconds(1);
_clientDict[client].OocMessages = 0;
}
else
{
_icTimeDict.Add(client, new Tuple<DateTime, int>(DateTime.Now, 0));
_clientDict[client].OocMessages++;
}

if (_clientDict[client].OocMessages > Config.MaxOocMessagesPerSecond)
{
client.SendOocMessage($"You have been OOC muted for {Config.OocMuteLengthInSeconds} seconds.");
_clientDict[client].OocTimer = DateTime.Now;
_clientDict[client].OocMessages = 0;
_clientDict[client].OocMuted = true;
return false;
}

return true;
}

public override bool OnMusicChange(IClient client, ref string song)
{
if (Config.MusicMuteLengthInSeconds < 0 || Config.MaxMusicMessagesPerSecond < 0)
return true;
if (_clientDict[client].MusicMuted)
return false;
if (DateTime.Now.CompareTo(_clientDict[client].MusicTimer) >= 0)
{
_clientDict[client].MusicTimer = DateTime.Now.AddSeconds(1);
_clientDict[client].MusicMessages = 0;
}
else
{
_clientDict[client].MusicMessages++;
}

if (_clientDict[client].MusicMessages > Config.MaxMusicMessagesPerSecond)
{
client.SendOocMessage($"You have been Music muted for {Config.MusicMuteLengthInSeconds} seconds.");
_clientDict[client].MusicTimer = DateTime.Now;
_clientDict[client].MusicMessages = 0;
_clientDict[client].MusicMuted = true;
return false;
}

return true;
Expand Down
17 changes: 17 additions & 0 deletions Alibi.Plugins.Cerberus/MuteInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;

namespace Alibi.Plugins.Cerberus
{
public class MuteInfo
{
public DateTime IcTimer = DateTime.Now;
public int IcMessages = 0;
public bool IcMuted = false;
public DateTime OocTimer = DateTime.Now;
public int OocMessages = 0;
public bool OocMuted = false;
public DateTime MusicTimer = DateTime.Now;
public int MusicMessages = 0;
public bool MusicMuted = false;
}
}
4 changes: 2 additions & 2 deletions Alibi.Plugins.Webhook/Alibi.Plugins.Webhook.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<Optimize>false</Optimize>
<OutputPath>..\Alibi\bin\Debug\</OutputPath>
<OutputPath>bin\Debug\</OutputPath>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
Expand All @@ -21,7 +21,7 @@
</PropertyGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="XCOPY &quot;$(TargetPath)&quot; &quot;$(SolutionDir)\$(SolutionName)\bin\$(ConfigurationName)\netcoreapp3.1\Plugins\&quot; /S /Y" />
<Exec Command="XCOPY &quot;$(TargetPath)&quot; &quot;$(SolutionDir)\$(SolutionName)\bin\$(ConfigurationName)\netcoreapp3.1\win-x64\Plugins\&quot; /S /Y" />
</Target>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Alibi.Plugins.Webhook/DiscordWebhook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public override bool OnModCall(IClient caller, string reason)
return true;
}

public override bool OnBan(IClient banned, string reason, TimeSpan? expires = null)
public override bool OnBan(IClient banned, ref string reason, TimeSpan? expires = null)
{
if (_validConfig && _enabled)
{
Expand Down
2 changes: 1 addition & 1 deletion Alibi/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public string GetBanReason()

public void BanHwid(string reason, TimeSpan? expireDate)
{
if (!ServerRef.OnBan(ServerRef.FindUser(HardwareId!)!, reason, expireDate))
if (!ServerRef.OnBan(ServerRef.FindUser(HardwareId!)!, ref reason, expireDate))
return;
Server.Database.BanHwid(HardwareId, reason, expireDate);
Send(new AOPacket("KB", reason));
Expand Down
2 changes: 2 additions & 0 deletions Alibi/ClientSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ protected override void OnConnected()
Client.LastAlive = DateTime.Now;
Client.KickIfBanned();

((Server)Server).OnPlayerJoined(Client);

// fuck fantaencrypt
Send(new AOPacket("decryptor", "NOENCRYPT"));
}
Expand Down
20 changes: 20 additions & 0 deletions Alibi/Commands/Commands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,26 @@ internal static void RemoveLogin(IClient client, string[] args)
throw new CommandException("Could not remove user " + args[0] + ". Does it exist?");
}

[ModOnly]
[CommandHandler("mute", "Prevent a player from sending messages to IC or OOC")]
internal static void Mute(IClient client, string[] args)
{
if (args.Length <= 0)
throw new CommandException("Usage: /mute <charid/name/oocname/hwid>");

client.ServerRef.FindUser(args[0])!.Muted = true;
}

[ModOnly]
[CommandHandler("unmute", "Allow a player to send messages again")]
internal static void Un(IClient client, string[] args)
{
if (args.Length <= 0)
throw new CommandException("Usage: /unmute <charid/name/oocname/hwid>");

client.ServerRef.FindUser(args[0])!.Muted = false;
}

[ModOnly]
[CommandHandler("ban", "Ban a user. You can specify a hardware ID or IP")]
internal static void Ban(IClient client, string[] args)
Expand Down
2 changes: 0 additions & 2 deletions Alibi/Protocol/IcValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ internal static AOPacket ValidateIcPacket(IAOPacket packet, IClient client)
// TODO: Sanitization and zalgo cleaning
string sentMessage = packet.Objects[4];
sentMessage = Regex.Replace(sentMessage,@"\s+"," ");
if(sentMessage.Length > Server.ServerConfiguration.MaxMessageSize)
throw new IcValidationException("Message was too long.");
if (!Server.ServerConfiguration.AllowDoublePostsIfDifferentAnim && sentMessage == client.LastSentMessage)
throw new IcValidationException("Cannot double post.");
if (Server.ServerConfiguration.AllowDoublePostsIfDifferentAnim
Expand Down
Loading

0 comments on commit 43c7784

Please sign in to comment.