This commit is contained in:
Dark 2020-10-18 12:17:38 -04:00
commit 18a09fe480
Signed by: Dark
GPG key ID: 8910EE89544A1676
6 changed files with 208 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
discord.so

87
discord_rpc.h Normal file
View file

@ -0,0 +1,87 @@
#pragma once
#include <stdint.h>
// clang-format off
#if defined(DISCORD_DYNAMIC_LIB)
# if defined(_WIN32)
# if defined(DISCORD_BUILDING_SDK)
# define DISCORD_EXPORT __declspec(dllexport)
# else
# define DISCORD_EXPORT __declspec(dllimport)
# endif
# else
# define DISCORD_EXPORT __attribute__((visibility("default")))
# endif
#else
# define DISCORD_EXPORT
#endif
// clang-format on
#ifdef __cplusplus
extern "C" {
#endif
typedef struct DiscordRichPresence {
const char* state; /* max 128 bytes */
const char* details; /* max 128 bytes */
int64_t startTimestamp;
int64_t endTimestamp;
const char* largeImageKey; /* max 32 bytes */
const char* largeImageText; /* max 128 bytes */
const char* smallImageKey; /* max 32 bytes */
const char* smallImageText; /* max 128 bytes */
const char* partyId; /* max 128 bytes */
int partySize;
int partyMax;
const char* matchSecret; /* max 128 bytes */
const char* joinSecret; /* max 128 bytes */
const char* spectateSecret; /* max 128 bytes */
int8_t instance;
} DiscordRichPresence;
typedef struct DiscordUser {
const char* userId;
const char* username;
const char* discriminator;
const char* avatar;
} DiscordUser;
typedef struct DiscordEventHandlers {
void (*ready)(const DiscordUser* request);
void (*disconnected)(int errorCode, const char* message);
void (*errored)(int errorCode, const char* message);
void (*joinGame)(const char* joinSecret);
void (*spectateGame)(const char* spectateSecret);
void (*joinRequest)(const DiscordUser* request);
} DiscordEventHandlers;
#define DISCORD_REPLY_NO 0
#define DISCORD_REPLY_YES 1
#define DISCORD_REPLY_IGNORE 2
DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
DiscordEventHandlers* handlers,
int autoRegister,
const char* optionalSteamId);
DISCORD_EXPORT void Discord_Shutdown(void);
/* checks for incoming messages, dispatches callbacks */
DISCORD_EXPORT void Discord_RunCallbacks(void);
/* If you disable the lib starting its own io thread, you'll need to call this from your own */
#ifdef DISCORD_DISABLE_IO_THREAD
DISCORD_EXPORT void Discord_UpdateConnection(void);
#endif
DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence);
DISCORD_EXPORT void Discord_ClearPresence(void);
DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply);
DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers);
#ifdef __cplusplus
} /* extern "C" */
#endif

BIN
libdiscord-rpc.a Normal file

Binary file not shown.

7
makefile Normal file
View file

@ -0,0 +1,7 @@
all: discord.so
discord.so:
cc mpvdiscord.c libdiscord-rpc.a -shared -o discord.so
clean:
rm discord.so

109
mpvdiscord.c Normal file
View file

@ -0,0 +1,109 @@
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <mpv/client.h>
#include "discord_rpc.h"
int mpv_command_ret(mpv_handle *ctx, char *args[], mpv_node *result) ;
//yeah
static void nullfunc() {}
static void initrpc() {
DiscordEventHandlers handlers = {
.ready = nullfunc,
.disconnected = nullfunc,
.errored = nullfunc,
.joinGame = nullfunc,
.spectateGame = nullfunc,
.joinRequest = nullfunc,
};
Discord_Initialize("599691476057849878", &handlers, 1, NULL);
}
static void update(mpv_handle *handle) {
//idle by default
char details[64] = "(idle)";
char state[64] = "(no file)";
DiscordRichPresence presence = {
.details = details,
.state = state,
.endTimestamp = 0,
};
int idle;
mpv_get_property(handle, "idle-active", MPV_FORMAT_FLAG, &idle);
if (!idle) {
//check if the player is paused
int paused;
mpv_get_property(handle, "pause", MPV_FORMAT_FLAG, &paused);
mpv_node result;
char *args[] = {
"expand-text",
NULL,
NULL
};
//current file
args[1] = "${?pause==yes:(paused) }${media-title}";
int rc = mpv_command_ret(handle, args, &result);
if (rc >= 0 && result.u.string != NULL) {
strncpy(details, result.u.string, sizeof(details));
mpv_free_node_contents(&result);
}
//state
args[1] = "${metadata/by-key/artist}";
rc = mpv_command_ret(handle, args, &result);
if (rc >= 0 && result.u.string != NULL) {
strncpy(state, result.u.string, sizeof(state));
mpv_free_node_contents(&result);
}
//show the timestamp if applicable
if (!paused) {
long int timer = time(NULL);
long int time_remaining;
mpv_get_property(handle, "time-remaining",
MPV_FORMAT_INT64, &time_remaining);
presence.endTimestamp = timer + time_remaining;
}
}
Discord_UpdatePresence(&presence);
}
int mpv_open_cplugin(mpv_handle *handle)
{
initrpc();
//mpv_observe_property(handle, 0, "pause", MPV_FORMAT_NONE);
mpv_event *event = NULL;
while(1) {
event = mpv_wait_event(handle, -1);
switch(event->event_id) {
case MPV_EVENT_SHUTDOWN:
return 0;
case MPV_EVENT_NONE:
break;
case MPV_EVENT_PAUSE:
case MPV_EVENT_UNPAUSE:
case MPV_EVENT_FILE_LOADED:
case MPV_EVENT_SEEK:
case MPV_EVENT_IDLE:
update(handle);
break;
default:
break;
}
}
}

4
readme.txt Normal file
View file

@ -0,0 +1,4 @@
this is just a dead simple mpv plugin for discord rich presence support
i don't recommend using this at all but generally you should be able to just
run `make` on a linux machine and drop `discord.so` into mpv's plugins folder