mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-01-10 14:17:13 +00:00
189 lines
5.3 KiB
Haxe
189 lines
5.3 KiB
Haxe
package funkin.api.discord;
|
|
|
|
#if FEATURE_DISCORD_RPC
|
|
import hxdiscord_rpc.Discord;
|
|
import hxdiscord_rpc.Types;
|
|
import sys.thread.Thread;
|
|
|
|
class DiscordClient
|
|
{
|
|
static final CLIENT_ID:String = "814588678700924999";
|
|
|
|
public static var instance(get, never):DiscordClient;
|
|
static var _instance:Null<DiscordClient> = null;
|
|
|
|
static function get_instance():DiscordClient
|
|
{
|
|
if (DiscordClient._instance == null) _instance = new DiscordClient();
|
|
if (DiscordClient._instance == null) throw "Could not initialize singleton DiscordClient!";
|
|
return DiscordClient._instance;
|
|
}
|
|
|
|
var handlers:DiscordEventHandlers;
|
|
|
|
private function new()
|
|
{
|
|
trace('[DISCORD] Initializing event handlers...');
|
|
|
|
handlers = DiscordEventHandlers.create();
|
|
|
|
handlers.ready = cpp.Function.fromStaticFunction(onReady);
|
|
handlers.disconnected = cpp.Function.fromStaticFunction(onDisconnected);
|
|
handlers.errored = cpp.Function.fromStaticFunction(onError);
|
|
}
|
|
|
|
public function init():Void
|
|
{
|
|
trace('[DISCORD] Initializing connection...');
|
|
|
|
// Discord.initialize(CLIENT_ID, handlers, true, null);
|
|
Discord.Initialize(CLIENT_ID, cpp.RawPointer.addressOf(handlers), 1, null);
|
|
|
|
createDaemon();
|
|
}
|
|
|
|
var daemon:Thread = null;
|
|
|
|
function createDaemon():Void
|
|
{
|
|
daemon = Thread.create(doDaemonWork);
|
|
}
|
|
|
|
function doDaemonWork():Void
|
|
{
|
|
while (true)
|
|
{
|
|
trace('[DISCORD] Performing client update...');
|
|
|
|
#if DISCORD_DISABLE_IO_THREAD
|
|
Discord.updateConnection();
|
|
#end
|
|
|
|
Discord.runCallbacks();
|
|
Sys.sleep(2);
|
|
}
|
|
}
|
|
|
|
public function shutdown():Void
|
|
{
|
|
trace('[DISCORD] Shutting down...');
|
|
|
|
Discord.shutdown();
|
|
}
|
|
|
|
public function setPresence(params:DiscordClientPresenceParams):Void
|
|
{
|
|
trace('[DISCORD] Updating presence... (${params})');
|
|
|
|
Discord.updatePresence(buildPresence(params));
|
|
}
|
|
|
|
function buildPresence(params:DiscordClientPresenceParams):DiscordRichPresence
|
|
{
|
|
var presence = DiscordRichPresence.create();
|
|
|
|
// Presence should always be playing the game.
|
|
presence.type = DiscordActivityType_Playing;
|
|
|
|
// Text when hovering over the large image. We just leave this as the game name.
|
|
presence.largeImageText = "Friday Night Funkin'";
|
|
|
|
// State should be generally what the person is doing, like "In the Menus" or "Pico (Pico Mix) [Freeplay Hard]"
|
|
presence.state = cast(params.state, Null<String>);
|
|
// Details should be what the person is specifically doing, including stuff like timestamps (maybe something like "03:24 elapsed").
|
|
presence.details = cast(params.details, Null<String>);
|
|
|
|
// The large image displaying what the user is doing.
|
|
// This should probably be album art.
|
|
// IMPORTANT NOTE: This can be an asset key uploaded to Discord's developer panel OR any URL you like.
|
|
// presence.largeImageKey = "icon";
|
|
presence.largeImageKey = "https://f4.bcbits.com/img/a3122193953_16.jpg";
|
|
// The small inset image for what the user is doing.
|
|
// This can be the opponent's health icon?
|
|
presence.smallImageKey = cast(params.smallImageKey, Null<String>);
|
|
|
|
// Start timestamp, used to power elapsed/remaining data
|
|
// presence.startTimestamp
|
|
// End timestamp, used to power elapsed/remaining data
|
|
// presence.endTimestamp
|
|
|
|
return presence;
|
|
}
|
|
|
|
// TODO: WHAT THE FUCK get this pointer bullfuckery out of here
|
|
private static function onReady(request:cpp.RawConstPointer<DiscordUser>):Void
|
|
{
|
|
trace('[DISCORD] Client has connected!');
|
|
|
|
final username:String = request[0].username;
|
|
final globalName:String = request[0].username;
|
|
final discriminator:Int = Std.parseInt(request[0].discriminator);
|
|
|
|
if (discriminator != 0)
|
|
{
|
|
trace('[DISCORD] User: ${username}#${discriminator} (${globalName})');
|
|
}
|
|
else
|
|
{
|
|
trace('[DISCORD] User: @${username} (${globalName})');
|
|
}
|
|
}
|
|
|
|
private static function onDisconnected(errorCode:Int, message:cpp.ConstCharStar):Void
|
|
{
|
|
trace('[DISCORD] Client has disconnected! ($errorCode) "${cast (message, String)}"');
|
|
}
|
|
|
|
private static function onError(errorCode:Int, message:cpp.ConstCharStar):Void
|
|
{
|
|
trace('[DISCORD] Client has received an error! ($errorCode) "${cast (message, String)}"');
|
|
}
|
|
|
|
// public var type(get, set):DiscordActivityType;
|
|
// public var state(get, set):String;
|
|
// public var details(get, set):String;
|
|
// public var startTimestamp(get, set):Int;
|
|
// public var endTimestamp(get, set):Int;
|
|
// public var largeImageKey(get, set):String;
|
|
// public var largeImageText(get, set):String;
|
|
// public var smallImageKey(get, set):String;
|
|
// public var smallImageText(get, set):String;
|
|
//
|
|
//
|
|
// public var partyId(get, set)
|
|
// public var partySize(get, set)
|
|
// public var partyMax(get, set)
|
|
// public var partyPrivacy(get, set)
|
|
//
|
|
// public var buttons(get, set)
|
|
//
|
|
// public var matchSecret(get, set)
|
|
// public var joinSecret(get, set)
|
|
// public var spectateSecret(get, set)
|
|
}
|
|
|
|
typedef DiscordClientPresenceParams =
|
|
{
|
|
/**
|
|
* The first row of text below the game title.
|
|
*/
|
|
var state:String;
|
|
|
|
/**
|
|
* The second row of text below the game title.
|
|
* Use `null` to display no text.
|
|
*/
|
|
var details:Null<String>;
|
|
|
|
/**
|
|
* A large, 4-row high image to the left of the content.
|
|
*/
|
|
var ?largeImageKey:String;
|
|
|
|
/**
|
|
* A small, inset image to the bottom right of `largeImageKey`.
|
|
*/
|
|
var ?smallImageKey:String;
|
|
}
|
|
#end
|