@@ -0,0 +1,196 @@ | |||
using System; | |||
using System.Security.Cryptography; | |||
using System.Text; | |||
using GamecraftModdingAPI.App; | |||
using GamecraftModdingAPI.Utility; | |||
namespace GamecraftRPC | |||
{ | |||
public static class CallbackUtility | |||
{ | |||
private const int SALT_BYTE_LENGTH = 256; | |||
private const string STATE_IN_GAME = "In Game"; | |||
private const string STATE_IN_MENU = "In Menu"; | |||
private const string DEETS_SIM = "Playing "; | |||
private const string DEETS_BUILD = "Building "; | |||
private const string DEETS_MENU = null; | |||
private static RandomNumberGenerator random = RandomNumberGenerator.Create(); | |||
private static long lastUserJoinRequest = 0; | |||
public static void GameEnter(object sender, GameEventArgs data) | |||
{ | |||
PresenceUtility.LastGameStart = (ulong)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; | |||
if (PresenceUtility.IsConnecting && PresenceUtility.Lobby.HasValue) | |||
{ | |||
PresenceUtility.IsConnecting = false; | |||
ConnectToGamecraftPeer(PresenceUtility.Lobby.Value); | |||
} | |||
else | |||
{ | |||
Plugin.SetDiscordActivity( | |||
state: STATE_IN_GAME, | |||
details: DEETS_BUILD + data.GameName, | |||
partyMaxSize: 0, | |||
partyCurrentSize: 0, | |||
start: (long)PresenceUtility.LastGameStart, | |||
debug: "GameEnter-API-callback" | |||
); | |||
CreateLobby(); | |||
} | |||
} | |||
public static void MenuEnter(object sender, MenuEventArgs data) | |||
{ | |||
PresenceUtility.LastGameStart = 0; | |||
PresenceUtility.Activity.Timestamps.Start = 0; | |||
PresenceUtility.Activity.Timestamps.End = 0; | |||
PresenceUtility.Activity.Party.Id = null; | |||
PresenceUtility.Activity.Party.Size.CurrentSize = 0; | |||
PresenceUtility.Activity.Party.Size.MaxSize = 0; | |||
PresenceUtility.Activity.Details = DEETS_MENU; | |||
PresenceUtility.Activity.State = STATE_IN_MENU; | |||
PresenceUtility.Activity.Secrets.Join = null; | |||
if (PresenceUtility.Lobby.HasValue && Plugin.DiscordRPC != null) | |||
{ | |||
if (PresenceUtility.IsActivityHost) | |||
{ | |||
Plugin.DiscordRPC.GetLobbyManager().DeleteLobby(PresenceUtility.Lobby.Value.Id, NobodyCares); | |||
} | |||
else | |||
{ | |||
Plugin.DiscordRPC.GetLobbyManager().DisconnectLobby(PresenceUtility.Lobby.Value.Id, NobodyCares); | |||
} | |||
PresenceUtility.Lobby = null; | |||
} | |||
PresenceUtility.IsActivityHost = false; | |||
PresenceUtility.IsServerActive = false; | |||
Plugin.SetDiscordActivity(PresenceUtility.Activity, debug: "MenuEnter-API-callback"); | |||
} | |||
public static void SimulationEnter(object sender, GameEventArgs data) | |||
{ | |||
PresenceUtility.Activity.Details = DEETS_SIM + data.GameName; | |||
Plugin.SetDiscordActivity(PresenceUtility.Activity, debug: "SimulationEnter-API-callback"); | |||
} | |||
public static void BuildEnter(object sender, GameEventArgs data) | |||
{ | |||
PresenceUtility.Activity.Details = DEETS_BUILD + data.GameName; | |||
Plugin.SetDiscordActivity(PresenceUtility.Activity, debug: "BuildEnter-API-callback"); | |||
} | |||
private static void CreateLobby() | |||
{ | |||
if (Plugin.DiscordRPC == null) return; | |||
Discord.LobbyManager lm = Plugin.DiscordRPC.GetLobbyManager(); | |||
Discord.LobbyTransaction lt = lm.GetLobbyCreateTransaction(); | |||
lt.SetMetadata("steamid", PresenceUtility.SteamId.ToString()); | |||
lt.SetType(Discord.LobbyType.Public); | |||
lt.SetCapacity(2); | |||
lm.CreateLobby(lt, SyncActivityLobby); | |||
PresenceUtility.IsActivityHost = true; | |||
} | |||
public static void ActivityJoin(string secret) | |||
{ | |||
Discord.LobbyManager lm = Plugin.DiscordRPC.GetLobbyManager(); | |||
if (PresenceUtility.Lobby.HasValue) | |||
{ | |||
lm.DeleteLobby(PresenceUtility.Lobby.Value.Id, NobodyCares); | |||
PresenceUtility.Lobby = null; | |||
} | |||
PresenceUtility.IsActivityHost = false; | |||
PresenceUtility.IsServerActive = false; | |||
lm.ConnectLobbyWithActivitySecret(secret, ConnectToGamecraftServerFromLobby); | |||
lastUserJoinRequest = 0; | |||
//Logging.MetaLog($"Received activity join"); | |||
} | |||
public static void ActivityJoinRequest(ref Discord.User user) | |||
{ | |||
lastUserJoinRequest = user.Id; | |||
Logging.MetaLog($"Received activity join request from {user.Username}"); | |||
} | |||
public static void ActivityInvite(Discord.ActivityActionType Type, ref Discord.User user, ref Discord.Activity activity) | |||
{ | |||
if (Type == Discord.ActivityActionType.Join) | |||
{ | |||
Logging.MetaLog($"Received invite to join {activity.Secrets.Join} from {user.Username}"); | |||
} | |||
} | |||
private static void SyncActivityLobby(Discord.Result result, ref Discord.Lobby lobby) | |||
{ | |||
Discord.LobbyManager lm = Plugin.DiscordRPC.GetLobbyManager(); | |||
PresenceUtility.Lobby = lobby; | |||
int lobbySize = lm.MemberCount(lobby.Id); | |||
Logging.MetaLog($"Lobby {lobby.Id} ({lobbySize}/{lobby.Capacity} players)"); | |||
// TODO sync lobby info to activity | |||
PresenceUtility.Activity.Secrets.Join = lm.GetLobbyActivitySecret(lobby.Id); | |||
Logging.MetaLog($"Secret is now {PresenceUtility.Activity.Secrets.Join}"); | |||
PresenceUtility.Activity.Party.Id = lobby.Id.ToString(); | |||
int currentSize = PresenceUtility.PlayerCount > 0 ? (int)PresenceUtility.PlayerCount : lobbySize; | |||
PresenceUtility.Activity.Party.Size.CurrentSize = currentSize; | |||
PresenceUtility.Activity.Party.Size.MaxSize = currentSize * 2; | |||
Plugin.SetDiscordActivity(PresenceUtility.Activity, debug: "SyncActivityLobby-Discord-callback"); | |||
} | |||
private static void ConnectToGamecraftServerFromLobby(Discord.Result result, ref Discord.Lobby lobby) | |||
{ | |||
SyncActivityLobby(result, ref lobby); | |||
Client client = new Client(); | |||
if (client.InMenu) | |||
{ | |||
PresenceUtility.IsConnecting = true; | |||
client.MyGames[0].EnterGame(); | |||
} | |||
else | |||
{ | |||
ConnectToGamecraftPeer(lobby); | |||
} | |||
} | |||
private static void ConnectToGamecraftPeer(Discord.Lobby lobby) | |||
{ | |||
Discord.LobbyManager lm = Plugin.DiscordRPC.GetLobbyManager(); | |||
string steamId = lm.GetLobbyMetadataValue(lobby.Id, "steamid"); | |||
Logging.MetaLog($"Joined lobby from request, now joining server hosted by {steamId}"); | |||
GamecraftModdingAPI.Commands.CommandBuilder.Builder() | |||
.Name("ConnectToCreativeServer") | |||
.FromExisting<string>() | |||
.Invoke(steamId); | |||
} | |||
public static void DiscordUserJoin(long lobbyId, long userId) | |||
{ | |||
if (PresenceUtility.IsActivityHost) | |||
{ | |||
if (!PresenceUtility.IsServerActive) | |||
{ | |||
Logging.MetaLog("First user connected -- starting server"); | |||
GamecraftModdingAPI.Commands.CommandBuilder.Builder() | |||
.Name("StartDefaultServer") | |||
.FromExisting() | |||
.Invoke(); | |||
PresenceUtility.IsServerActive = true; | |||
} | |||
} | |||
} | |||
public static void NobodyCares(Discord.Result result) | |||
{ | |||
} | |||
} | |||
} |
@@ -1,16 +1,9 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using GamecraftModdingAPI.Tasks; | |||
using GamecraftModdingAPI.Engines; | |||
using Svelto.ECS; | |||
using RobocraftX.Character; | |||
using RobocraftX.Physics; | |||
namespace GamecraftRPC.Engines | |||
{ | |||
class PlayerCountEngine : IApiEngine | |||
@@ -21,51 +14,40 @@ namespace GamecraftRPC.Engines | |||
public bool isRemovable => false; | |||
private Discord.Discord discordRPC = null; | |||
private bool Ok = false; | |||
public void Dispose() | |||
{ | |||
Ok = false; | |||
PresenceUtility.PlayerCount = 0; | |||
PresenceUtility.Activity.Party.Size.CurrentSize = 0; | |||
PresenceUtility.Activity.Party.Size.MaxSize = 0; | |||
PresenceUtility.Activity.Party.Id = ""; | |||
} | |||
public void Ready() | |||
{ | |||
Ok = true; | |||
Scheduler.Schedule(new Repeatable(updatePlayerCount, () => { return Ok; }, delay: 5f)); | |||
PresenceUtility.Activity.Party.Size.CurrentSize = 1; | |||
PresenceUtility.Activity.Party.Size.MaxSize = 1; | |||
PresenceUtility.Activity.Party.Id = "";//PresenceUtility.PartyId.ToString(); | |||
} | |||
private void updatePlayerCount() | |||
{ | |||
if (entitiesDB == null) return; | |||
uint count = 0; | |||
for (uint i = 0; i < CharacterExclusiveGroups.AllCharacters.count; i++) | |||
{ | |||
count += entitiesDB.Count<RigidBodyEntityStruct>(CharacterExclusiveGroups.AllCharacters[i]); | |||
} | |||
if ((int)count != PresenceUtility.PlayerCount && count > 0) | |||
uint count = GamecraftModdingAPI.Player.Count(); | |||
if (count != PresenceUtility.PlayerCount && count > 0) | |||
{ | |||
PresenceUtility.PlayerCount = (int)count; | |||
if (PresenceUtility.Lobby.HasValue && Plugin.DiscordRPC != null) | |||
{ | |||
Discord.LobbyManager lm = Plugin.DiscordRPC.GetLobbyManager(); | |||
Discord.LobbyTransaction lt = lm.GetLobbyUpdateTransaction(PresenceUtility.Lobby.Value.Id); | |||
lt.SetCapacity(count * 2); | |||
lm.UpdateLobby(PresenceUtility.Lobby.Value.Id, lt, CallbackUtility.NobodyCares); | |||
} | |||
PresenceUtility.PlayerCount = count; | |||
PresenceUtility.Activity.Party.Size.CurrentSize = (int)count; | |||
PresenceUtility.Activity.Party.Size.MaxSize = (int)count; | |||
Plugin.SetDiscordActivity(discordRPC, debug: "PlayerCountEngine-updatePlayerCount"); | |||
PresenceUtility.Activity.Party.Size.MaxSize = (int)count * 2; | |||
Plugin.SetDiscordActivity(debug: "PlayerCountEngine-updatePlayerCount"); | |||
#if DEBUG | |||
GamecraftModdingAPI.Utility.Logging.MetaLog($"Player Count: {count}"); | |||
GamecraftModdingAPI.Utility.Logging.MetaLog($"Updated Player Count: {count}"); | |||
#endif | |||
} | |||
} | |||
public PlayerCountEngine(Discord.Discord discordRPC) | |||
{ | |||
this.discordRPC = discordRPC; | |||
} | |||
} | |||
} |
@@ -1,29 +0,0 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using GamecraftModdingAPI.Events; | |||
using Svelto.ECS; | |||
using RobocraftX.Common; | |||
namespace GamecraftRPC.Events | |||
{ | |||
class EditPresenceHandler : SimpleEventHandlerEngine | |||
{ | |||
public static readonly string HandlerName = "GamecraftRPCEditPresenceEventHandler"; | |||
//private Discord.Discord discordRPC = null; | |||
public static void OnAdd(Discord.Discord discordRPC) | |||
{ | |||
Plugin.SetDiscordActivity(discordRPC, state: "In-Game", details: $"Editing {GameMode.SaveGameDetails.Name}", start: PresenceUtility.LastGameStart, matchSecret: PresenceUtility.GameSecret, joinSecret: PresenceUtility.GameSecret); | |||
} | |||
public EditPresenceHandler(Discord.Discord _discordRPC) : base((db) => { OnAdd(_discordRPC); }, (db) => { }, EventType.BuildSwitchedTo, HandlerName) | |||
{ | |||
//this.discordRPC = _discordRPC; | |||
} | |||
} | |||
} |
@@ -1,32 +0,0 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using GamecraftModdingAPI.Events; | |||
using Svelto.ECS; | |||
using RobocraftX.Common; | |||
using Discord; | |||
namespace GamecraftRPC.Events | |||
{ | |||
class GamePresenceHandler : SimpleEventHandlerEngine | |||
{ | |||
public static readonly string HandlerName = "GamecraftRPCGamePresenceEventHandler"; | |||
//private Discord.Discord discordRPC = null; | |||
public static void OnAdd(Discord.Discord discordRPC) | |||
{ | |||
PresenceUtility.LastGameStart = (int)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; | |||
Plugin.SetDiscordActivity(discordRPC, state: "In-Game", details: $"Editing {GameMode.SaveGameDetails.Name}", start: PresenceUtility.LastGameStart, partyId: PresenceUtility.PartyId.ToString(), partyCurrentSize: 1, partyMaxSize: 1, debug: "GamePresence-OnAdd"); | |||
} | |||
public GamePresenceHandler(Discord.Discord _discordRPC) : base((db) => { OnAdd(_discordRPC); }, (db) => { }, EventType.GameSwitchedTo, HandlerName) | |||
{ | |||
//this.discordRPC = _discordRPC; | |||
} | |||
} | |||
} |
@@ -1,28 +0,0 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using GamecraftModdingAPI.Events; | |||
using Svelto.ECS; | |||
namespace GamecraftRPC.Events | |||
{ | |||
class MenuPresenceHandler : SimpleEventHandlerEngine | |||
{ | |||
public static readonly string HandlerName = "GamecraftRPCMenuPresenceEventHandler"; | |||
//private Discord.Discord discordRPC = null; | |||
public static void OnAdd(Discord.Discord discordRPC) | |||
{ | |||
Plugin.SetDiscordActivity(discordRPC, state: "On menu screen", details: "", start: (int)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds); | |||
} | |||
public MenuPresenceHandler(Discord.Discord _discordRPC) : base((db) => { OnAdd(_discordRPC); }, (db) => { }, EventType.Menu, HandlerName) | |||
{ | |||
//this.discordRPC = _discordRPC; | |||
} | |||
} | |||
} |
@@ -1,29 +0,0 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using GamecraftModdingAPI.Events; | |||
using Svelto.ECS; | |||
using RobocraftX.Common; | |||
namespace GamecraftRPC.Events | |||
{ | |||
class SimulatePresenceHandler : SimpleEventHandlerEngine | |||
{ | |||
public static readonly string HandlerName = "GamecraftRPCSimulatePresenceEventHandler"; | |||
//private Discord.Discord discordRPC = null; | |||
public static void OnAdd(Discord.Discord discordRPC) | |||
{ | |||
Plugin.SetDiscordActivity(discordRPC, state: "In-Game", details: $"Playing {GameMode.SaveGameDetails.Name}", start: PresenceUtility.LastGameStart, matchSecret: PresenceUtility.GameSecret, joinSecret: PresenceUtility.GameSecret); | |||
} | |||
public SimulatePresenceHandler(Discord.Discord _discordRPC) : base((db) => { OnAdd(_discordRPC); }, (db) => { }, EventType.SimulationSwitchedTo, HandlerName) | |||
{ | |||
//this.discordRPC = _discordRPC; | |||
} | |||
} | |||
} |
@@ -3,7 +3,7 @@ | |||
<PropertyGroup> | |||
<TargetFramework>net472</TargetFramework> | |||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | |||
<Version>0.0.1</Version> | |||
<Version>1.0.0</Version> | |||
<Authors>Me</Authors> | |||
<PackageLicenseExpression>MIT</PackageLicenseExpression> | |||
<PackageProjectUrl>https://git.exmods.org/???/???</PackageProjectUrl> | |||
@@ -821,6 +821,12 @@ | |||
<HintPath>..\..\ref\Gamecraft_Data\Managed\VisualProfiler.dll</HintPath> | |||
</Reference> | |||
<Reference Include="Microsoft.CSharp" /> | |||
<Reference Include="GamecraftModdingAPI"> | |||
<HintPath>..\..\ref\Plugins\GamecraftModdingAPI.dll</HintPath> | |||
</Reference> | |||
<Reference Include="GamecraftModdingAPI"> | |||
<HintPath>..\..\ref\Plugins\GamecraftModdingAPI.dll</HintPath> | |||
</Reference> | |||
</ItemGroup> | |||
<!--End Dependencies--> | |||
@@ -3,7 +3,7 @@ using System.Reflection; | |||
//using Microsoft.Win32; | |||
using IllusionPlugin; | |||
using GamecraftModdingAPI.Events; | |||
using GamecraftModdingAPI.App; | |||
using GamecraftModdingAPI.Commands; | |||
using Discord; | |||
@@ -13,25 +13,36 @@ namespace GamecraftRPC | |||
{ | |||
public string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name; | |||
public string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString(); | |||
public string Version { get; } = | |||
#if DEBUG | |||
Assembly.GetExecutingAssembly().GetName().Version.ToString() + "alpha"; | |||
#else | |||
Assembly.GetExecutingAssembly().GetName().Version.ToString(); | |||
#endif | |||
private static readonly long CLIENT_ID = | |||
private const long CLIENT_ID = | |||
#if DEBUG | |||
692733325902872619; | |||
#else | |||
696732441012076605; | |||
696732441012076605; | |||
#endif | |||
private const LogLevel LOG_LEVEL = | |||
#if DEBUG | |||
LogLevel.Debug; | |||
#else | |||
LogLevel.Warn; | |||
#endif | |||
private Discord.Discord discordRPC; | |||
internal static Discord.Discord DiscordRPC; | |||
// called when Gamecraft shuts down | |||
public void OnApplicationQuit() | |||
{ | |||
// Shutdown this mod | |||
if (discordRPC != null) | |||
if (DiscordRPC != null) | |||
{ | |||
discordRPC.GetActivityManager().ClearActivity((result) => { GamecraftModdingAPI.Utility.Logging.LogDebug($"Cleared status: {result}"); }); | |||
discordRPC.Dispose(); | |||
DiscordRPC.GetActivityManager().ClearActivity((result) => { GamecraftModdingAPI.Utility.Logging.LogDebug($"Cleared status: {result}"); DiscordRPC.Dispose(); }); | |||
} | |||
GamecraftModdingAPI.Utility.Logging.LogDebug($"{Name} has shutdown"); | |||
@@ -57,62 +68,87 @@ namespace GamecraftRPC | |||
} | |||
if (isWineDetected) | |||
{ | |||
// check for or install fake Discord | |||
// info for getting this to work through Wine/Proton | |||
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--------------------------------"); | |||
} | |||
// Initialize this mod | |||
discordRPC = new Discord.Discord(CLIENT_ID, (UInt64)Discord.CreateFlags.Default); | |||
discordRPC.SetLogHook(LogLevel.Debug, (_, msg) => { GamecraftModdingAPI.Utility.Logging.MetaLog(msg); }); | |||
DiscordRPC = new Discord.Discord(CLIENT_ID, (UInt64)Discord.CreateFlags.NoRequireDiscord); | |||
DiscordRPC.SetLogHook(LOG_LEVEL, (_, msg) => { GamecraftModdingAPI.Utility.Logging.MetaLog(msg); }); | |||
//DiscordRPC.GetActivityManager().RegisterSteam(1078000); | |||
discordRPC.GetRelationshipManager().OnRefresh += () => | |||
{ | |||
discordRPC.GetRelationshipManager().Filter((ref Relationship r) => { return r.Presence.Status == Status.Online && r.Type == RelationshipType.Friend; }); | |||
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(); | |||
PresenceUtility.Users = new Relationship[discordRPC.GetRelationshipManager().Count()]; | |||
for (uint i = 0; i < discordRPC.GetRelationshipManager().Count(); i++) | |||
CommandBuilder.Builder() | |||
.Name(Name + "Info") | |||
.Description("Build information for the GamecraftRPC mod.") | |||
.Action(() => | |||
{ | |||
if (DiscordRPC != null) | |||
{ | |||
PresenceUtility.Users[i] = discordRPC.GetRelationshipManager().GetAt(i); | |||
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}"); | |||
} | |||
}; | |||
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 | |||
SimpleCustomCommandEngine listDiscordUsersCommand = new SimpleCustomCommandEngine( | |||
() => | |||
else | |||
{ | |||
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"); | |||
// register the command so the modding API knows about it | |||
CommandManager.AddCommand(rpcCommand); | |||
CommandManager.AddCommand(listDiscordUsersCommand); | |||
GamecraftModdingAPI.Utility.GameEngineManager.AddGameEngine(new Engines.PlayerCountEngine(discordRPC)); | |||
GamecraftModdingAPI.Utility.Logging.CommandLogError("Discord GameSDK functionality is unavailable. Please make sure Discord is open when launching Gamecraft."); | |||
} | |||
}) | |||
.Build(); | |||
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 | |||
@@ -121,12 +157,12 @@ namespace GamecraftRPC | |||
public void OnUpdate() // called once per rendered frame (frame update) | |||
{ | |||
if (discordRPC != null ) discordRPC.RunCallbacks(); | |||
if (DiscordRPC != null ) DiscordRPC.RunCallbacks(); | |||
} | |||
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 = "") | |||
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 = "") | |||
{ | |||
if (discordRPC == null) return; | |||
if (DiscordRPC == null) return; | |||
ref Activity activity = ref PresenceUtility.Activity; | |||
activity.Instance = instance; | |||
@@ -158,24 +194,26 @@ namespace GamecraftRPC | |||
activity.Secrets.Spectate = spectateSecret; | |||
} | |||
discordRPC.GetActivityManager().UpdateActivity(activity, result => | |||
DiscordRPC.GetActivityManager().UpdateActivity(activity, result => | |||
{ | |||
GamecraftModdingAPI.Utility.Logging.MetaLog($"Update Activity Result: {result} {debug}"); | |||
}); | |||
} | |||
public static void SetDiscordActivity(Discord.Discord discordRPC, Discord.Activity activity, string debug = "") | |||
public static void SetDiscordActivity(Discord.Activity activity, string debug = "") | |||
{ | |||
if (DiscordRPC == null) return; | |||
PresenceUtility.Activity = activity; | |||
discordRPC.GetActivityManager().UpdateActivity(PresenceUtility.Activity, result => | |||
DiscordRPC.GetActivityManager().UpdateActivity(PresenceUtility.Activity, result => | |||
{ | |||
GamecraftModdingAPI.Utility.Logging.MetaLog($"Update Activity Result: {result} {debug}"); | |||
}); | |||
} | |||
public static void SetDiscordActivity(Discord.Discord discordRPC, string debug = "") | |||
public static void SetDiscordActivity(string debug = "") | |||
{ | |||
discordRPC.GetActivityManager().UpdateActivity(PresenceUtility.Activity, result => | |||
if (DiscordRPC == null) return; | |||
DiscordRPC.GetActivityManager().UpdateActivity(PresenceUtility.Activity, result => | |||
{ | |||
GamecraftModdingAPI.Utility.Logging.MetaLog($"Update Activity Result: {result} {debug}"); | |||
}); | |||
@@ -13,27 +13,20 @@ namespace GamecraftRPC | |||
{ | |||
public static class PresenceUtility | |||
{ | |||
public static int LastGameStart = 0; | |||
public static ulong LastGameStart = 0; | |||
public static string GameSecret { | |||
get | |||
{ | |||
return _gameSecret == null? Steamworks.SteamClient.SteamId.AccountId.ToString() : _gameSecret; | |||
} | |||
set | |||
{ | |||
_gameSecret = value; | |||
} | |||
} | |||
public static uint PlayerCount = 1; | |||
private static string _gameSecret = null; | |||
public static Activity Activity; | |||
public static int PlayerCount = 1; | |||
public static ulong SteamId { get => Steamworks.SteamClient.SteamId.Value; } | |||
public static Activity Activity; | |||
public static Lobby? Lobby; | |||
public static bool IsActivityHost = false; | |||
public static uint PartyId { get => Steamworks.SteamClient.SteamId.AccountId; } | |||
public static bool IsServerActive = false; | |||
public static Relationship[] Users; | |||
public static bool IsConnecting = false; | |||
} | |||
} |