using System; using System.Collections; using InnerNet; using UnityEngine; using UnityEngine.SceneManagement; public class DiscordManager : DestroyableSingleton { private DiscordRpc.RichPresence presence = new DiscordRpc.RichPresence(); public DiscordRpc.DiscordUser joinRequest; private DateTime? StartTime; private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); public void Start() { if (DestroyableSingleton.Instance == this) { DiscordRpc.EventHandlers eventHandlers = default(DiscordRpc.EventHandlers); eventHandlers.errorCallback = (DiscordRpc.ErrorCallback)Delegate.Combine(eventHandlers.errorCallback, new DiscordRpc.ErrorCallback(this.HandleError)); eventHandlers.disconnectedCallback = (DiscordRpc.DisconnectedCallback)Delegate.Combine(eventHandlers.disconnectedCallback, new DiscordRpc.DisconnectedCallback(this.HandleError)); eventHandlers.joinCallback = (DiscordRpc.JoinCallback)Delegate.Combine(eventHandlers.joinCallback, new DiscordRpc.JoinCallback(this.HandleJoinRequest)); eventHandlers.requestCallback = (DiscordRpc.RequestCallback)Delegate.Combine(eventHandlers.requestCallback, new DiscordRpc.RequestCallback(this.HandleAutoJoin)); DiscordRpc.Initialize("477175586805252107", ref eventHandlers, true, null); this.SetInMenus(); SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode) { this.OnSceneChange(scene.name); }; } } private void HandleError(int errorCode, string message) { Debug.LogError(message ?? string.Format("No message: {0}", errorCode)); } private void OnSceneChange(string name) { if (name == "MatchMaking" || name == "MMOnline" || name == "MainMenu") { this.SetInMenus(); } } public void FixedUpdate() { DiscordRpc.RunCallbacks(); } public void SetInMenus() { this.ClearPresence(); this.StartTime = null; this.presence.state = "In Menus"; this.presence.largeImageKey = "icon"; DiscordRpc.UpdatePresence(this.presence); } public void SetPlayingGame() { if (this.StartTime == null) { this.StartTime = new DateTime?(DateTime.UtcNow); } this.presence.state = "In Game"; this.presence.details = "Playing"; this.presence.largeImageKey = "icon"; this.presence.startTimestamp = DiscordManager.ToUnixTime(this.StartTime.Value); DiscordRpc.UpdatePresence(this.presence); } public void SetHowToPlay() { this.ClearPresence(); this.presence.state = "In Freeplay"; this.presence.largeImageKey = "icon"; DiscordRpc.UpdatePresence(this.presence); } public void SetInLobbyClient() { if (this.StartTime == null) { this.StartTime = new DateTime?(DateTime.UtcNow); } this.ClearPresence(); this.presence.state = "In Lobby"; this.presence.largeImageKey = "icon"; this.presence.startTimestamp = DiscordManager.ToUnixTime(this.StartTime.Value); DiscordRpc.UpdatePresence(this.presence); } private void ClearPresence() { this.presence.startTimestamp = 0L; this.presence.details = null; this.presence.partyId = null; this.presence.matchSecret = null; this.presence.joinSecret = null; this.presence.partySize = 0; this.presence.partyMax = 0; } public void SetInLobbyHost(int numPlayers, int gameId) { if (this.StartTime == null) { this.StartTime = new DateTime?(DateTime.UtcNow); } string text = InnerNetClient.IntToGameName(gameId); this.presence.state = "In Lobby"; this.presence.details = "Hosting a game"; this.presence.partySize = numPlayers; this.presence.partyMax = 10; this.presence.smallImageKey = "icon"; this.presence.largeImageText = "Ask to play!"; this.presence.joinSecret = "join" + text; this.presence.matchSecret = "match" + text; this.presence.partyId = text; DiscordRpc.UpdatePresence(this.presence); } private void HandleAutoJoin(ref DiscordRpc.DiscordUser requestUser) { Debug.Log("Discord: request from " + requestUser.username); if (AmongUsClient.Instance.IsGameStarted) { this.RequestRespondNo(); return; } this.RequestRespondYes(); } private void HandleJoinRequest(string joinSecret) { if (!joinSecret.StartsWith("join")) { Debug.LogWarning("Invalid join secret: " + joinSecret); return; } if (!AmongUsClient.Instance) { Debug.LogWarning("Missing AmongUsClient"); return; } if (!DestroyableSingleton.InstanceExists) { Debug.LogWarning("Missing DiscordManager"); return; } if (AmongUsClient.Instance.mode != MatchMakerModes.None) { Debug.LogWarning("Already connected"); return; } AmongUsClient.Instance.GameMode = GameModes.OnlineGame; AmongUsClient.Instance.GameId = InnerNetClient.GameNameToInt(joinSecret.Substring(4)); AmongUsClient.Instance.SetEndpoint(DestroyableSingleton.Instance.OnlineNetAddress, 22023); AmongUsClient.Instance.MainMenuScene = "MMOnline"; AmongUsClient.Instance.OnlineScene = "OnlineGame"; DestroyableSingleton.Instance.StopAllCoroutines(); DestroyableSingleton.Instance.StartCoroutine(DestroyableSingleton.Instance.CoJoinGame()); } public IEnumerator CoJoinGame() { while (DataCollectScreen.Instance && DataCollectScreen.Instance.isActiveAndEnabled) { yield return null; } AmongUsClient.Instance.Connect(MatchMakerModes.Client); yield return AmongUsClient.Instance.WaitForConnectionOrFail(); if (AmongUsClient.Instance.ClientId < 0) { SceneManager.LoadScene("MMOnline"); } yield break; } public void RequestRespondYes() { DiscordRpc.Respond(this.joinRequest.userId, DiscordRpc.Reply.Yes); } public void RequestRespondNo() { Debug.Log("Discord: responding no to Ask to Join request"); DiscordRpc.Respond(this.joinRequest.userId, DiscordRpc.Reply.No); } public override void OnDestroy() { base.OnDestroy(); if (DestroyableSingleton.Instance == this) { DiscordRpc.Shutdown(); } } private static long ToUnixTime(DateTime time) { return (long)(time - DiscordManager.epoch).TotalSeconds; } }