Decompiled source of DiscordHook v0.1.2

BepInEx/plugins/DiscordHook/glitchapotamus.discordhook.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DiscordHook.Utils;
using DiscordHook.Utils.Discord;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using REPOLib.Commands;
using Steamworks;
using Steamworks.Data;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Autodesk.Fbx")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("FbxBuildTestAssets")]
[assembly: IgnoresAccessChecksTo("Klattersynth")]
[assembly: IgnoresAccessChecksTo("Photon3Unity3D")]
[assembly: IgnoresAccessChecksTo("PhotonChat")]
[assembly: IgnoresAccessChecksTo("PhotonRealtime")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.API")]
[assembly: IgnoresAccessChecksTo("PhotonVoice")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")]
[assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime")]
[assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime.Public")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Utilities")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Formats.Fbx.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Antlr3.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Core")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Flow")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.State")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("GlitchApotamus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.2.0")]
[assembly: AssemblyInformationalVersion("0.1.2+3ac3a3bf7d2943990fd8a0881813c2c13252e087")]
[assembly: AssemblyProduct("DiscordHook")]
[assembly: AssemblyTitle("glitchapotamus.discordhook")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DiscordHook
{
	[BepInPlugin("glitchapotamus.discordhook", "DiscordHook", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal sealed class DiscordHook : BaseUnityPlugin
	{
		internal static DiscordHook Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		internal static DiscordHookConfig? BoundConfig { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			BoundConfig = new DiscordHookConfig(((BaseUnityPlugin)this).Config);
			string value = BoundConfig.WebhookUrl.Value;
			if (value == string.Empty || !Uri.TryCreate(value, UriKind.Absolute, out Uri result) || result.Scheme != Uri.UriSchemeHttps || !value.Contains("discord.com/api/webhooks/"))
			{
				Logger.LogError((object)("Please set a valid Webhook URL in the config file." + Environment.NewLine + "The plugin will not load until a valid Webhook URL is set." + Environment.NewLine + "You can find the config file in the BepInEx/config folder." + Environment.NewLine + "Disabling the plugin!"));
			}
			else
			{
				((Component)this).gameObject.transform.parent = null;
				((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
				Patch();
				Logger.LogInfo((object)"DiscordHook v0.1.2 has loaded!");
			}
		}

		internal void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val2 = (Harmony = new Harmony("glitchapotamus.discordhook"));
			}
			Harmony.PatchAll();
		}

		internal void Unpatch()
		{
			Harmony harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
		}

		private void OnDestroy()
		{
			Unpatch();
			Logger.LogInfo((object)"DiscordHook v0.1.2 has been unloaded!");
		}
	}
	internal static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "glitchapotamus.discordhook";

		public const string PLUGIN_NAME = "DiscordHook";

		public const string PLUGIN_VERSION = "0.1.2";

		public const string PLUGIN_AUTHOR = "GlitchApotamus";
	}
}
namespace DiscordHook.Utils
{
	internal class DiscordHookConfig
	{
		public readonly ConfigEntry<bool> SendAsEmbed;

		public readonly ConfigEntry<string> WebhookUrl;

		public readonly ConfigEntry<string> WebhookUsername;

		public readonly ConfigEntry<string> WebhookAvatarUrl;

		public readonly ConfigEntry<string> WebhookImageUrl;

		public DiscordHookConfig(ConfigFile cfg)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			cfg.SaveOnConfigSet = false;
			SendAsEmbed = cfg.Bind<bool>("Settings", "SendAsEmbed", false, new ConfigDescription("Whether to send this message as an embed.", (AcceptableValueBase)null, Array.Empty<object>()));
			WebhookUrl = cfg.Bind<string>("Settings", "WebhookUrl", string.Empty, new ConfigDescription("Where to send content to in discord. Should look like this: https://discord.com/api/webhooks/1349793699168518255/WLPhkQcHHH0DoFfVpmL-feS4TsfnfgiChEMJMWOXnVnfPtJgN8-mq7-dvx", (AcceptableValueBase)null, Array.Empty<object>()));
			WebhookUsername = cfg.Bind<string>("Settings", "WebhookUsername", "Webhook Bot", new ConfigDescription("The username that will be displayed when the webhook sends a message.", (AcceptableValueBase)null, Array.Empty<object>()));
			WebhookAvatarUrl = cfg.Bind<string>("Settings", "WebhookAvatarUrl", "https://example.com/avatar.png", new ConfigDescription("The avatar URL that will be displayed when the webhook sends a message. Don't want an image? Just leave it blank and discord will give a random default.", (AcceptableValueBase)null, Array.Empty<object>()));
			WebhookImageUrl = cfg.Bind<string>("Settings", "WebhookImageUrl", "https://shared.cloudflare.steamstatic.com/store_item_assets/steam/apps/3241660/extras/00_title_repo.png?t=1740578354", new ConfigDescription("The image URL that will be displayed when the webhook sends a message. Don't want an image? Just leave it blank.", (AcceptableValueBase)null, Array.Empty<object>()));
			ClearOrphanedEntries(cfg);
			cfg.Save();
			cfg.SaveOnConfigSet = true;
		}

		private static void ClearOrphanedEntries(ConfigFile cfg)
		{
			PropertyInfo propertyInfo = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries");
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)propertyInfo.GetValue(cfg);
			dictionary.Clear();
		}
	}
}
namespace DiscordHook.Utils.Discord
{
	public class DiscordEmbed
	{
		[JsonProperty("title")]
		public string? Title { get; set; }

		[JsonProperty("description")]
		public string? Description { get; set; }

		[JsonProperty("url")]
		public string? Url { get; set; }

		[JsonProperty("color")]
		public int? Color { get; set; }

		[JsonProperty("timestamp")]
		public string? Timestamp { get; set; }

		[JsonProperty("footer")]
		public EmbedFooter? Footer { get; set; }

		[JsonProperty("image")]
		public EmbedImage? Image { get; set; }

		[JsonProperty("thumbnail")]
		public EmbedThumbnail? Thumbnail { get; set; }

		[JsonProperty("author")]
		public EmbedAuthor? Author { get; set; }

		[JsonProperty("fields")]
		public List<EmbedField>? Fields { get; set; } = new List<EmbedField>();


		public DiscordEmbed()
		{
		}

		public DiscordEmbed(string title, string description, int color)
		{
			Title = title;
			Description = description;
			Color = color;
		}
	}
	public class EmbedFooter
	{
		[JsonProperty("text")]
		public string? Text { get; set; }

		[JsonProperty("icon_url")]
		public string? IconUrl { get; set; }
	}
	public class EmbedImage
	{
		[JsonProperty("url")]
		public string? Url { get; set; }
	}
	public class EmbedThumbnail
	{
		[JsonProperty("url")]
		public string? Url { get; set; }
	}
	public class EmbedAuthor
	{
		[JsonProperty("name")]
		public string? Name { get; set; }

		[JsonProperty("url")]
		public string? Url { get; set; }

		[JsonProperty("icon_url")]
		public string? IconUrl { get; set; }
	}
	public class EmbedField
	{
		[JsonProperty("name")]
		public string? Name { get; set; }

		[JsonProperty("value")]
		public string? Value { get; set; }

		[JsonProperty("inline")]
		public bool Inline { get; set; }
	}
	internal sealed class DiscordMessage
	{
		private static readonly DiscordHookConfig? BoundConfig = DiscordHook.BoundConfig;

		internal void PostDiscordMessage(string message, DiscordEmbed embed)
		{
			string username = BoundConfig?.WebhookUsername.Value;
			string avatarUrl = BoundConfig?.WebhookAvatarUrl.Value;
			string imageUrl = BoundConfig?.WebhookImageUrl.Value;
			DiscordHookConfig? boundConfig = BoundConfig;
			if (boundConfig != null && boundConfig.SendAsEmbed.Value && embed != null)
			{
				((MonoBehaviour)DiscordHook.Instance).StartCoroutine(new DiscordWebhook().SendWebhook(new DiscordWebhook.IDiscordWebhook
				{
					Username = username,
					AvatarUrl = avatarUrl,
					ImageUrl = imageUrl,
					Embed = embed
				}));
			}
			else
			{
				((MonoBehaviour)DiscordHook.Instance).StartCoroutine(new DiscordWebhook().SendWebhook(new DiscordWebhook.IDiscordWebhook
				{
					Username = username,
					AvatarUrl = avatarUrl,
					ImageUrl = imageUrl,
					Message = message
				}));
			}
		}
	}
	public class DiscordWebhook : MonoBehaviour
	{
		public class IDiscordWebhook
		{
			public string? Username { get; set; } = string.Empty;


			public string? AvatarUrl { get; set; } = string.Empty;


			public DiscordEmbed? Embed { get; set; }

			public string? Message { get; set; } = string.Empty;


			public string? ImageUrl { get; set; } = string.Empty;

		}

		[CompilerGenerated]
		private sealed class <SendWebhook>d__0 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public IDiscordWebhook webhook;

			private UnityWebRequest <request>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SendWebhook>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<request>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0190: Unknown result type (might be due to invalid IL or missing references)
				//IL_0196: Invalid comparison between Unknown and I4
				//IL_011d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: Expected O, but got Unknown
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_0141: Expected O, but got Unknown
				//IL_0147: Unknown result type (might be due to invalid IL or missing references)
				//IL_0151: Expected O, but got Unknown
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
					{
						<>1__state = -1;
						if (string.IsNullOrEmpty(webhook.Message) && webhook.Embed == null)
						{
							Debug.LogError((object)"Error: Either a message or an embed must be provided.");
							result = false;
							break;
						}
						if (webhook.Embed != null)
						{
							DiscordEmbed embed = webhook.Embed;
							if (embed.Image == null)
							{
								EmbedImage embedImage2 = (embed.Image = new EmbedImage());
							}
							webhook.Embed.Image.Url = webhook.ImageUrl;
						}
						var anon = new
						{
							username = webhook.Username,
							avatar_url = webhook.AvatarUrl,
							content = webhook.Message,
							embeds = ((webhook.Embed == null) ? null : new DiscordEmbed[1] { webhook.Embed })
						};
						string s = JsonConvert.SerializeObject((object)anon, (Formatting)1);
						byte[] bytes = Encoding.UTF8.GetBytes(s);
						<request>5__2 = new UnityWebRequest(DiscordHook.BoundConfig?.WebhookUrl.Value, "POST");
						<>1__state = -3;
						<request>5__2.uploadHandler = (UploadHandler)new UploadHandlerRaw(bytes);
						<request>5__2.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
						<request>5__2.SetRequestHeader("Content-Type", "application/json");
						<>2__current = <request>5__2.SendWebRequest();
						<>1__state = 1;
						result = true;
						break;
					}
					case 1:
						<>1__state = -3;
						if ((int)<request>5__2.result != 1)
						{
							Debug.LogError((object)("Discord Hook Error: " + <request>5__2.downloadHandler.text));
						}
						result = false;
						<>m__Finally1();
						break;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<request>5__2 != null)
				{
					((IDisposable)<request>5__2).Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[IteratorStateMachine(typeof(<SendWebhook>d__0))]
		public IEnumerator SendWebhook(IDiscordWebhook webhook)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SendWebhook>d__0(0)
			{
				webhook = webhook
			};
		}
	}
}
namespace DiscordHook.Stats
{
	public static class Tracker
	{
		private static ManualLogSource _logger = DiscordHook.Logger;

		public static int TotalDeaths { get; set; } = 0;


		public static int TotalRevives { get; set; } = 0;


		public static int TotalKills { get; set; } = 0;


		public static int TotalDamage { get; set; } = 0;


		public static int TotalDamageTaken { get; set; } = 0;


		public static int TotalDamageDealt { get; set; } = 0;


		public static List<PlayerAvatar> Players { get; set; } = GameDirector.instance.PlayerList;


		public static void IncrementDeaths()
		{
			_logger.LogInfo((object)$"Total Deaths: {TotalDeaths}");
		}

		public static void IncrementRevives()
		{
			_logger.LogInfo((object)$"Total Revives: {TotalRevives}");
		}

		public static void IncrementKills()
		{
			_logger.LogInfo((object)$"Total Kills: {TotalKills}");
		}

		public static void IncrementDamage(int damage)
		{
			TotalDamage += damage;
			_logger.LogInfo((object)$"Total Damage: {TotalDamage}");
		}

		public static void IncrementDamageTaken(int damage)
		{
			TotalDamageTaken += damage;
			_logger.LogInfo((object)$"Total Damage Taken: {TotalDamageTaken}");
		}

		public static void IncrementDamageDealt(int damage)
		{
			TotalDamageDealt += damage;
			_logger.LogInfo((object)$"Total Damage Dealt: {TotalDamageDealt}");
		}
	}
}
namespace DiscordHook.Patches
{
	[HarmonyPatch(typeof(SteamManager))]
	public class SteamManagerPatches
	{
		private static Lobby currentLobby;

		private static bool lobbyClosed;

		private static bool awakeCalled;

		private static string GetLobbyLink(SteamId lobbyId, SteamId ownerId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			AppId appId = SteamClient.AppId;
			return $"https://steamuri.com/joinlobby/{appId}/{lobbyId}/{ownerId}";
		}

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		public static void OnAwake()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			currentLobby = SteamManager.instance.currentLobby;
			if (!awakeCalled)
			{
				new DiscordMessage().PostDiscordMessage(SteamClient.Name + " has started playing REPO!", new DiscordEmbed
				{
					Description = SteamClient.Name + " has started playing REPO!",
					Color = 65280
				});
				awakeCalled = true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("LockLobby")]
		public static void OnLobbyLocked()
		{
			new DiscordMessage().PostDiscordMessage("The lobby is now locked.", new DiscordEmbed
			{
				Description = "The lobby is now locked.",
				Color = 16711680
			});
		}

		[HarmonyPostfix]
		[HarmonyPatch("UnlockLobby")]
		public static void OnLobbyUnlocked()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			Friend owner = ((Lobby)(ref currentLobby)).Owner;
			int levelsCompleted = RunManager.instance.levelsCompleted;
			new DiscordMessage().PostDiscordMessage($"[{((Friend)(ref owner)).Name}'s Lobby]({GetLobbyLink(((Lobby)(ref currentLobby)).Id, owner.Id)}) is now open. We will be moving to level number {levelsCompleted + 1}!", new DiscordEmbed
			{
				Description = $"[{((Friend)(ref owner)).Name}'s Lobby]({GetLobbyLink(((Lobby)(ref currentLobby)).Id, owner.Id)}) is now open. We will be moving to level number {levelsCompleted + 1}!",
				Color = 65280
			});
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnLobbyMemberJoined")]
		public static void OnLobbyJoined(Lobby _lobby, Friend _friend)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			string name = ((Friend)(ref _friend)).Name;
			Friend owner = ((Lobby)(ref _lobby)).Owner;
			if (!(name == ((Friend)(ref owner)).Name))
			{
				DiscordMessage discordMessage = new DiscordMessage();
				object[] obj = new object[4]
				{
					((Friend)(ref _friend)).Name,
					null,
					null,
					null
				};
				owner = ((Lobby)(ref _lobby)).Owner;
				obj[1] = ((Friend)(ref owner)).Name;
				obj[2] = ((Lobby)(ref _lobby)).MemberCount;
				obj[3] = ((Lobby)(ref _lobby)).MaxMembers;
				string message = string.Format("{0} has joined {1}'s lobby. Lobby count: {2}/{3}", obj);
				DiscordEmbed discordEmbed = new DiscordEmbed();
				object[] obj2 = new object[4]
				{
					((Friend)(ref _friend)).Name,
					null,
					null,
					null
				};
				owner = ((Lobby)(ref _lobby)).Owner;
				obj2[1] = ((Friend)(ref owner)).Name;
				obj2[2] = ((Lobby)(ref _lobby)).MemberCount;
				obj2[3] = ((Lobby)(ref _lobby)).MaxMembers;
				discordEmbed.Description = string.Format("{0} has joined {1}'s lobby. Lobby count: {2}/{3}", obj2);
				discordEmbed.Color = 65280;
				discordMessage.PostDiscordMessage(message, discordEmbed);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnLobbyMemberLeft")]
		public static void OnLobbyLeft(Lobby _lobby, Friend _friend)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			string name = ((Friend)(ref _friend)).Name;
			Friend owner = ((Lobby)(ref _lobby)).Owner;
			if (!(name == ((Friend)(ref owner)).Name))
			{
				DiscordMessage discordMessage = new DiscordMessage();
				object[] obj = new object[4]
				{
					((Friend)(ref _friend)).Name,
					null,
					null,
					null
				};
				owner = ((Lobby)(ref _lobby)).Owner;
				obj[1] = ((Friend)(ref owner)).Name;
				obj[2] = ((Lobby)(ref _lobby)).MemberCount;
				obj[3] = ((Lobby)(ref _lobby)).MaxMembers;
				string message = string.Format("{0} has left {1}'s Lobby. Lobby count: {2}/{3}", obj);
				DiscordEmbed discordEmbed = new DiscordEmbed();
				object[] obj2 = new object[4]
				{
					((Friend)(ref _friend)).Name,
					null,
					null,
					null
				};
				owner = ((Lobby)(ref _lobby)).Owner;
				obj2[1] = ((Friend)(ref owner)).Name;
				obj2[2] = ((Lobby)(ref _lobby)).MemberCount;
				obj2[3] = ((Lobby)(ref _lobby)).MaxMembers;
				discordEmbed.Description = string.Format("{0} has left {1}'s Lobby. Lobby count: {2}/{3}", obj2);
				discordEmbed.Color = 16711680;
				discordMessage.PostDiscordMessage(message, discordEmbed);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnDestroy")]
		public static void OnDestroy()
		{
			if (RunManager.instance.levelsCompleted != 0 && !lobbyClosed)
			{
				new DiscordMessage().PostDiscordMessage("The Lobby has taken a wild turn into CrashMania!", new DiscordEmbed
				{
					Description = "The Lobby has taken a wild turn into CrashMania!",
					Color = 16711680
				});
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("LeaveLobby")]
		public static void OnLeaveLobby()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			Lobby val = SteamManager.instance.currentLobby;
			Friend owner = ((Lobby)(ref val)).Owner;
			if (SteamClient.Name == ((Friend)(ref owner)).Name)
			{
				new DiscordMessage().PostDiscordMessage(SteamClient.Name + " has closed their lobby.", new DiscordEmbed
				{
					Description = SteamClient.Name + " has closed their lobby.",
					Color = 16711680
				});
				lobbyClosed = true;
			}
			else
			{
				new DiscordMessage().PostDiscordMessage(SteamClient.Name + " has left " + ((Friend)(ref owner)).Name + "'s Lobby.", new DiscordEmbed
				{
					Description = SteamClient.Name + " has left " + ((Friend)(ref owner)).Name + "'s Lobby.",
					Color = 16711680
				});
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnLobbyEntered")]
		public static void OnJoinLobby(Lobby _lobby)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			Friend owner = ((Lobby)(ref _lobby)).Owner;
			if (!(((Friend)(ref owner)).Name == SteamClient.Name))
			{
				DiscordMessage discordMessage = new DiscordMessage();
				string name = SteamClient.Name;
				owner = ((Lobby)(ref _lobby)).Owner;
				string message = name + " has joined " + ((Friend)(ref owner)).Name + "'s lobby.";
				DiscordEmbed discordEmbed = new DiscordEmbed();
				string name2 = SteamClient.Name;
				owner = ((Lobby)(ref _lobby)).Owner;
				discordEmbed.Description = name2 + " has joined " + ((Friend)(ref owner)).Name + "'s lobby.";
				discordEmbed.Color = 65280;
				discordMessage.PostDiscordMessage(message, discordEmbed);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("HostLobby")]
		public static void OnHostLobby()
		{
			new DiscordMessage().PostDiscordMessage(SteamClient.Name + " is now hosting a lobby, please stand by for the invite link....", new DiscordEmbed
			{
				Description = SteamClient.Name + " is now hosting a lobby, please stand by for the invite link....",
				Color = 65280
			});
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar))]
	public static class PlayerAvatarPatches
	{
		private static PlayerAvatar Player { get; set; }

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void Awake_Postfix()
		{
			Player = PlayerAvatar.instance;
		}

		[HarmonyPatch("PlayerDeathRPC")]
		[HarmonyPrefix]
		private static void PlayerDeath_Prefix(PlayerAvatar __instance)
		{
			Debug.Log((object)("Player " + __instance.playerName + " is about to die."));
		}

		[HarmonyPatch("PlayerDeathRPC")]
		[HarmonyPostfix]
		private static void PlayerDeath_Postfix(PlayerAvatar __instance)
		{
			Debug.Log((object)("Player " + __instance.playerName + " has died."));
		}

		[HarmonyPatch("ReviveRPC")]
		[HarmonyPrefix]
		private static void PlayerRevive_Prefix(PlayerAvatar __instance)
		{
			Debug.Log((object)("Player " + __instance.playerName + " is about to be revived."));
		}

		[HarmonyPatch("ReviveRPC")]
		[HarmonyPostfix]
		private static void PlayerRevive_Postfix(PlayerAvatar __instance)
		{
			Debug.Log((object)("Player " + __instance.playerName + " has been revived."));
		}
	}
}
namespace DiscordHook.Commands
{
	public static class Test
	{
		[CommandInitializer]
		public static void Initialize()
		{
			DiscordHook.Logger.LogInfo((object)"Test Command has been initialized.");
		}

		[CommandExecution("Test", "Description of what the command does and how to use it.", true, false)]
		[CommandAlias("test")]
		[CommandAlias("t")]
		public static void Execute(string args)
		{
			DiscordHook.Logger.LogInfo((object)("TestCommand executed with arguments: " + args));
			new DiscordMessage().PostDiscordMessage("TestCommand executed with arguments: " + args, new DiscordEmbed
			{
				Description = "TestCommand executed with arguments: " + args,
				Color = 65280
			});
		}
	}
}