2020-03-26 15:36:06 -04:00
using System ;
using System.Reflection ;
2020-06-02 16:55:08 -04:00
//using Microsoft.Win32;
2020-03-26 15:36:06 -04:00
using IllusionPlugin ;
using GamecraftModdingAPI.Events ;
using GamecraftModdingAPI.Commands ;
using Discord ;
namespace GamecraftRPC
{
public class Plugin : IPlugin // the Illusion Plugin Architecture (IPA) will ignore classes that don't implement IPlugin'
{
public string Name { get ; } = Assembly . GetExecutingAssembly ( ) . GetName ( ) . Name ;
public string Version { get ; } = Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version . ToString ( ) ;
2020-04-06 17:36:07 -04:00
private static readonly long CLIENT_ID =
#if DEBUG
692733325902872619 ;
#else
696732441012076605 ;
#endif
2020-03-26 15:36:06 -04:00
private Discord . Discord discordRPC ;
// called when Gamecraft shuts down
public void OnApplicationQuit ( )
{
// Shutdown this mod
2020-04-06 17:36:07 -04:00
if ( discordRPC ! = null )
{
discordRPC . GetActivityManager ( ) . ClearActivity ( ( result ) = > { GamecraftModdingAPI . Utility . Logging . LogDebug ( $"Cleared status: {result}" ) ; } ) ;
discordRPC . Dispose ( ) ;
}
2020-03-26 15:36:06 -04:00
GamecraftModdingAPI . Utility . Logging . LogDebug ( $"{Name} has shutdown" ) ;
// Shutdown the Gamecraft modding API last
GamecraftModdingAPI . Main . Shutdown ( ) ;
}
// called when Gamecraft starts up
public void OnApplicationStart ( )
{
// Initialize the Gamecraft modding API first
GamecraftModdingAPI . Main . Init ( ) ;
2020-06-02 16:55:08 -04:00
// detect Wine (maybe?)
bool isWineDetected = false ;
foreach ( var key in Microsoft . Win32 . Registry . CurrentUser . OpenSubKey ( "Software" ) . GetSubKeyNames ( ) )
{
if ( key = = "Wine" )
{
isWineDetected = true ;
break ;
}
}
if ( isWineDetected )
{
// check for or install fake Discord
GamecraftModdingAPI . Utility . Logging . MetaLog ( "\n--------------------------------\n\nIt looks like you may be using Wine/Proton, cool!\nPlease install https://github.com/0e4ef622/wine-discord-ipc-bridge to get this to work.\n\n--------------------------------" ) ;
}
2020-03-26 15:36:06 -04:00
// Initialize this mod
discordRPC = new Discord . Discord ( CLIENT_ID , ( UInt64 ) Discord . CreateFlags . Default ) ;
2020-04-06 17:36:07 -04:00
discordRPC . SetLogHook ( LogLevel . Debug , ( _ , msg ) = > { GamecraftModdingAPI . Utility . Logging . MetaLog ( msg ) ; } ) ;
discordRPC . GetRelationshipManager ( ) . OnRefresh + = ( ) = >
{
discordRPC . GetRelationshipManager ( ) . Filter ( ( ref Relationship r ) = > { return r . Presence . Status = = Status . Online & & r . Type = = RelationshipType . Friend ; } ) ;
PresenceUtility . Users = new Relationship [ discordRPC . GetRelationshipManager ( ) . Count ( ) ] ;
for ( uint i = 0 ; i < discordRPC . GetRelationshipManager ( ) . Count ( ) ; i + + )
{
PresenceUtility . Users [ i ] = discordRPC . GetRelationshipManager ( ) . GetAt ( i ) ;
}
} ;
2020-03-26 15:36:06 -04:00
SetDiscordActivity ( discordRPC , state : "Loading..." , details : "Initializing Gamecraft" , start : ( int ) ( DateTime . UtcNow . Subtract ( new DateTime ( 1970 , 1 , 1 ) ) ) . TotalSeconds ) ;
EventManager . AddEventHandler ( new Events . GamePresenceHandler ( discordRPC ) ) ;
EventManager . AddEventHandler ( new Events . MenuPresenceHandler ( discordRPC ) ) ;
EventManager . AddEventHandler ( new Events . EditPresenceHandler ( discordRPC ) ) ;
EventManager . AddEventHandler ( new Events . SimulatePresenceHandler ( discordRPC ) ) ;
SimpleCustomCommandEngine < string > rpcCommand = new SimpleCustomCommandEngine < string > (
( s ) = > { SetDiscordActivity ( discordRPC , state : s ) ; } , // TODO: command action
"SetRichPresence" , // command name (used to invoke it in the console)
"Set Discord status (experimental)" // command description (displayed when help command is executed)
) ; // this command can also be executed using the Command Computer
2020-04-06 17:36:07 -04:00
SimpleCustomCommandEngine inviteNGniusCommand = new SimpleCustomCommandEngine ( ( ) = >
discordRPC . GetActivityManager ( ) . SendInvite ( 106537989684887552 , ActivityActionType . Join , "Join the Borg" , ( res ) = > { GamecraftModdingAPI . Utility . Logging . LogDebug ( $"Send invite {res}" ) ; } ) ,
"InviteNGnius" ,
"Send a Discord lobby invite to NGnius" ) ;
SimpleCustomCommandEngine < long > inviteDiscordCommand = new SimpleCustomCommandEngine < long > ( ( id ) = >
discordRPC . GetActivityManager ( ) . SendInvite ( id , ActivityActionType . Join , "Join the Borg" , ( res ) = > { GamecraftModdingAPI . Utility . Logging . LogDebug ( $"Send invite {res}" ) ; } ) ,
"InviteDiscord" ,
"Send a game invite to a Discord user" ) ;
SimpleCustomCommandEngine listDiscordUsersCommand = new SimpleCustomCommandEngine (
( ) = >
{
string result = "Online Friends\n" ;
for ( int i = 0 ; i < PresenceUtility . Users . Length ; i + + )
{
result + = $"{PresenceUtility.Users[i].User.Username} ({PresenceUtility.Users[i].User.Id})\n" ;
}
GamecraftModdingAPI . Utility . Logging . CommandLog ( result ) ;
} ,
"ListDiscordUsers" ,
"List online Discord friends" ) ;
2020-03-26 15:36:06 -04:00
// register the command so the modding API knows about it
2020-04-06 17:36:07 -04:00
CommandManager . AddCommand ( rpcCommand ) ;
CommandManager . AddCommand ( inviteNGniusCommand ) ;
CommandManager . AddCommand ( inviteDiscordCommand ) ;
CommandManager . AddCommand ( listDiscordUsersCommand ) ;
GamecraftModdingAPI . Utility . GameEngineManager . AddGameEngine ( new Engines . PlayerCountEngine ( discordRPC ) ) ;
2020-03-26 15:36:06 -04:00
GamecraftModdingAPI . Utility . Logging . LogDebug ( $"{Name} has started up" ) ;
}
// unused methods
public void OnFixedUpdate ( ) { } // called once per physics update
public void OnLevelWasInitialized ( int level ) { } // called after a level is initialized
public void OnLevelWasLoaded ( int level ) { } // called after a level is loaded
public void OnUpdate ( ) // called once per rendered frame (frame update)
{
if ( discordRPC ! = null ) discordRPC . RunCallbacks ( ) ;
}
2020-04-06 17:36:07 -04:00
public static void SetDiscordActivity ( Discord . Discord discordRPC , string state = null , string details = null , int start = 0 , int end = 0 , string largeImg = "gamecraft-logo-g" , string largeTxt = "Gamecraft" , string smallImg = "exmods-logo-xm2" , string smallTxt = "Exmods" , string partyId = null , int partyCurrentSize = 0 , int partyMaxSize = 0 , string matchSecret = null , string joinSecret = null , string spectateSecret = null , bool instance = true , string debug = "" )
2020-03-26 15:36:06 -04:00
{
if ( discordRPC = = null ) return ;
2020-04-06 17:36:07 -04:00
ref Activity activity = ref PresenceUtility . Activity ;
activity . Instance = instance ;
2020-03-26 15:36:06 -04:00
if ( state ! = null ) activity . State = state ;
if ( details ! = null ) activity . Details = details ;
if ( start ! = 0 ) activity . Timestamps . Start = start ;
if ( end ! = 0 ) activity . Timestamps . End = end ;
if ( ! string . IsNullOrEmpty ( largeImg ) )
{
activity . Assets . LargeImage = largeImg ;
activity . Assets . LargeText = largeTxt ;
}
if ( ! string . IsNullOrEmpty ( smallImg ) )
{
activity . Assets . SmallImage = smallImg ;
activity . Assets . SmallText = smallTxt ;
}
2020-04-06 17:36:07 -04:00
if ( ! string . IsNullOrEmpty ( partyId ) )
{
activity . Party . Id = partyId ;
activity . Party . Size . CurrentSize = partyCurrentSize ;
activity . Party . Size . MaxSize = partyMaxSize ;
}
if ( ! string . IsNullOrEmpty ( matchSecret ) | | ! string . IsNullOrEmpty ( joinSecret ) | | ! string . IsNullOrEmpty ( spectateSecret ) )
{
activity . Secrets . Match = matchSecret ;
activity . Secrets . Join = joinSecret ;
activity . Secrets . Spectate = spectateSecret ;
}
2020-03-26 15:36:06 -04:00
discordRPC . GetActivityManager ( ) . UpdateActivity ( activity , result = >
{
2020-04-06 17:36:07 -04:00
GamecraftModdingAPI . Utility . Logging . MetaLog ( $"Update Activity Result: {result} {debug}" ) ;
} ) ;
}
public static void SetDiscordActivity ( Discord . Discord discordRPC , Discord . Activity activity , string debug = "" )
{
PresenceUtility . Activity = activity ;
discordRPC . GetActivityManager ( ) . UpdateActivity ( PresenceUtility . Activity , result = >
{
GamecraftModdingAPI . Utility . Logging . MetaLog ( $"Update Activity Result: {result} {debug}" ) ;
} ) ;
}
public static void SetDiscordActivity ( Discord . Discord discordRPC , string debug = "" )
{
discordRPC . GetActivityManager ( ) . UpdateActivity ( PresenceUtility . Activity , result = >
{
GamecraftModdingAPI . Utility . Logging . MetaLog ( $"Update Activity Result: {result} {debug}" ) ;
2020-03-26 15:36:06 -04:00
} ) ;
}
}
}