diff --git a/MCGalaxy/Config/JSON.cs b/MCGalaxy/Config/JSON.cs index cd43b71d6..840c6d579 100644 --- a/MCGalaxy/Config/JSON.cs +++ b/MCGalaxy/Config/JSON.cs @@ -4,15 +4,17 @@ using System.Collections.Generic; using System.IO; using System.Text; -namespace MCGalaxy.Config { - +namespace MCGalaxy.Config +{ public sealed class JsonArray : List { } - public sealed class JsonObject : Dictionary { + public sealed class JsonObject : Dictionary + { public object Meta; public void Deserialise(ConfigElement[] elems, object instance) { - foreach (var kvp in this) { + foreach (var kvp in this) + { ConfigElement.Parse(elems, instance, kvp.Key, (string)kvp.Value); } } @@ -21,7 +23,8 @@ namespace MCGalaxy.Config { public delegate void JsonOnMember(JsonObject obj, string key, object value); /// Implements a simple JSON parser. - public sealed class JsonReader { + public sealed class JsonReader + { public readonly string Value; /// Whether an error occurred while parsing the given JSON. public bool Failed; @@ -48,7 +51,8 @@ namespace MCGalaxy.Config { bool NextConstant(string value) { if (offset + value.Length > Value.Length) return false; - for (int i = 0; i < value.Length; i++) { + for (int i = 0; i < value.Length; i++) + { if (Value[offset + i] != value[i]) return false; } @@ -130,7 +134,8 @@ namespace MCGalaxy.Config { string ParseString() { StringBuilder s = strBuffer; s.Length = 0; - for (; offset < Value.Length;) { + for (; offset < Value.Length;) + { char c = Cur; offset++; if (c == '"') return s.ToString(); if (c != '\\') { s.Append(c); continue; } @@ -175,7 +180,8 @@ namespace MCGalaxy.Config { } } - public class JsonWriter { + public class JsonWriter + { readonly TextWriter w; public JsonWriter(TextWriter dst) { w = dst; } @@ -189,7 +195,8 @@ namespace MCGalaxy.Config { public void WriteString(string value) { w.Write('"'); - foreach (char c in value) { + foreach (char c in value) + { if (c == '/') { w.Write("\\/"); } else if (c == '\\') { w.Write("\\\\"); } else if (c == '"') { w.Write("\\\""); @@ -207,7 +214,8 @@ namespace MCGalaxy.Config { w.Write("[\r\n"); string separator = ""; - for (int i = 0; i < array.Count; i++) { + for (int i = 0; i < array.Count; i++) + { w.Write(separator); object value = array[i]; WriteValue(value); @@ -251,7 +259,8 @@ namespace MCGalaxy.Config { string separator = null; JsonObject obj = (JsonObject)value; - foreach (var kvp in obj) { + foreach (var kvp in obj) + { Write(separator); WriteObjectKey(kvp.Key); WriteValue(kvp.Value); @@ -260,7 +269,8 @@ namespace MCGalaxy.Config { } } - public class JsonConfigWriter : JsonWriter { + public class JsonConfigWriter : JsonWriter + { ConfigElement[] elems; public JsonConfigWriter(TextWriter dst, ConfigElement[] cfg) : base(dst) { elems = cfg; } @@ -280,7 +290,8 @@ namespace MCGalaxy.Config { protected override void SerialiseObject(object value) { string separator = null; - for (int i = 0; i < elems.Length; i++) { + for (int i = 0; i < elems.Length; i++) + { ConfigElement elem = elems[i]; ConfigAttribute a = elem.Attrib; Write(separator); @@ -295,8 +306,8 @@ namespace MCGalaxy.Config { } } - public static class Json { - + public static class Json + { [Obsolete("Use JsonWriter instead", true)] public static void Serialise(TextWriter dst, ConfigElement[] elems, object instance) { JsonConfigWriter w = new JsonConfigWriter(dst, elems); diff --git a/MCGalaxy/MCGalaxy_.csproj b/MCGalaxy/MCGalaxy_.csproj index 9f48c4c5e..81abcba73 100644 --- a/MCGalaxy/MCGalaxy_.csproj +++ b/MCGalaxy/MCGalaxy_.csproj @@ -595,6 +595,7 @@ + @@ -602,6 +603,7 @@ + diff --git a/MCGalaxy/Modules/Relay/Discord/DiscordBot.cs b/MCGalaxy/Modules/Relay/Discord/DiscordBot.cs index bddbd09f2..391ce6ce5 100644 --- a/MCGalaxy/Modules/Relay/Discord/DiscordBot.cs +++ b/MCGalaxy/Modules/Relay/Discord/DiscordBot.cs @@ -20,7 +20,6 @@ using System.Collections.Generic; using System.IO; using System.Text; using MCGalaxy.Config; -using MCGalaxy.Events; using MCGalaxy.Events.PlayerEvents; using MCGalaxy.Games; using MCGalaxy.Tasks; @@ -28,23 +27,6 @@ using MCGalaxy.Util; namespace MCGalaxy.Modules.Relay.Discord { - public delegate void OnSendingWhoEmbed(DiscordBot bot, RelayUser user, ref ChannelSendEmbed embed); - /// Called when sending an embed response to a .who message from Discord - public sealed class OnSendingWhoEmbedEvent : IEvent - { - public static void Call(DiscordBot bot, RelayUser user, ref ChannelSendEmbed embed) { - IEvent[] items = handlers.Items; - for (int i = 0; i < items.Length; i++) - { - try { - items[i].method(bot, user, ref embed); - } catch (Exception ex) { - LogHandlerException(ex, items[i]); - } - } - } - } - sealed class DiscordUser : RelayUser { public string ReferencedUser; @@ -106,6 +88,7 @@ namespace MCGalaxy.Modules.Relay.Discord socket.OnResumed = HandleResumedEvent; socket.OnMessageCreate = HandleMessageEvent; socket.OnChannelCreate = HandleChannelEvent; + socket.OnGatewayEvent = HandleGatewayEvent; socket.Connect(); } @@ -333,6 +316,10 @@ namespace MCGalaxy.Modules.Relay.Discord } OnReady(); } + + void HandleGatewayEvent(string eventName, JsonObject data) { + OnGatewayEventReceivedEvent.Call(this, eventName, data); + } static bool IsEscaped(char c) { diff --git a/MCGalaxy/Modules/Relay/Discord/DiscordBotEvents.cs b/MCGalaxy/Modules/Relay/Discord/DiscordBotEvents.cs new file mode 100644 index 000000000..98c0cfaca --- /dev/null +++ b/MCGalaxy/Modules/Relay/Discord/DiscordBotEvents.cs @@ -0,0 +1,57 @@ +/* + Copyright 2015 MCGalaxy + + Dual-licensed under the Educational Community License, Version 2.0 and + the GNU General Public License, Version 3 (the "Licenses"); you may + not use this file except in compliance with the Licenses. You may + obtain a copy of the Licenses at + + https://opensource.org/license/ecl-2-0/ + https://www.gnu.org/licenses/gpl-3.0.html + + Unless required by applicable law or agreed to in writing, + software distributed under the Licenses are distributed on an "AS IS" + BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the Licenses for the specific language governing + permissions and limitations under the Licenses. + */ +using System; +using MCGalaxy.Config; +using MCGalaxy.Events; + +namespace MCGalaxy.Modules.Relay.Discord +{ + public delegate void OnSendingWhoEmbed(DiscordBot bot, RelayUser user, ref ChannelSendEmbed embed); + /// Called when sending an embed response to a .who message from Discord + public sealed class OnSendingWhoEmbedEvent : IEvent + { + public static void Call(DiscordBot bot, RelayUser user, ref ChannelSendEmbed embed) { + IEvent[] items = handlers.Items; + for (int i = 0; i < items.Length; i++) + { + try { + items[i].method(bot, user, ref embed); + } catch (Exception ex) { + LogHandlerException(ex, items[i]); + } + } + } + } + + public delegate void OnGatewayEventReceived(DiscordBot bot, string eventName, JsonObject data); + /// Called when a gateway event has been received from Discord + public sealed class OnGatewayEventReceivedEvent : IEvent + { + public static void Call(DiscordBot bot, string eventName, JsonObject data) { + IEvent[] items = handlers.Items; + for (int i = 0; i < items.Length; i++) + { + try { + items[i].method(bot, eventName, data); + } catch (Exception ex) { + LogHandlerException(ex, items[i]); + } + } + } + } +} diff --git a/MCGalaxy/Modules/Relay/Discord/DiscordWebsocket.cs b/MCGalaxy/Modules/Relay/Discord/DiscordWebsocket.cs index 453672df2..2d977de13 100644 --- a/MCGalaxy/Modules/Relay/Discord/DiscordWebsocket.cs +++ b/MCGalaxy/Modules/Relay/Discord/DiscordWebsocket.cs @@ -64,6 +64,8 @@ namespace MCGalaxy.Modules.Relay.Discord public Action OnMessageCreate; /// Callback invoked when a channel created event has been received public Action OnChannelCreate; + /// Callback invoked when a gateway event has been received + public Action OnGatewayEvent; readonly object sendLock = new object(); SchedulerTask heartbeat; @@ -200,23 +202,23 @@ namespace MCGalaxy.Modules.Relay.Discord if (obj.TryGetValue("s", out sequence)) Session.LastSeq = (string)sequence; - string eventName = (string)obj["t"]; - JsonObject data; + string eventName = (string)obj["t"]; + object rawData; + + obj.TryGetValue("d", out rawData); + JsonObject data = (JsonObject)rawData; if (eventName == "READY") { - data = (JsonObject)obj["d"]; HandleReady(data); OnReady(data); } else if (eventName == "RESUMED") { - data = (JsonObject)obj["d"]; OnResumed(data); } else if (eventName == "MESSAGE_CREATE") { - data = (JsonObject)obj["d"]; OnMessageCreate(data); } else if (eventName == "CHANNEL_CREATE") { - data = (JsonObject)obj["d"]; OnChannelCreate(data); } + OnGatewayEvent(eventName, data); } void HandleReady(JsonObject data) { diff --git a/MCGalaxy/Modules/Relay/RelayBot.cs b/MCGalaxy/Modules/Relay/RelayBot.cs index 5a4df692d..57888aa62 100644 --- a/MCGalaxy/Modules/Relay/RelayBot.cs +++ b/MCGalaxy/Modules/Relay/RelayBot.cs @@ -21,9 +21,7 @@ using System.IO; using System.Net.Sockets; using System.Text; using System.Threading; -using MCGalaxy.Commands; using MCGalaxy.DB; -using MCGalaxy.Events; using MCGalaxy.Events.ServerEvents; namespace MCGalaxy.Modules.Relay @@ -34,38 +32,6 @@ namespace MCGalaxy.Modules.Relay public virtual string GetMessagePrefix() { return ""; } } - - public delegate void OnDirectMessage(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel); - /// Called when an external communication service user sends a message directly to the relay bot - public sealed class OnDirectMessageEvent : IEvent - { - public static void Call(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel) { - IEvent[] items = handlers.Items; - for (int i = 0; i < items.Length; i++) { - try { - items[i].method(bot, channel, user, message, ref cancel); - } catch (Exception ex) { - LogHandlerException(ex, items[i]); - } - } - } - } - - public delegate void OnChannelMessage(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel); - /// Called when an external communication service user sends a message to the given channel - public sealed class OnChannelMessageEvent : IEvent - { - public static void Call(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel) { - IEvent[] items = handlers.Items; - for (int i = 0; i < items.Length; i++) { - try { - items[i].method(bot, channel, user, message, ref cancel); - } catch (Exception ex) { - LogHandlerException(ex, items[i]); - } - } - } - } /// Manages a connection to an external communication service public abstract class RelayBot diff --git a/MCGalaxy/Modules/Relay/RelayBotEvents.cs b/MCGalaxy/Modules/Relay/RelayBotEvents.cs new file mode 100644 index 000000000..164d72828 --- /dev/null +++ b/MCGalaxy/Modules/Relay/RelayBotEvents.cs @@ -0,0 +1,56 @@ +/* + Copyright 2011 MCForge + + Dual-licensed under the Educational Community License, Version 2.0 and + the GNU General Public License, Version 3 (the "Licenses"); you may + not use this file except in compliance with the Licenses. You may + obtain a copy of the Licenses at + + https://opensource.org/license/ecl-2-0/ + https://www.gnu.org/licenses/gpl-3.0.html + + Unless required by applicable law or agreed to in writing, + software distributed under the Licenses are distributed on an "AS IS" + BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the Licenses for the specific language governing + permissions and limitations under the Licenses. + */ +using System; +using MCGalaxy.Events; + +namespace MCGalaxy.Modules.Relay +{ + public delegate void OnDirectMessage(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel); + /// Called when an external communication service user sends a message directly to the relay bot + public sealed class OnDirectMessageEvent : IEvent + { + public static void Call(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel) { + IEvent[] items = handlers.Items; + for (int i = 0; i < items.Length; i++) + { + try { + items[i].method(bot, channel, user, message, ref cancel); + } catch (Exception ex) { + LogHandlerException(ex, items[i]); + } + } + } + } + + public delegate void OnChannelMessage(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel); + /// Called when an external communication service user sends a message to the given channel + public sealed class OnChannelMessageEvent : IEvent + { + public static void Call(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel) { + IEvent[] items = handlers.Items; + for (int i = 0; i < items.Length; i++) + { + try { + items[i].method(bot, channel, user, message, ref cancel); + } catch (Exception ex) { + LogHandlerException(ex, items[i]); + } + } + } + } +}