Skip to content

Instantly share code, notes, and snippets.

@nathan130200
Last active January 9, 2020 15:34
Show Gist options
  • Save nathan130200/12e0a3ca9c79ce63e52a3aa8e85ceb1d to your computer and use it in GitHub Desktop.
Save nathan130200/12e0a3ca9c79ce63e52a3aa8e85ceb1d to your computer and use it in GitHub Desktop.
DSharpPlus Remote Event Handlers.
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()
{
}
}
}
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