You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
12 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using ProxyCore.Messages;
using ProxyCore.Scripting;
namespace ProxyCore.Output
{
internal static class TriggerHandler
{
static TriggerHandler()
{
}
private static SortedDictionary<int, List<TriggerEntry>> Triggers = new SortedDictionary<int, List<TriggerEntry>>();
internal static Dictionary<string, TriggerEntry> TriggersName = new Dictionary<string, TriggerEntry>();
internal static void DisableTriggers(string FromPlugin, int MinPriority, int MaxPriority)
{
if(FromPlugin == null)
return;
FromPlugin = FromPlugin.ToLower().Trim();
if(FromPlugin.Length == 0)
return;
foreach(KeyValuePair<int, List<TriggerEntry>> x in Triggers)
{
if(x.Key < MinPriority)
continue;
if(x.Key > MaxPriority)
break;
foreach(TriggerEntry y in x.Value)
{
if(y.Disabled == null)
y.Disabled = new List<string>();
if(!y.Disabled.Contains(FromPlugin))
y.Disabled.Add(FromPlugin);
}
}
}
internal static void EnableTriggers(string FromPlugin, int MinPriority, int MaxPriority)
{
if(FromPlugin == null)
return;
FromPlugin = FromPlugin.ToLower().Trim();
if(FromPlugin.Length == 0)
return;
foreach(KeyValuePair<int, List<TriggerEntry>> x in Triggers)
{
if(x.Key < MinPriority)
continue;
if(x.Key > MaxPriority)
break;
foreach(TriggerEntry y in x.Value)
{
if(y.Disabled == null)
continue;
y.Disabled.Remove(FromPlugin);
}
}
}
/// <summary>
/// Register a new trigger.
/// </summary>
/// <param name="Name">Unique identifier for the trigger.</param>
/// <param name="Pattern">Regex pattern for the trigger.</param>
/// <param name="Function">Function that will be called if this trigger fires.</param>
internal static void RegisterTrigger(string Name, string Pattern, TriggerFunction Function)
{
RegisterTrigger(Name, Pattern, Function, TriggerFlags.None);
}
/// <summary>
/// Register a new trigger.
/// </summary>
/// <param name="Name">Unique identifier for the trigger.</param>
/// <param name="Pattern">Regex pattern for the trigger.</param>
/// <param name="Function">Function that will be called if this trigger fires.</param>
/// <param name="Flags">Options for the trigger.</param>
internal static void RegisterTrigger(string Name, string Pattern, TriggerFunction Function, TriggerFlags Flags)
{
RegisterTrigger(Name, Pattern, Function, Flags, 1000);
}
/// <summary>
/// Register a new trigger.
/// </summary>
/// <param name="Name">Unique identifier for the trigger.</param>
/// <param name="Pattern">Regex pattern for the trigger.</param>
/// <param name="Function">Function that will be called if this trigger fires.</param>
/// <param name="Flags">Options for the trigger.</param>
/// <param name="Priority">Lower priority triggers get matched first. Default: 1000</param>
internal static void RegisterTrigger(string Name, string Pattern, TriggerFunction Function, TriggerFlags Flags, int Priority)
{
RegisterTrigger(Name, Pattern, Function, Flags, Priority, 0, "core");
}
/// <summary>
/// Register a new trigger.
/// </summary>
/// <param name="Name">Unique identifier for the trigger.</param>
/// <param name="Pattern">Regex pattern for the trigger.</param>
/// <param name="Function">Function that will be called if this trigger fires.</param>
/// <param name="Flags">Options for the trigger.</param>
/// <param name="Priority">Lower priority triggers get matched first. Default: 1000</param>
/// <param name="Arg">Custom argument to pass to trigger data.</param>
/// <param name="Plugin">From which plugin was this registered.</param>
internal static void RegisterTrigger(string Name, string Pattern, TriggerFunction Function, TriggerFlags Flags, int Priority, int Arg, string Plugin)
{
if(string.IsNullOrEmpty(Pattern) || string.IsNullOrEmpty(Name) || Function == null)
return;
Name = Name.ToLower().Trim();
if(Name.Length == 0)
return;
Regex p = null;
if((Flags & TriggerFlags.NotRegex) == TriggerFlags.None)
{
try
{
RegexOptions op = RegexOptions.None;
if((Flags & TriggerFlags.RightToLeft) != TriggerFlags.None)
op |= RegexOptions.RightToLeft;
if((Flags & TriggerFlags.CaseInsensitive) != TriggerFlags.None)
op |= RegexOptions.IgnoreCase;
p = new Regex(Pattern, op);
}
catch
{
return;
}
}
TriggerEntry e = new TriggerEntry();
e.Function = Function;
e.Pattern = p;
e.PatternStr = Pattern;
e.Priority = Priority;
e.Name = Name;
e.Flags = Flags;
e.Arg = Arg;
e.Plugin = Plugin;
if(TriggersName.ContainsKey(Name))
Triggers[TriggersName[Name].Priority].Remove(TriggersName[Name]);
TriggersName[Name] = e;
if(!Triggers.ContainsKey(e.Priority))
Triggers[e.Priority] = new List<TriggerEntry>();
Triggers[e.Priority].Add(e);
}
/// <summary>
/// Unregister a trigger by name.
/// </summary>
/// <param name="Name">Name of the trigger you wish to unregister.</param>
internal static void UnregisterTrigger(string Name)
{
if(Name != null)
Name = Name.ToLower().Trim();
if(string.IsNullOrEmpty(Name))
return;
if(!TriggersName.ContainsKey(Name))
return;
Triggers[TriggersName[Name].Priority].Remove(TriggersName[Name]);
TriggersName.Remove(Name);
}
internal static void HandleText(string Msg, World world)
{
if(!string.IsNullOrEmpty(lastColorCode))
Msg = lastColorCode + Msg;
lastColorCode = Colors.GetLastColorCode(Msg);
Msg = Colors.RemoveDuplicateColors(Msg);
Message m = new Message(true);
m.Msg = Msg;
HandleLineRaw(m);
if(m.Msg != null)
{
world._SendMessage(m);
world.lastLine.Add(m.Msg);
while(world.lastLine.Count > 100)
world.lastLine.RemoveAt(0);
}
}
private static string lastColorCode = "";
private static readonly List<KeyValuePair<string, string>> gmcpData =
new List<KeyValuePair<string, string>>();
internal static void HandleGMCP(string Msg)
{
//string origMsg = Msg;
string module;
try
{
int ind = Msg.IndexOf(' ');
if(ind == -1)
{
module = Msg;
Msg = "";
}
else
{
module = Msg.Substring(0, ind);
Msg = Msg.Substring(ind).Trim();
}
}
catch
{
return;
}
if(string.IsNullOrEmpty(module))
return;
if(gmcpData.Count != 0)
gmcpData.Clear();
module = module.ToLower();
bool res = JSON.Parse(Msg, module, gmcpData);
if(!res)
return;
if(gmcpData.Count == 0)
HandleGMCP(module, null);
else
{
foreach(KeyValuePair<string, string> i in gmcpData)
HandleGMCP(i.Key.ToLower().Trim(), i.Value);
}
}
private static void HandleGMCP(string Module, string Value)
{
Message m = new Message(true);
m.Msg = "$gmcp." + Module + (Value != null ? (" " + Value) : "");
HandleLineRaw(m);
}
private static void HandleLineRaw(Message Msg)
{
foreach(KeyValuePair<string, Plugin> x in PluginMgr.Plugins)
{
try
{
x.Value.OnReceivedLineBefore(Msg);
}
catch(Exception e)
{
Log.Crash(e, x.Key);
}
if(Msg.Msg == null)
return;
}
foreach(KeyValuePair<int, List<TriggerEntry>> x in Triggers)
{
foreach(TriggerEntry y in x.Value)
{
if(y.Disabled != null && y.Disabled.Count != 0)
continue;
int i = 0;
while(Msg.Msg != null)
{
int o = i;
Match m = null;
if((y.Flags & TriggerFlags.NotRegex) == TriggerFlags.None)
{
if((y.Flags & TriggerFlags.RightToLeft) != TriggerFlags.None)
m = y.Pattern.Match((y.Flags & TriggerFlags.NonAnsi) == TriggerFlags.None ? Msg.Msg : Msg.MsgNoColor);
else
m = y.Pattern.Match((y.Flags & TriggerFlags.NonAnsi) == TriggerFlags.None ? Msg.Msg : Msg.MsgNoColor, i);
if(!m.Success)
break;
}
else if(y.PatternStr != ((y.Flags & TriggerFlags.NonAnsi) == TriggerFlags.None ? Msg.Msg : Msg.MsgNoColor))
break;
TriggerData d = new TriggerData();
d.Match = m;
d.Arg = y.Arg;
d.Msg = Msg;
#if !DEBUG
try
{
#endif
if(y.Function(d))
{
Msg.Msg = null;
return;
}
#if !DEBUG
}
catch(Exception e)
{
Log.Crash(e, y.Plugin);
}
#endif
if((y.Flags & TriggerFlags.NotRegex) != TriggerFlags.None)
break;
if((y.Flags & TriggerFlags.RightToLeft) != TriggerFlags.None)
break;
i = m.Groups[0].Index + m.Groups[0].Length;
if((y.Flags & TriggerFlags.Repeat) == TriggerFlags.None)
break;
if(i == o)
i++;
}
}
}
foreach(KeyValuePair<string, Plugin> x in PluginMgr.Plugins)
{
#if !DEBUG
try
{
#endif
x.Value.OnReceivedLineAfter(Msg);
#if !DEBUG
}
catch(Exception e)
{
Log.Crash(e, x.Key);
}
#endif
if(Msg.Msg == null)
return;
}
}
}
}