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 ;
2020-06-26 19:36:40 -04:00
using GamecraftModdingAPI.App ;
2020-03-26 15:36:06 -04:00
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 ;
2020-06-26 19:36:40 -04:00
public string Version { get ; } =
#if DEBUG
Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version . ToString ( ) + "alpha" ;
#else
Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version . ToString ( ) ;
#endif
2020-03-26 15:36:06 -04:00
2020-06-26 19:36:40 -04:00
private const long CLIENT_ID =
2020-04-06 17:36:07 -04:00
#if DEBUG
692733325902872619 ;
#else
2020-06-26 19:36:40 -04:00
696732441012076605 ;
#endif
private const LogLevel LOG_LEVEL =
#if DEBUG
LogLevel . Debug ;
#else
LogLevel . Warn ;
2020-04-06 17:36:07 -04:00
#endif
2020-03-26 15:36:06 -04:00
2020-06-26 19:36:40 -04:00
internal static Discord . Discord DiscordRPC ;
2020-03-26 15:36:06 -04:00
// called when Gamecraft shuts down
public void OnApplicationQuit ( )
{
// Shutdown this mod
2020-06-26 19:36:40 -04:00
if ( DiscordRPC ! = null )
2020-04-06 17:36:07 -04:00
{
2020-06-26 19:36:40 -04:00
DiscordRPC . GetActivityManager ( ) . ClearActivity ( ( result ) = > { GamecraftModdingAPI . Utility . Logging . LogDebug ( $"Cleared status: {result}" ) ; DiscordRPC . Dispose ( ) ; } ) ;
2020-04-06 17:36:07 -04:00
}
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 )
{
2020-06-26 19:36:40 -04:00
// info for getting this to work through Wine/Proton
2020-06-02 16:55:08 -04:00
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
2020-06-26 19:36:40 -04:00
DiscordRPC = new Discord . Discord ( CLIENT_ID , ( UInt64 ) Discord . CreateFlags . NoRequireDiscord ) ;
DiscordRPC . SetLogHook ( LOG_LEVEL , ( _ , msg ) = > { GamecraftModdingAPI . Utility . Logging . MetaLog ( msg ) ; } ) ;
//DiscordRPC.GetActivityManager().RegisterSteam(1078000);
2020-04-06 17:36:07 -04:00
2020-06-26 19:36:40 -04:00
ActivityManager am = DiscordRPC . GetActivityManager ( ) ;
am . OnActivityJoinRequest + = CallbackUtility . ActivityJoinRequest ;
am . OnActivityJoin + = CallbackUtility . ActivityJoin ;
am . OnActivityInvite + = CallbackUtility . ActivityInvite ;
LobbyManager lm = DiscordRPC . GetLobbyManager ( ) ;
lm . OnMemberConnect + = CallbackUtility . DiscordUserJoin ;
SetDiscordActivity ( state : $"{UnityEngine.Application.version} ({Version})" , details : $"Initializing..." , start : ( int ) ( DateTime . UtcNow . Subtract ( new DateTime ( 1970 , 1 , 1 ) ) ) . TotalSeconds ) ;
Game . Edit + = CallbackUtility . BuildEnter ;
Game . Enter + = CallbackUtility . GameEnter ;
Game . Simulate + = CallbackUtility . SimulationEnter ;
Client . EnterMenu + = CallbackUtility . MenuEnter ;
GamecraftModdingAPI . Utility . GameEngineManager . AddGameEngine ( new Engines . PlayerCountEngine ( ) ) ;
CommandBuilder . Builder ( )
. Name ( "JoinDiscord" )
. Description ( "Join the Exmods server for help or more information" )
. Action ( ( ) = >
{
if ( DiscordRPC ! = null )
{
DiscordRPC . GetOverlayManager ( ) . OpenGuildInvite ( "2CtWzZT" , CallbackUtility . NobodyCares ) ;
}
else
{
GamecraftModdingAPI . Utility . Logging . CommandLogError ( "Discord GameSDK functionality is unavailable. Please make sure Discord is open when launching Gamecraft." ) ;
}
} )
. Build ( ) ;
CommandBuilder . Builder ( )
. Name ( "InviteDiscordUser" )
. Description ( "Invite a Discord user (by id) to your game" )
. Action < long > ( ( userId ) = >
{
if ( DiscordRPC ! = null )
{
Game game = Game . CurrentGame ( ) ;
DiscordRPC . GetActivityManager ( ) . SendInvite ( userId , Discord . ActivityActionType . Join , $"Let's play Gamecraft together! (requires the GamecraftRPC mod)" , CallbackUtility . NobodyCares ) ;
}
else
{
GamecraftModdingAPI . Utility . Logging . CommandLogError ( "Discord GameSDK functionality is unavailable. Please make sure Discord is open when launching Gamecraft." ) ;
}
} )
. Build ( ) ;
2020-04-06 17:36:07 -04:00
2020-06-26 19:36:40 -04:00
CommandBuilder . Builder ( )
. Name ( Name + "Info" )
. Description ( "Build information for the GamecraftRPC mod." )
. Action ( ( ) = >
{
if ( DiscordRPC ! = null )
2020-04-06 17:36:07 -04:00
{
2020-06-26 19:36:40 -04:00
Game game = Game . CurrentGame ( ) ;
Client client = new Client ( ) ;
GamecraftModdingAPI . Utility . Logging . CommandLog ( $"Gamecraft {client.Version}\nUnity {client.UnityVersion}\n{Name} {Version}\nSDK {DiscordRPC.ToString()}\nGame {game.Name}" ) ;
2020-04-06 17:36:07 -04:00
}
2020-06-26 19:36:40 -04:00
else
2020-04-06 17:36:07 -04:00
{
2020-06-26 19:36:40 -04:00
GamecraftModdingAPI . Utility . Logging . CommandLogError ( "Discord GameSDK functionality is unavailable. Please make sure Discord is open when launching Gamecraft." ) ;
}
} )
. Build ( ) ;
2020-03-26 15:36:06 -04:00
GamecraftModdingAPI . Utility . Logging . LogDebug ( $"{Name} has started up" ) ;
}
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)
{
2020-06-26 19:36:40 -04:00
if ( DiscordRPC ! = null ) DiscordRPC . RunCallbacks ( ) ;
2020-03-26 15:36:06 -04:00
}
2020-06-26 19:36:40 -04:00
public static void SetDiscordActivity ( string state = null , string details = null , long start = 0 , long 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
{
2020-06-26 19:36:40 -04:00
if ( DiscordRPC = = null ) return ;
2020-03-26 15:36:06 -04:00
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
2020-06-26 19:36:40 -04:00
DiscordRPC . GetActivityManager ( ) . UpdateActivity ( activity , result = >
2020-03-26 15:36:06 -04:00
{
2020-04-06 17:36:07 -04:00
GamecraftModdingAPI . Utility . Logging . MetaLog ( $"Update Activity Result: {result} {debug}" ) ;
} ) ;
}
2020-06-26 19:36:40 -04:00
public static void SetDiscordActivity ( Discord . Activity activity , string debug = "" )
2020-04-06 17:36:07 -04:00
{
2020-06-26 19:36:40 -04:00
if ( DiscordRPC = = null ) return ;
2020-04-06 17:36:07 -04:00
PresenceUtility . Activity = activity ;
2020-06-26 19:36:40 -04:00
DiscordRPC . GetActivityManager ( ) . UpdateActivity ( PresenceUtility . Activity , result = >
2020-04-06 17:36:07 -04:00
{
GamecraftModdingAPI . Utility . Logging . MetaLog ( $"Update Activity Result: {result} {debug}" ) ;
} ) ;
}
2020-06-26 19:36:40 -04:00
public static void SetDiscordActivity ( string debug = "" )
2020-04-06 17:36:07 -04:00
{
2020-06-26 19:36:40 -04:00
if ( DiscordRPC = = null ) return ;
DiscordRPC . GetActivityManager ( ) . UpdateActivity ( PresenceUtility . Activity , result = >
2020-04-06 17:36:07 -04:00
{
GamecraftModdingAPI . Utility . Logging . MetaLog ( $"Update Activity Result: {result} {debug}" ) ;
2020-03-26 15:36:06 -04:00
} ) ;
}
}
}