Add event for when a gateway event is received from Discord

This commit is contained in:
UnknownShadow200 2024-01-02 18:38:40 +11:00
parent 03ba36f694
commit 6b3af740b7
7 changed files with 154 additions and 73 deletions

View File

@ -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<object> { }
public sealed class JsonObject : Dictionary<string, object> {
public sealed class JsonObject : Dictionary<string, object>
{
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);
/// <summary> Implements a simple JSON parser. </summary>
public sealed class JsonReader {
public sealed class JsonReader
{
public readonly string Value;
/// <summary> Whether an error occurred while parsing the given JSON. </summary>
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);

View File

@ -595,6 +595,7 @@
<Compile Include="Modules\Relay\BotControllersCmd.cs" />
<Compile Include="Modules\Relay\Discord\DiscordApiClient.cs" />
<Compile Include="Modules\Relay\Discord\DiscordBot.cs" />
<Compile Include="Modules\Relay\Discord\DiscordBotEvents.cs" />
<Compile Include="Modules\Relay\Discord\DiscordMessages.cs" />
<Compile Include="Modules\Relay\Discord\DiscordPlugin.cs" />
<Compile Include="Modules\Relay\Discord\DiscordWebsocket.cs" />
@ -602,6 +603,7 @@
<Compile Include="Modules\Relay\IRC\IRCPlugin.cs" />
<Compile Include="Modules\Relay\RelayBot.cs" />
<Compile Include="Modules\Relay\RelayBotCmd.cs" />
<Compile Include="Modules\Relay\RelayBotEvents.cs" />
<Compile Include="Modules\Security\IPThrottler.cs" />
<Compile Include="Modules\Warps\CmdWarp.cs" />
<Compile Include="Modules\Warps\CmdWaypoint.cs" />

View File

@ -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);
/// <summary> Called when sending an embed response to a .who message from Discord </summary>
public sealed class OnSendingWhoEmbedEvent : IEvent<OnSendingWhoEmbed>
{
public static void Call(DiscordBot bot, RelayUser user, ref ChannelSendEmbed embed) {
IEvent<OnSendingWhoEmbed>[] 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();
}
@ -334,6 +317,10 @@ namespace MCGalaxy.Modules.Relay.Discord
OnReady();
}
void HandleGatewayEvent(string eventName, JsonObject data) {
OnGatewayEventReceivedEvent.Call(this, eventName, data);
}
static bool IsEscaped(char c) {
// To match Discord: \a --> \a, \* --> *

View File

@ -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);
/// <summary> Called when sending an embed response to a .who message from Discord </summary>
public sealed class OnSendingWhoEmbedEvent : IEvent<OnSendingWhoEmbed>
{
public static void Call(DiscordBot bot, RelayUser user, ref ChannelSendEmbed embed) {
IEvent<OnSendingWhoEmbed>[] 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);
/// <summary> Called when a gateway event has been received from Discord </summary>
public sealed class OnGatewayEventReceivedEvent : IEvent<OnGatewayEventReceived>
{
public static void Call(DiscordBot bot, string eventName, JsonObject data) {
IEvent<OnGatewayEventReceived>[] 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]);
}
}
}
}
}

View File

@ -64,6 +64,8 @@ namespace MCGalaxy.Modules.Relay.Discord
public Action<JsonObject> OnMessageCreate;
/// <summary> Callback invoked when a channel created event has been received </summary>
public Action<JsonObject> OnChannelCreate;
/// <summary> Callback invoked when a gateway event has been received </summary>
public Action<string, JsonObject> OnGatewayEvent;
readonly object sendLock = new object();
SchedulerTask heartbeat;
@ -201,22 +203,22 @@ namespace MCGalaxy.Modules.Relay.Discord
Session.LastSeq = (string)sequence;
string eventName = (string)obj["t"];
JsonObject data;
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) {

View File

@ -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
@ -35,38 +33,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);
/// <summary> Called when an external communication service user sends a message directly to the relay bot </summary>
public sealed class OnDirectMessageEvent : IEvent<OnDirectMessage>
{
public static void Call(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel) {
IEvent<OnDirectMessage>[] 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);
/// <summary> Called when an external communication service user sends a message to the given channel </summary>
public sealed class OnChannelMessageEvent : IEvent<OnChannelMessage>
{
public static void Call(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel) {
IEvent<OnChannelMessage>[] 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]);
}
}
}
}
/// <summary> Manages a connection to an external communication service </summary>
public abstract class RelayBot
{

View File

@ -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);
/// <summary> Called when an external communication service user sends a message directly to the relay bot </summary>
public sealed class OnDirectMessageEvent : IEvent<OnDirectMessage>
{
public static void Call(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel) {
IEvent<OnDirectMessage>[] 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);
/// <summary> Called when an external communication service user sends a message to the given channel </summary>
public sealed class OnChannelMessageEvent : IEvent<OnChannelMessage>
{
public static void Call(RelayBot bot, string channel, RelayUser user, string message, ref bool cancel) {
IEvent<OnChannelMessage>[] 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]);
}
}
}
}
}