Last active
January 9, 2020 15:34
-
-
Save nathan130200/12e0a3ca9c79ce63e52a3aa8e85ceb1d to your computer and use it in GitHub Desktop.
DSharpPlus Remote Event Handlers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using System.Reflection; | |
using System.Text; | |
using System.Threading.Tasks; | |
using DSharpPlus; | |
namespace Workshop | |
{ | |
static class A | |
{ | |
public static void V(this object o) | |
{ | |
} | |
} | |
public class EventEmitter | |
{ | |
private DiscordShardedClient _client; | |
public EventEmitter(DiscordShardedClient client) | |
{ | |
_client = client; | |
} | |
public void Bind<T>(string name, AsyncEventHandler<T> handler, bool once = false) where T : AsyncEventArgs | |
{ | |
var evht = typeof(AsyncEventHandler<>) | |
.MakeGenericType(typeof(T)); | |
var evh = _client.GetType().GetEvents() | |
.Where(x => x.EventHandlerType == evht && x.Name == name) | |
.FirstOrDefault(); | |
if (evh == null) | |
throw new NullReferenceException("Cannot register handler to unknown event type."); | |
if (!once) | |
evh.AddEventHandler(_client, handler); | |
else | |
{ | |
AsyncEventHandler<T> callback = default; | |
callback = async e => | |
{ | |
await handler(e).ConfigureAwait(false); | |
if (e.Handled) | |
this.Unbind(name, callback); | |
}; | |
evh.AddEventHandler(_client, callback); | |
} | |
} | |
public void Unbind<T>(string name, AsyncEventHandler<T> handler) where T : AsyncEventArgs | |
{ | |
var evht = typeof(AsyncEventHandler<>) | |
.MakeGenericType(typeof(T)); | |
var evh = _client.GetType().GetEvents() | |
.Where(x => x.EventHandlerType == evht && x.Name == name) | |
.FirstOrDefault(); | |
if (evh == null) | |
throw new NullReferenceException("Cannot register handler to unknown event type."); | |
evh.RemoveEventHandler(_client, handler); | |
} | |
public void RegisterEvents() | |
{ | |
this.RegisterGenericEvents(); | |
this.RegisterNonGenericEvents(); | |
} | |
protected void RegisterGenericEvents() | |
{ | |
foreach (var type in typeof(EventEmitter).Assembly.GetTypes()) | |
{ | |
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) | |
{ | |
if (method.GetParameters().Count() != 1) | |
continue; | |
var attr = method.GetCustomAttribute<AsyncEventHandlerAttribute>(); | |
if (attr == null) | |
continue; | |
else | |
{ | |
if (!attr.IsGeneric) | |
continue; | |
var argt = method.GetParameters().First().ParameterType; | |
var evht = typeof(AsyncEventHandler<>) | |
.MakeGenericType(argt); | |
EventInfo evh; | |
if (string.IsNullOrEmpty(attr.Name)) | |
evh = _client.GetType().GetEvents() | |
.Where(xe => xe.EventHandlerType == evht) | |
.FirstOrDefault(); | |
else | |
evh = _client.GetType().GetEvent(attr.Name); | |
var fullname = string.Concat(type.FullName, ".", method.Name); | |
if (evh == null) | |
Console.WriteLine("[EventEmitter] Cannot bind {0} as event handler of {1}", fullname, argt.Name); | |
else | |
{ | |
evh.AddEventHandler(_client, method.CreateDelegate(evht)); | |
Console.WriteLine("[EventEmitter] Function {0} bind to handler {1}.", fullname, | |
string.Concat(_client.GetType().Name, "::", evh.Name)); | |
} | |
} | |
} | |
} | |
} | |
protected void RegisterNonGenericEvents() | |
{ | |
foreach (var type in typeof(EventEmitter).Assembly.GetTypes()) | |
{ | |
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) | |
{ | |
var attr = method.GetCustomAttribute<AsyncEventHandlerAttribute>(); | |
if (attr == null || attr.IsGeneric) | |
continue; | |
else | |
{ | |
var fullname = string.Concat(type.FullName, ".", method.Name); | |
if (string.IsNullOrEmpty(attr.Name)) | |
{ | |
Console.WriteLine("[EventEmitter] Cannot bind function {0} as event handler.", fullname); | |
continue; | |
} | |
var evht = typeof(AsyncEventHandler); | |
var evh = _client.GetType().GetEvent(attr.Name); | |
if (evh == null) | |
Console.WriteLine("[EventEmitter] Cannot bind {0} as event handler of {1}", fullname, attr.Name); | |
else | |
{ | |
evh.AddEventHandler(_client, method.CreateDelegate(evht)); | |
Console.WriteLine("[EventEmitter] Function {0} bind to handler {1}.", fullname, | |
string.Concat(_client.GetType().Name, "::", evh.Name)); | |
} | |
} | |
} | |
} | |
} | |
} | |
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] | |
public sealed class AsyncEventHandlerAttribute : Attribute | |
{ | |
public string Name { get; set; } | |
public bool IsGeneric { get; set; } | |
public AsyncEventHandlerAttribute() | |
{ | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using DSharpPlus; | |
using DSharpPlus.Entities; | |
using DSharpPlus.EventArgs; | |
namespace Workshop.Events | |
{ | |
class TestReadyEvent | |
{ | |
[AsyncEventHandler(IsGeneric = true)] | |
static async Task OnReady(ReadyEventArgs e) | |
{ | |
await e.Client.UpdateStatusAsync(new DiscordActivity | |
{ | |
Name = $"workshop help | {e.Client.Ping}ms", | |
ActivityType = ActivityType.Watching | |
}); | |
} | |
[AsyncEventHandler(IsGeneric = true)] | |
static async Task OnHeartbeat(HeartbeatEventArgs e) | |
{ | |
await e.Client.UpdateStatusAsync(new DiscordActivity | |
{ | |
Name = $"w!help | {e.Client.Ping}ms", | |
ActivityType = ActivityType.Watching | |
}); | |
} | |
[AsyncEventHandler(Name = "SocketOpened")] | |
static async Task OnSocketOpened() | |
{ | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment