Add Editor Rick Presence package

This commit is contained in:
BuyMyMojo 2023-02-28 02:50:32 +11:00
parent 2d2eb7d32f
commit 72a0daf486
40 changed files with 5141 additions and 0 deletions

8
Assets/ERP.meta Normal file
View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9dee676ed2a98d2439bd27dacba38c36
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 404dfd50bd7825149b4dc8d5c79ac837
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5126d240b3c42a449843d9abbc8fa0a8
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/ERP/Editor.meta Normal file
View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: dc28a777929b11d4db19be0bbf17326c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

203
Assets/ERP/Editor/ERP.cs Normal file
View file

@ -0,0 +1,203 @@
#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.SceneManagement;
using UnityEditor;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using ERP.Discord;
using System.Diagnostics;
using Debug = UnityEngine.Debug;
namespace ERP
{
[InitializeOnLoad]
public static class ERP
{
private const string applicationId = "509465267630374935";
private const string prefix = "<b>ERP</b>";
public static Discord.Discord discord { get; private set; }
public static string projectName { get; private set; }
public static string sceneName { get; private set; }
public static bool showSceneName = true;
public static bool showProjectName = true;
public static bool resetOnSceneChange = false;
public static bool debugMode = false;
public static bool EditorClosed = true;
public static long lastTimestamp = 0;
public static long lastSessionID = 0;
public static bool Errored = false;
public static bool Failed;
static ERP()
{
ERPSettings.GetSettings();
DelayStart();
}
public static async void DelayStart(int delay = 1000)
{
await Task.Delay(delay);
Init();
}
public static void Init()
{
if (Errored && lastSessionID == EditorAnalyticsSessionInfo.id)
{
if (debugMode)
LogWarning($"Error but in same session");
return;
}
if (!DiscordRunning())
{
LogWarning("Can't find Discord's Process");
Failed = true;
Errored = true;
ERPSettings.SaveSettings();
return;
}
try
{
discord = new Discord.Discord(long.Parse(applicationId), (long)CreateFlags.Default);
}
catch (Exception e)
{
if (debugMode)
LogWarning("Expected Error, retrying\n" + e.ToString());
if (!Failed)
DelayStart(2000);
Failed = true;
return;
}
if (!resetOnSceneChange || EditorAnalyticsSessionInfo.id != lastSessionID)
{
lastTimestamp = GetTimestamp();
ERPSettings.SaveSettings();
}
lastSessionID = EditorAnalyticsSessionInfo.id;
projectName = Application.productName;
sceneName = EditorSceneManager.GetActiveScene().name;
UpdateActivity();
EditorApplication.update += Update;
EditorSceneManager.sceneOpened += SceneOpened;
Log("Started!");
}
private static void SceneOpened(UnityEngine.SceneManagement.Scene scene, OpenSceneMode mode)
{
if (resetOnSceneChange)
lastTimestamp = GetTimestamp();
sceneName = EditorSceneManager.GetActiveScene().name;
UpdateActivity();
}
private static void Update()
{
if (discord != null)
discord.RunCallbacks();
}
public static void UpdateActivity()
{
Log("Updating Activity");
if (discord == null)
Init();
projectName = Application.productName;
sceneName = EditorSceneManager.GetActiveScene().name;
var activityManager = discord.GetActivityManager();
Activity activity = new Activity
{
State = showProjectName ? projectName : "",
Details = showSceneName ? sceneName : "",
Timestamps =
{
Start = lastTimestamp
},
Assets =
{
LargeImage = "logo",
LargeText = "Unity " + Application.unityVersion,
SmallImage = "marshmello",
SmallText = "ERP on Unity Asset Store",
},
};
activityManager.UpdateActivity(activity, result =>
{
if (result != Result.Ok)
LogError("Error from discord (" + result.ToString() + ")");
else
Log("Discord Result = " + result.ToString());
});
ERPSettings.SaveSettings();
}
public static long GetTimestamp()
{
if (!resetOnSceneChange)
{
TimeSpan timeSpan = TimeSpan.FromMilliseconds(EditorAnalyticsSessionInfo.elapsedTime);
long timestamp = DateTimeOffset.Now.Add(timeSpan).ToUnixTimeSeconds();
Log("Got time stamp: " + timestamp);
return timestamp;
}
long unixTimestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
Log("Got time stamp: " + unixTimestamp);
return unixTimestamp;
}
public static void Log(object message)
{
if (debugMode)
Debug.Log(prefix + ": " + message);
}
public static void LogWarning(object message)
{
if (debugMode)
Debug.LogWarning(prefix + ": " + message);
}
public static void LogError(object message)
{
Debug.LogError(prefix + ": " + message);
}
private static bool DiscordRunning()
{
Process[] processes = Process.GetProcessesByName("Discord");
if (processes.Length == 0)
{
processes = Process.GetProcessesByName("DiscordPTB");
if (processes.Length == 0)
{
processes = Process.GetProcessesByName("DiscordCanary");
}
}
if (debugMode)
{
for (int i = 0; i < processes.Length; i++)
{
Log($"({i}/{processes.Length - 1})Found Process {processes[i].ProcessName}");
}
}
return processes.Length != 0;
}
}
}
#endif

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 22bb83fad6b4e1e44afed775331903a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,77 @@
#if UNITY_EDITOR
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using UnityEngine;
namespace ERP
{
[Serializable]
public class ERPSettings
{
private static string path = Directory.GetCurrentDirectory() + "/.erp";
public bool showSceneName;
public bool showProjectName;
public bool resetOnSceneChange;
public bool debugMode;
public bool EditorClosed;
public long LastTimestamp;
public long LastSessionID;
public bool Errored;
public ERPSettings() { }
public ERPSettings(bool showSceneName, bool showProjectName, bool resetOnSceneChange, bool debugMode, bool editorClosed, long lastTimestamp, long lastSessionID, bool errored)
{
this.showSceneName = showSceneName;
this.showProjectName = showProjectName;
this.resetOnSceneChange = resetOnSceneChange;
this.debugMode = debugMode;
EditorClosed = editorClosed;
LastTimestamp = lastTimestamp;
LastSessionID = lastSessionID;
Errored = errored;
}
public static void GetSettings()
{
if (File.Exists(path))
{
XmlSerializer serializer = new XmlSerializer(typeof(ERPSettings));
FileStream stream = new FileStream(path, FileMode.Open);
ERPSettings settings = serializer.Deserialize(stream) as ERPSettings;
ApplySettings(settings);
stream.Close();
}
}
private static void ApplySettings(ERPSettings settings)
{
ERP.showSceneName = settings.showSceneName;
ERP.showProjectName = settings.showProjectName;
ERP.resetOnSceneChange = settings.resetOnSceneChange;
ERP.debugMode = settings.debugMode;
ERP.EditorClosed = settings.EditorClosed;
ERP.lastTimestamp = settings.LastTimestamp;
ERP.lastSessionID = settings.LastSessionID;
ERP.Errored = settings.Errored;
ERP.Log("Applied Settings from file");
}
public static void SaveSettings()
{
ERPSettings settings = new ERPSettings(ERP.showSceneName, ERP.showProjectName, ERP.resetOnSceneChange, ERP.debugMode, ERP.EditorClosed, ERP.lastTimestamp, ERP.lastSessionID, ERP.Errored);
XmlSerializer serializer = new XmlSerializer(typeof(ERPSettings));
var stream = new FileStream(path, FileMode.Create);
serializer.Serialize(stream, settings);
stream.Close();
ERP.Log("Saved Settings");
}
}
}
#endif

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f2d151e101b964240b0e57a8cf391c3c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,93 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace ERP
{
public class ERPWindow : EditorWindow
{
private static ERPWindow _window;
[MenuItem("Window/Editor Rich Presence")]
private static void Init()
{
_window = (ERPWindow)GetWindow(typeof(ERPWindow), false, "Editor Rich Presence");
_window.Show();
}
private void OnGUI()
{
if (ERP.discord == null && !ERP.Failed)
ERP.DelayStart();
if (ERP.Failed | ERP.Errored)
{
GUILayout.Label($"ERP Failed to start", EditorStyles.boldLabel);
if (GUILayout.Button("Retry"))
{
ERP.Errored = false;
ERP.Failed = false;
ERP.Init();
}
return;
}
GUILayout.Label("Editor Rich Presence", EditorStyles.boldLabel);
GUILayout.Label("Current Project: " + ERP.projectName);
GUILayout.Label("Current Scene: " + ERP.sceneName);
GUILayout.Label(string.Empty);
GUILayout.Label($"Scene Name Visible: {ERP.showSceneName}");
GUILayout.Label($"Project Name Visible: {ERP.showProjectName}");
GUILayout.Label($"Reset Timestap on scene change: {ERP.resetOnSceneChange}");
if (ToggleButton("Hide Scene name", "Show Scene name", ref ERP.showSceneName))
{
ERP.UpdateActivity();
ERPSettings.SaveSettings();
}
if (ToggleButton("Hide Project name", "Show Project name", ref ERP.showProjectName))
{
ERP.UpdateActivity();
ERPSettings.SaveSettings();
}
if (ToggleButton("Don't reset timestap on scene change", "Reset timestap on scene change", ref ERP.resetOnSceneChange))
{
ERP.UpdateActivity();
ERPSettings.SaveSettings();
}
if (ToggleButton("Disable Debug Mode", "Enable Debug Mode", ref ERP.debugMode))
{
ERPSettings.SaveSettings();
}
GUILayout.Label(string.Empty);
GUILayout.BeginHorizontal();
if (GUILayout.Button("GitHub Repository"))
{
Application.OpenURL("https://github.com/MarshMello0/Editor-Rich-Presence");
}
if (GUILayout.Button("Asset Store Page"))
{
Application.OpenURL("https://assetstore.unity.com/packages/tools/utilities/editor-rich-presence-178736");
}
GUILayout.EndHorizontal();
}
private bool ToggleButton(string trueText, string falseText, ref bool value)
{
if (value && GUILayout.Button(trueText))
{
value = false;
return true;
}
else if (!value && GUILayout.Button(falseText))
{
value = true;
return true;
}
return false;
}
}
}
#endif

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 59dfeb4cf2bfe5d40bc44adef75bc71c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f2f9d30f2a57de249b316cd189be4165
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ce6f73dd7415ecd4aaa685f854de777e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,12 @@
using System;
namespace ERP.Discord
{
public partial class ActivityManager
{
public void RegisterCommand()
{
RegisterCommand(null);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1bbf7726d48d669488894791799286e0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,9 @@
using System;
namespace ERP.Discord
{
static class Constants
{
public const string DllName = "discord_game_sdk";
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2b81933783bc3c2448c5d19141baea99
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e67fa7bdd3cf6a34e9ef9b85b66e7f0a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,53 @@
using System;
using System.Runtime.InteropServices;
#if UNITY_EDITOR || UNITY_STANDALONE
using UnityEngine;
#endif
namespace ERP.Discord
{
public partial struct ImageHandle
{
static public ImageHandle User(Int64 id)
{
return User(id, 128);
}
static public ImageHandle User(Int64 id, UInt32 size)
{
return new ImageHandle
{
Type = ImageType.User,
Id = id,
Size = size,
};
}
}
public partial class ImageManager
{
public void Fetch(ImageHandle handle, FetchHandler callback)
{
Fetch(handle, false, callback);
}
public byte[] GetData(ImageHandle handle)
{
var dimensions = GetDimensions(handle);
var data = new byte[dimensions.Width * dimensions.Height * 4];
GetData(handle, data);
return data;
}
#if UNITY_EDITOR || UNITY_STANDALONE
public Texture2D GetTexture(ImageHandle handle)
{
var dimensions = GetDimensions(handle);
var texture = new Texture2D((int)dimensions.Width, (int)dimensions.Height, TextureFormat.RGBA32, false, true);
texture.LoadRawTextureData(GetData(handle));
texture.Apply();
return texture;
}
#endif
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a07e195a8d9505745a5ffd0ba2bb01e2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,26 @@
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
namespace ERP.Discord
{
public partial class LobbyManager
{
public IEnumerable<User> GetMemberUsers(Int64 lobbyID)
{
var memberCount = MemberCount(lobbyID);
var members = new List<User>();
for (var i = 0; i < memberCount; i++)
{
members.Add(GetMemberUser(lobbyID, GetMemberUserId(lobbyID, i)));
}
return members;
}
public void SendLobbyMessage(Int64 lobbyID, string data, SendLobbyMessageHandler handler)
{
SendLobbyMessage(lobbyID, Encoding.UTF8.GetBytes(data), handler);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d033386aa12b5434890ecd02dfb2486d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ERP.Discord
{
public partial class StorageManager
{
public IEnumerable<FileStat> Files()
{
var fileCount = Count();
var files = new List<FileStat>();
for (var i = 0; i < fileCount; i++)
{
files.Add(StatAt(i));
}
return files;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f117fb9d4ace5c34b8fd8cc721cca726
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,32 @@
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
namespace ERP.Discord
{
public partial class StoreManager
{
public IEnumerable<Entitlement> GetEntitlements()
{
var count = CountEntitlements();
var entitlements = new List<Entitlement>();
for (var i = 0; i < count; i++)
{
entitlements.Add(GetEntitlementAt(i));
}
return entitlements;
}
public IEnumerable<Sku> GetSkus()
{
var count = CountSkus();
var skus = new List<Sku>();
for (var i = 0; i < count; i++)
{
skus.Add(GetSkuAt(i));
}
return skus;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 88ddef408c40a034fb598224080b36e7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6cf4f21b3c4cef54ebba8baf75884671
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View file

@ -0,0 +1,80 @@
fileFormatVersion: 2
guid: 7cc1a84a3fca5524cb7bcb73f7c1aabd
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: x86
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: x86_64
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 050e0629584e2d54cbf84f0e0ed91c69
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View file

@ -0,0 +1,80 @@
fileFormatVersion: 2
guid: 1727ecd695a502444b36efd0e5dacd34
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: x86_64
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: x86_64
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,13 @@
{
"name": "com.ben-w.erp",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5f94b3bb5603bb5489cba7d6df77444c
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

16
Assets/ERP/README.md Normal file
View file

@ -0,0 +1,16 @@
# Editor Rich Presence
## A Discord Rich Presence for the Unity editor
![Unity Asset Store Image](https://assetstorev1-prd-cdn.unity3d.com/key-image/d514aa2a-ca58-4a63-9ae0-b27239e1f8d8.webp)
Show off what you're working on in unity with Editor Rich Presence on discord.
![Example Image](https://assetstorev1-prd-cdn.unity3d.com/package-screenshot/d7c67997-ea03-4881-ae7c-41f15296513a.webp)
## Download
You can now download Editor Rich Presence from the Unity Asset store from [here](https://assetstore.unity.com/packages/tools/utilities/editor-rich-presence-178736)!
## Warning
This package makes a `.erp` file in the root of the project if you don't want this to be shared in a git repo add it to your ignore list.

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7236ea587e9df0b4eb4779968f15f94f
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

17
Assets/ERP/package.json Normal file
View file

@ -0,0 +1,17 @@
{
"name": "com.ben-w.erp",
"version": "3.1.2",
"displayName": "Editor Rich Presence",
"description": "Show off what you're working on in Unity with Editor Rich Presence on discord.\n\nEditor Rich Presence uses Discords GameSDK to display your project name, current active scene name and session time on your Discord profile. These can be disabled on a per-project basis.",
"keywords": [
"Discord",
"Rich Presense",
"Editor Tool"
],
"author": {
"name": "Ben Wilson",
"email": "me@ben-w.com",
"url": "https://github.com/MarshMello0/Editor-Rich-Presence"
},
"type": "tool"
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d6c6f38634ca76649b31df0c339545c0
PackageManifestImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: