Decompiled source of Repo Chat v1.0.0

BepInEx/plugins/RepoChat/RepoDiscordBridge.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Rao")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RepoDiscordBridge")]
[assembly: AssemblyTitle("RepoDiscordBridge")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 RepoDiscordBridge
{
	public sealed class BridgeChatUI : MonoBehaviour
	{
		private sealed class NotificationEntry
		{
			public GameObject Object = null;

			public float Remaining;
		}

		private static int _chatClosedFrame = -1;

		private const KeyCode ToggleKey = (KeyCode)287;

		private const int MaxMessages = 100;

		private const float NotificationOffsetX = 90f;

		private const float NotificationOffsetY = 195f;

		private const float NotificationDurationDefault = 5f;

		private static readonly Color PanelColor = new Color(0.055f, 0.065f, 0.08f, 0.94f);

		private static readonly Color HeaderColor = new Color(0.035f, 0.045f, 0.06f, 0.98f);

		private static readonly Color BorderColor = new Color(0.32f, 0.36f, 0.43f, 0.9f);

		private static readonly Color DiscordColor = new Color(0.4f, 0.62f, 1f, 1f);

		private static readonly Color RepoColor = new Color(0.25f, 0.88f, 0.58f, 1f);

		private static readonly Color MainTextColor = new Color(0.93f, 0.94f, 0.97f, 1f);

		private static readonly Color MutedTextColor = new Color(0.58f, 0.62f, 0.69f, 1f);

		private readonly List<GameObject> _messageRows = new List<GameObject>();

		private Canvas _canvas = null;

		private RectTransform _messageList = null;

		private ScrollRect _scrollRect = null;

		private GameObject _chatPanel = null;

		private GameObject _settingsPanel = null;

		private RectTransform _notificationRoot = null;

		private readonly List<NotificationEntry> _notifications = new List<NotificationEntry>();

		private InputField _input = null;

		private Text _connectionTitle = null;

		private Text _emptyChatHint = null;

		private Button _sendButton = null;

		private bool _accessBlocked;

		private Text _notificationDurationText = null;

		private Text _tokenText = null;

		private Image? _settingsIconImage;

		private Sprite? _settingsIconSprite;

		private EventSystem? _controlledEventSystem;

		private bool _previousSendNavigationEvents;

		private bool _navigationInputBlocked;

		private bool _inputDiagnosticsLogged;

		private bool _chatVisible;

		private bool _settingsVisible;

		private bool _notificationsEnabled = true;

		private float _notificationDuration = 5f;

		private Font _font = null;

		private float _notificationX = 90f;

		private float _notificationY = 195f;

		private bool _inputMode;

		internal static bool IsInputMode { get; private set; } = false;

		internal static bool IsChatOpen { get; private set; } = false;

		internal static bool BlockGameMenuInput => IsChatOpen || Time.frameCount == _chatClosedFrame;

		public event Action<string>? MessageSubmitted;

		private void Awake()
		{
			_font = Font.CreateDynamicFontFromOSFont(new string[3] { "Yu Gothic UI", "Meiryo", "Arial" }, 20);
			BuildUI();
			SetChatVisible(visible: false);
		}

		private void OnDestroy()
		{
			SetNavigationInputBlocked(blocked: false);
			IsChatOpen = false;
			IsInputMode = false;
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)287))
			{
				SetChatVisible(!_chatVisible);
				return;
			}
			if (_chatVisible && !_settingsVisible)
			{
				if (!_accessBlocked && !_inputMode && (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271)))
				{
					RepoDiscordBridge.Logger.LogInfo((object)"[Repo Chat InputDiag] Enter detected by chat UI (inputMode=false).");
					BeginInputMode();
				}
				else if (!_accessBlocked && _inputMode && (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271)))
				{
					RepoDiscordBridge.Logger.LogInfo((object)"[Repo Chat InputDiag] Enter detected by chat UI (inputMode=true); sending message.");
					SendCurrentMessage();
				}
				if (Input.GetKeyDown((KeyCode)27))
				{
					if (_inputMode)
					{
						CancelInputMode();
					}
					else
					{
						SetChatVisible(visible: false);
					}
				}
			}
			UpdateNotifications();
		}

		internal void SetConnectionTitle(string title)
		{
			if ((Object)(object)_connectionTitle != (Object)null)
			{
				_connectionTitle.text = title;
			}
		}

		internal void SetAccessBlocked()
		{
			_accessBlocked = true;
			EndInputMode();
			((Selectable)_input).interactable = false;
			((Selectable)_sendButton).interactable = false;
		}

		public void AddDiscordMessage(string username, string message)
		{
			string time = DateTime.Now.ToString("HH:mm");
			AddMessage("Discord", username, message, time, scrollToBottom: true);
			if (_notificationsEnabled)
			{
				ShowNotification("[Discord] (" + username + ") : " + message);
			}
		}

		public void AddRepoMessage(string username, string message)
		{
			AddMessage("REPO", username, message, DateTime.Now.ToString("HH:mm"), scrollToBottom: true);
		}

		private void BuildUI()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Expected O, but got Unknown
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("RepoBridgeCanvas", new Type[3]
			{
				typeof(Canvas),
				typeof(CanvasScaler),
				typeof(GraphicRaycaster)
			});
			Object.DontDestroyOnLoad((Object)(object)val);
			_canvas = val.GetComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 32000;
			CanvasScaler component = val.GetComponent<CanvasScaler>();
			component.uiScaleMode = (ScaleMode)1;
			component.referenceResolution = new Vector2(1920f, 1080f);
			component.matchWidthOrHeight = 0.5f;
			_chatPanel = CreatePanel("ChatPanel", val.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-24f, 0f), new Vector2(570f, 520f), PanelColor, BorderColor);
			_chatPanel.GetComponent<RectTransform>().pivot = new Vector2(1f, 0.5f);
			BuildChatPanel(_chatPanel.transform);
			_settingsPanel = CreatePanel("SettingsPanel", val.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-610f, -20f), new Vector2(430f, 460f), PanelColor, BorderColor);
			_settingsPanel.GetComponent<RectTransform>().pivot = new Vector2(1f, 0.5f);
			BuildSettingsPanel(_settingsPanel.transform);
			_settingsPanel.SetActive(false);
			GameObject val2 = new GameObject("NotificationRoot", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent(val.transform, false);
			_notificationRoot = val2.GetComponent<RectTransform>();
			_notificationRoot.anchorMin = new Vector2(0f, 0.5f);
			_notificationRoot.anchorMax = new Vector2(0f, 0.5f);
			_notificationRoot.pivot = new Vector2(0f, 0.5f);
			_notificationRoot.sizeDelta = new Vector2(1000f, 1f);
			_notificationRoot.anchoredPosition = new Vector2(_notificationX, _notificationY);
		}

		private void BuildChatPanel(Transform root)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Expected O, but got Unknown
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Expected O, but got Unknown
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Expected O, but got Unknown
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Unknown result type (might be due to invalid IL or missing references)
			//IL_054a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0559: Unknown result type (might be due to invalid IL or missing references)
			//IL_0568: Unknown result type (might be due to invalid IL or missing references)
			//IL_0577: Unknown result type (might be due to invalid IL or missing references)
			//IL_0592: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ed: Expected O, but got Unknown
			//IL_0609: Unknown result type (might be due to invalid IL or missing references)
			//IL_060e: Unknown result type (might be due to invalid IL or missing references)
			//IL_061d: Unknown result type (might be due to invalid IL or missing references)
			//IL_062c: Unknown result type (might be due to invalid IL or missing references)
			//IL_063e: Unknown result type (might be due to invalid IL or missing references)
			//IL_066a: Unknown result type (might be due to invalid IL or missing references)
			//IL_067e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0683: Unknown result type (might be due to invalid IL or missing references)
			//IL_0688: Unknown result type (might be due to invalid IL or missing references)
			//IL_068d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0729: Unknown result type (might be due to invalid IL or missing references)
			//IL_0738: Unknown result type (might be due to invalid IL or missing references)
			//IL_0747: Unknown result type (might be due to invalid IL or missing references)
			//IL_0756: Unknown result type (might be due to invalid IL or missing references)
			//IL_0765: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreatePanel("Header", root, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -29f), new Vector2(0f, 58f), HeaderColor, Color.clear);
			Text val2 = CreateText("Title", val.transform, "接続先を確認中...", 22, MainTextColor, (TextAnchor)3);
			Stretch(((Graphic)val2).rectTransform, new Vector2(0f, 0f), Vector2.one, new Vector2(22f, 0f), new Vector2(-108f, 0f));
			_connectionTitle = val2;
			val2.supportRichText = false;
			val2.horizontalOverflow = (HorizontalWrapMode)0;
			val2.verticalOverflow = (VerticalWrapMode)0;
			val2.resizeTextForBestFit = true;
			val2.resizeTextMinSize = 12;
			val2.resizeTextMaxSize = 22;
			Image val3 = CreateImage("Accent", val.transform, DiscordColor);
			SetRect(((Graphic)val3).rectTransform, new Vector2(0f, 0.18f), new Vector2(0f, 0.9f), new Vector2(14f, 0f), new Vector2(4f, 0f));
			CreateSettingsIconButton(val.transform, delegate
			{
				SetSettingsVisible(!_settingsVisible);
			});
			CreateButton("CloseButton", val.transform, "×", 34, MainTextColor, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-24f, 0f), new Vector2(44f, 48f), delegate
			{
				SetChatVisible(visible: false);
			});
			Image val4 = CreateImage("MessageViewport", root, new Color(0f, 0f, 0f, 0.08f));
			Stretch(((Graphic)val4).rectTransform, new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(12f, 70f), new Vector2(-12f, -68f));
			((Component)val4).gameObject.AddComponent<RectMask2D>();
			_emptyChatHint = CreateText("EmptyChatHint", ((Component)val4).transform, "ここから会話をはじめましょう\n\nEnter で送信 · F6 で開閉", 18, MutedTextColor, (TextAnchor)4);
			((Graphic)_emptyChatHint).raycastTarget = false;
			Stretch(((Graphic)_emptyChatHint).rectTransform, Vector2.zero, Vector2.one, new Vector2(24f, 24f), new Vector2(-24f, -24f));
			GameObject val5 = new GameObject("MessageList", new Type[3]
			{
				typeof(RectTransform),
				typeof(VerticalLayoutGroup),
				typeof(ContentSizeFitter)
			});
			val5.transform.SetParent(((Component)val4).transform, false);
			_messageList = val5.GetComponent<RectTransform>();
			_messageList.anchorMin = new Vector2(0f, 1f);
			_messageList.anchorMax = new Vector2(1f, 1f);
			_messageList.pivot = new Vector2(0.5f, 1f);
			_messageList.anchoredPosition = Vector2.zero;
			_messageList.sizeDelta = Vector2.zero;
			VerticalLayoutGroup component = val5.GetComponent<VerticalLayoutGroup>();
			((LayoutGroup)component).padding = new RectOffset(8, 8, 10, 10);
			((HorizontalOrVerticalLayoutGroup)component).spacing = 10f;
			((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false;
			val5.GetComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			GameObject val6 = new GameObject("MessageScroll", new Type[1] { typeof(ScrollRect) });
			val6.transform.SetParent(root, false);
			RectTransform component2 = val6.GetComponent<RectTransform>();
			Stretch(component2, new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(12f, 70f), new Vector2(-12f, -68f));
			_scrollRect = val6.GetComponent<ScrollRect>();
			_scrollRect.viewport = ((Graphic)val4).rectTransform;
			_scrollRect.content = _messageList;
			_scrollRect.horizontal = false;
			_scrollRect.vertical = true;
			_scrollRect.movementType = (MovementType)2;
			_scrollRect.scrollSensitivity = 30f;
			GameObject val7 = CreatePanel("InputBar", root, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(0f, 33f), new Vector2(0f, 66f), HeaderColor, Color.clear);
			Image val8 = CreateImage("InputBackground", val7.transform, new Color(0.11f, 0.13f, 0.17f, 1f));
			Stretch(((Graphic)val8).rectTransform, new Vector2(0f, 0.16f), new Vector2(1f, 0.84f), new Vector2(16f, 0f), new Vector2(-66f, 0f));
			Outline val9 = ((Component)val8).gameObject.AddComponent<Outline>();
			((Shadow)val9).effectColor = BorderColor;
			((Shadow)val9).effectDistance = new Vector2(1f, -1f);
			GameObject val10 = new GameObject("MessageInput", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(InputField)
			});
			val10.transform.SetParent(((Component)val8).transform, false);
			Stretch(val10.GetComponent<RectTransform>(), Vector2.zero, Vector2.one, new Vector2(14f, 4f), new Vector2(-12f, -4f));
			((Graphic)val10.GetComponent<Image>()).color = Color.clear;
			_input = val10.GetComponent<InputField>();
			Text val11 = CreateText("Placeholder", val10.transform, "メッセージを入力...(Enterで送信)", 21, MutedTextColor, (TextAnchor)3);
			Stretch(((Graphic)val11).rectTransform, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero);
			Text val12 = CreateText("InputText", val10.transform, "", 21, MainTextColor, (TextAnchor)3);
			Stretch(((Graphic)val12).rectTransform, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero);
			_input.textComponent = val12;
			_input.placeholder = (Graphic)(object)val11;
			_input.lineType = (LineType)0;
			_input.characterLimit = 500;
			_sendButton = CreateButton("SendButton", val7.transform, "送信", 18, MainTextColor, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-30f, 0f), new Vector2(52f, 52f), SendCurrentMessage);
		}

		private void BuildSettingsPanel(Transform root)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_0556: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Unknown result type (might be due to invalid IL or missing references)
			//IL_0590: Unknown result type (might be due to invalid IL or missing references)
			//IL_059f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0601: Unknown result type (might be due to invalid IL or missing references)
			//IL_061c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0621: Unknown result type (might be due to invalid IL or missing references)
			//IL_0630: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0694: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0704: Unknown result type (might be due to invalid IL or missing references)
			//IL_0713: Unknown result type (might be due to invalid IL or missing references)
			//IL_0722: Unknown result type (might be due to invalid IL or missing references)
			//IL_0731: Unknown result type (might be due to invalid IL or missing references)
			//IL_0769: Unknown result type (might be due to invalid IL or missing references)
			//IL_0778: Unknown result type (might be due to invalid IL or missing references)
			//IL_0787: Unknown result type (might be due to invalid IL or missing references)
			//IL_0796: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreatePanel("SettingsHeader", root, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -30f), new Vector2(0f, 60f), HeaderColor, Color.clear);
			Text val2 = CreateText("SettingsTitle", val.transform, "設定", 24, MainTextColor, (TextAnchor)3);
			Stretch(((Graphic)val2).rectTransform, Vector2.zero, Vector2.one, new Vector2(22f, 0f), new Vector2(-60f, 0f));
			CreateButton("SettingsClose", val.transform, "×", 30, MainTextColor, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-26f, 0f), new Vector2(44f, 44f), delegate
			{
				SetSettingsVisible(visible: false);
			});
			CreateText("NotificationSection", root, "通知設定", 15, DiscordColor, (TextAnchor)3);
			RectTransform component = ((Component)root.Find("NotificationSection")).GetComponent<RectTransform>();
			SetRect(component, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(22f, -78f), new Vector2(-44f, 24f));
			GameObject val3 = CreatePanel("NotificationCard", root, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -148f), new Vector2(-32f, 72f), new Color(0.09f, 0.105f, 0.135f, 1f), new Color(0.2f, 0.24f, 0.3f, 0.8f));
			Text val4 = CreateText("NotificationLabel", val3.transform, "ゲーム画面にDiscord通知を表示", 16, MainTextColor, (TextAnchor)3);
			Stretch(((Graphic)val4).rectTransform, Vector2.zero, Vector2.one, new Vector2(18f, 0f), new Vector2(-112f, 0f));
			val4.resizeTextForBestFit = true;
			val4.resizeTextMinSize = 14;
			val4.resizeTextMaxSize = 16;
			CreateButton("NotificationToggle", val3.transform, "ON", 15, MainTextColor, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-54f, 0f), new Vector2(82f, 40f), ToggleNotifications);
			GameObject val5 = CreatePanel("DurationCard", root, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -232f), new Vector2(-32f, 72f), new Color(0.09f, 0.105f, 0.135f, 1f), new Color(0.2f, 0.24f, 0.3f, 0.8f));
			Text val6 = CreateText("DurationLabel", val5.transform, "通知の表示時間", 17, MainTextColor, (TextAnchor)3);
			Stretch(((Graphic)val6).rectTransform, Vector2.zero, Vector2.one, new Vector2(18f, 0f), new Vector2(-205f, 0f));
			_notificationDurationText = CreateText("DurationValue", val5.transform, "5秒", 17, MainTextColor, (TextAnchor)4);
			SetRect(((Graphic)_notificationDurationText).rectTransform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-84f, 0f), new Vector2(70f, 42f));
			((Graphic)_notificationDurationText).rectTransform.pivot = new Vector2(0.5f, 0.5f);
			CreateButton("DurationMinus", val5.transform, "−", 22, MainTextColor, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-145f, 0f), new Vector2(34f, 38f), delegate
			{
				ChangeDuration(-1f);
			});
			CreateButton("DurationPlus", val5.transform, "+", 22, MainTextColor, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-25f, 0f), new Vector2(34f, 38f), delegate
			{
				ChangeDuration(1f);
			});
			CreateText("AccountSection", root, "アカウント連携", 15, DiscordColor, (TextAnchor)3);
			RectTransform component2 = ((Component)root.Find("AccountSection")).GetComponent<RectTransform>();
			SetRect(component2, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(22f, -280f), new Vector2(-44f, 24f));
			GameObject val7 = CreatePanel("TokenCard", root, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -348f), new Vector2(-32f, 64f), new Color(0.09f, 0.105f, 0.135f, 1f), new Color(0.2f, 0.24f, 0.3f, 0.8f));
			_tokenText = CreateText("PlayerTokenText", val7.transform, "PlayerTokenをコピーしてWebで連携", 15, MainTextColor, (TextAnchor)3);
			Stretch(((Graphic)_tokenText).rectTransform, Vector2.zero, Vector2.one, new Vector2(14f, 0f), new Vector2(-112f, 0f));
			_tokenText.horizontalOverflow = (HorizontalWrapMode)0;
			_tokenText.resizeTextForBestFit = true;
			_tokenText.resizeTextMinSize = 13;
			_tokenText.resizeTextMaxSize = 15;
			CreateButton("CopyTokenButton", val7.transform, "コピー", 14, MainTextColor, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-48f, 0f), new Vector2(78f, 38f), CopyPlayerToken);
			CreateButton("WebSettingsButton", root, "Webで接続設定", 16, MainTextColor, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(-72f, 36f), new Vector2(220f, 42f), delegate
			{
				Application.OpenURL("https://team-ace.jp/repo-bridge/");
			});
			CreateButton("UsageGuideButton", root, "使い方", 16, MainTextColor, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(130f, 36f), new Vector2(100f, 42f), delegate
			{
				Application.OpenURL("https://team-ace.jp/blog/repo-chat/");
			});
			UpdateDurationText();
			UpdateNotificationToggleText();
		}

		private static string GetPlayerToken()
		{
			return RepoDiscordBridge.PlayerToken ?? "";
		}

		private void CopyPlayerToken()
		{
			string playerToken = GetPlayerToken();
			if (!string.IsNullOrEmpty(playerToken))
			{
				GUIUtility.systemCopyBuffer = playerToken;
			}
			if ((Object)(object)_tokenText != (Object)null)
			{
				_tokenText.text = (string.IsNullOrEmpty(playerToken) ? "Tokenが取得できません" : "コピーしました · Webに貼り付け");
			}
		}

		private void UpdateNotificationToggleText()
		{
			Transform obj = _settingsPanel.transform.Find("NotificationCard/NotificationToggle/NotificationToggleText");
			Text val = ((obj != null) ? ((Component)obj).GetComponent<Text>() : null);
			if ((Object)(object)val != (Object)null)
			{
				val.text = (_notificationsEnabled ? "ON" : "OFF");
			}
		}

		private void CreateSettingsIconButton(Transform parent, Action onClick)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			Image val = CreateImage("SettingsButton", parent, new Color(0.14f, 0.17f, 0.22f, 0.8f));
			RectTransform rectTransform = ((Graphic)val).rectTransform;
			rectTransform.anchorMin = new Vector2(1f, 0.5f);
			rectTransform.anchorMax = new Vector2(1f, 0.5f);
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.anchoredPosition = new Vector2(-74f, 0f);
			rectTransform.sizeDelta = new Vector2(48f, 48f);
			Button val2 = ((Component)val).gameObject.AddComponent<Button>();
			((Selectable)val2).targetGraphic = (Graphic)(object)val;
			((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
			try
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("RepoDiscordBridge.Assets.settings.png");
				if (stream == null)
				{
					return;
				}
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				Texture2D val3 = new Texture2D(2, 2, (TextureFormat)4, false);
				if (ImageConversion.LoadImage(val3, memoryStream.ToArray()))
				{
					_settingsIconSprite = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), new Vector2(0.5f, 0.5f));
					GameObject val4 = new GameObject("SettingsIcon", new Type[2]
					{
						typeof(RectTransform),
						typeof(Image)
					});
					val4.transform.SetParent(((Component)val).transform, false);
					Image val5 = (_settingsIconImage = val4.GetComponent<Image>());
					val5.sprite = _settingsIconSprite;
					val5.preserveAspect = true;
					Stretch(((Graphic)val5).rectTransform, new Vector2(0.12f, 0.12f), new Vector2(0.88f, 0.88f), Vector2.zero, Vector2.zero);
				}
			}
			catch (Exception ex)
			{
				RepoDiscordBridge.Logger.LogWarning((object)("設定アイコン読み込み失敗: " + ex.Message));
			}
		}

		private void BeginInputMode()
		{
			if (!_inputMode && !_accessBlocked)
			{
				_inputMode = true;
				IsInputMode = true;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				if ((Object)(object)EventSystem.current != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject(((Component)_input).gameObject);
				}
				_input.ActivateInputField();
				((Selectable)_input).Select();
			}
		}

		private void EndInputMode()
		{
			if (_inputMode)
			{
				_inputMode = false;
				IsInputMode = false;
				_input.DeactivateInputField();
				if ((Object)(object)EventSystem.current != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject((GameObject)null);
				}
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
			}
		}

		private void CancelInputMode()
		{
			_input.text = string.Empty;
			EndInputMode();
		}

		private void SendCurrentMessage()
		{
			if (!_accessBlocked && !((Object)(object)_input == (Object)null) && _chatVisible && !_settingsVisible)
			{
				string text = _input.text.Trim();
				if (text.Length > 0)
				{
					string localPlayerName = RepoDiscordBridge.GetLocalPlayerName();
					AddRepoMessage(localPlayerName, text);
					this.MessageSubmitted?.Invoke(text);
				}
				_input.text = string.Empty;
				if (!_inputMode)
				{
					_inputMode = true;
					IsInputMode = true;
				}
				((MonoBehaviour)this).StartCoroutine(ReactivateInputNextFrame());
			}
		}

		private IEnumerator ReactivateInputNextFrame()
		{
			yield return null;
			if (_chatVisible && !_settingsVisible && _inputMode && !((Object)(object)_input == (Object)null))
			{
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				_input.ActivateInputField();
				((Selectable)_input).Select();
				if ((Object)(object)EventSystem.current != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject(((Component)_input).gameObject);
				}
			}
		}

		private void AddMessage(string source, string username, string message, string time, bool scrollToBottom)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Message", new Type[3]
			{
				typeof(RectTransform),
				typeof(LayoutElement),
				typeof(VerticalLayoutGroup)
			});
			val.transform.SetParent((Transform)(object)_messageList, false);
			LayoutElement component = val.GetComponent<LayoutElement>();
			component.minHeight = 38f;
			VerticalLayoutGroup component2 = val.GetComponent<VerticalLayoutGroup>();
			((LayoutGroup)component2).padding = new RectOffset(2, 2, 6, 6);
			((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false;
			GameObject val2 = new GameObject("MessageText", new Type[2]
			{
				typeof(RectTransform),
				typeof(Text)
			});
			val2.transform.SetParent(val.transform, false);
			Text component3 = val2.GetComponent<Text>();
			component3.font = _font;
			component3.fontSize = 19;
			component3.lineSpacing = 1.15f;
			component3.alignment = (TextAnchor)3;
			component3.horizontalOverflow = (HorizontalWrapMode)0;
			component3.verticalOverflow = (VerticalWrapMode)1;
			component3.supportRichText = true;
			((Graphic)component3).color = MainTextColor;
			Color val3 = ((source == "Discord") ? DiscordColor : RepoColor);
			component3.text = "<color=#" + ColorUtility.ToHtmlStringRGB(val3) + ">[" + source + "]</color> (" + EscapeRichText(username) + ") : " + EscapeRichText(message) + " <color=#" + ColorUtility.ToHtmlStringRGB(MutedTextColor) + ">|" + time + "</color>";
			Stretch(((Graphic)component3).rectTransform, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero);
			_messageRows.Add(val);
			((Component)_emptyChatHint).gameObject.SetActive(false);
			while (_messageRows.Count > 100)
			{
				Object.Destroy((Object)(object)_messageRows[0]);
				_messageRows.RemoveAt(0);
			}
			if (scrollToBottom)
			{
				((MonoBehaviour)this).StartCoroutine(ScrollToBottomNextFrame());
			}
		}

		private IEnumerator ScrollToBottomNextFrame()
		{
			yield return null;
			Canvas.ForceUpdateCanvases();
			_scrollRect.verticalNormalizedPosition = 0f;
		}

		private void ShowNotification(string message)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			Text val = CreateText("Notification_" + _notifications.Count, (Transform)(object)_notificationRoot, message, 28, MainTextColor, (TextAnchor)3);
			val.horizontalOverflow = (HorizontalWrapMode)1;
			val.verticalOverflow = (VerticalWrapMode)1;
			val.supportRichText = false;
			RectTransform rectTransform = ((Graphic)val).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 0.5f);
			rectTransform.anchorMax = new Vector2(0f, 0.5f);
			rectTransform.pivot = new Vector2(0f, 0.5f);
			rectTransform.sizeDelta = new Vector2(1000f, 38f);
			_notifications.Add(new NotificationEntry
			{
				Object = ((Component)val).gameObject,
				Remaining = _notificationDuration
			});
			((Component)_notificationRoot).gameObject.SetActive(true);
			LayoutNotifications();
		}

		private void UpdateNotifications()
		{
			if (_notifications.Count == 0)
			{
				return;
			}
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			for (int num = _notifications.Count - 1; num >= 0; num--)
			{
				NotificationEntry notificationEntry = _notifications[num];
				notificationEntry.Remaining -= unscaledDeltaTime;
				if (notificationEntry.Remaining <= 0f)
				{
					Object.Destroy((Object)(object)notificationEntry.Object);
					_notifications.RemoveAt(num);
				}
			}
			if (_notifications.Count == 0)
			{
				((Component)_notificationRoot).gameObject.SetActive(false);
			}
			else
			{
				LayoutNotifications();
			}
		}

		private void LayoutNotifications()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < _notifications.Count; i++)
			{
				RectTransform component = _notifications[i].Object.GetComponent<RectTransform>();
				component.anchoredPosition = new Vector2(0f, (float)(-i) * 42f);
			}
		}

		private void ToggleNotifications()
		{
			_notificationsEnabled = !_notificationsEnabled;
			UpdateNotificationToggleText();
		}

		private void ChangeDuration(float delta)
		{
			_notificationDuration = Mathf.Clamp(_notificationDuration + delta, 1f, 15f);
			UpdateDurationText();
		}

		private void UpdateDurationText()
		{
			if ((Object)(object)_notificationDurationText != (Object)null)
			{
				_notificationDurationText.text = $"{_notificationDuration:0}秒";
			}
		}

		private void SetChatVisible(bool visible)
		{
			if (!visible && _chatVisible)
			{
				_chatClosedFrame = Time.frameCount;
			}
			if (!visible)
			{
				EndInputMode();
			}
			_chatVisible = visible;
			IsChatOpen = visible;
			SetNavigationInputBlocked(visible);
			if (visible && !_inputDiagnosticsLogged)
			{
				LogInputDiagnostics();
				_inputDiagnosticsLogged = true;
			}
			if ((Object)(object)_chatPanel != (Object)null)
			{
				_chatPanel.SetActive(visible);
			}
			if (!visible)
			{
				SetSettingsVisible(visible: false);
			}
			else
			{
				BeginInputMode();
			}
			SetUiCursor(visible);
		}

		private static void SetUiCursor(bool visible)
		{
			Cursor.lockState = (CursorLockMode)(!visible);
			Cursor.visible = visible;
		}

		private void LateUpdate()
		{
			if (_chatVisible)
			{
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				SetNavigationInputBlocked(blocked: true);
			}
		}

		private void LogInputDiagnostics()
		{
			EventSystem current = EventSystem.current;
			RepoDiscordBridge.Logger.LogInfo((object)("[Repo Chat InputDiag] Chat opened. InputMode=" + _inputMode + ", EventSystem=" + (((Object)(object)current != (Object)null) ? ((object)current).GetType().FullName : "null") + ", sendNavigationEvents=" + (((Object)(object)current != (Object)null) ? current.sendNavigationEvents.ToString() : "n/a")));
			string[] array = new string[4] { "MenuManager", "GameDirector", "PlayerController", "SemiFunc" };
			string[] array2 = new string[5] { "TextInputActive", "SetDisableInput", "InputDisable", "InputDisableMovement", "InputDisableAiming" };
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type[] types;
				try
				{
					types = assembly.GetTypes();
				}
				catch (ReflectionTypeLoadException ex)
				{
					types = ex.Types;
				}
				catch
				{
					continue;
				}
				Type[] array3 = types;
				foreach (Type type in array3)
				{
					if (type == null)
					{
						continue;
					}
					bool flag = false;
					string[] array4 = array;
					foreach (string text in array4)
					{
						if (type.Name == text)
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						continue;
					}
					RepoDiscordBridge.Logger.LogInfo((object)("[Repo Chat InputDiag] Found type: " + type.FullName + " (assembly=" + assembly.GetName().Name + ")"));
					try
					{
						MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						MethodInfo[] array5 = methods;
						foreach (MethodInfo methodInfo in array5)
						{
							bool flag2 = false;
							string[] array6 = array2;
							foreach (string text2 in array6)
							{
								if (methodInfo.Name == text2)
								{
									flag2 = true;
									break;
								}
							}
							if (!flag2)
							{
								continue;
							}
							ParameterInfo[] parameters = methodInfo.GetParameters();
							string text3 = methodInfo.Name + "(";
							for (int n = 0; n < parameters.Length; n++)
							{
								if (n > 0)
								{
									text3 += ", ";
								}
								text3 = text3 + parameters[n].ParameterType.FullName + " " + parameters[n].Name;
							}
							text3 += ")";
							RepoDiscordBridge.Logger.LogInfo((object)("[Repo Chat InputDiag] Method: " + type.FullName + "." + text3 + " [static=" + methodInfo.IsStatic + "]"));
						}
					}
					catch (Exception ex2)
					{
						RepoDiscordBridge.Logger.LogWarning((object)("[Repo Chat InputDiag] Failed to inspect " + type.FullName + ": " + ex2.Message));
					}
				}
			}
		}

		private void SetNavigationInputBlocked(bool blocked)
		{
			if (blocked)
			{
				EventSystem current = EventSystem.current;
				if ((Object)(object)current == (Object)null)
				{
					return;
				}
				if (!_navigationInputBlocked || (Object)(object)_controlledEventSystem != (Object)(object)current)
				{
					if (_navigationInputBlocked && (Object)(object)_controlledEventSystem != (Object)null)
					{
						_controlledEventSystem.sendNavigationEvents = _previousSendNavigationEvents;
					}
					_controlledEventSystem = current;
					_previousSendNavigationEvents = current.sendNavigationEvents;
					_navigationInputBlocked = true;
				}
				current.sendNavigationEvents = false;
			}
			else if (_navigationInputBlocked)
			{
				if ((Object)(object)_controlledEventSystem != (Object)null)
				{
					_controlledEventSystem.sendNavigationEvents = _previousSendNavigationEvents;
				}
				_controlledEventSystem = null;
				_navigationInputBlocked = false;
			}
		}

		private void SetSettingsVisible(bool visible)
		{
			_settingsVisible = visible;
			if ((Object)(object)_settingsPanel != (Object)null)
			{
				_settingsPanel.SetActive(visible);
			}
			if (_chatVisible)
			{
				SetUiCursor(visible: true);
			}
		}

		private GameObject CreatePanel(string name, Transform parent, Vector2 anchorMin, Vector2 anchorMax, Vector2 position, Vector2 size, Color color, Color outline)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			Image val = CreateImage(name, parent, color);
			RectTransform rectTransform = ((Graphic)val).rectTransform;
			rectTransform.anchorMin = anchorMin;
			rectTransform.anchorMax = anchorMax;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.anchoredPosition = position;
			rectTransform.sizeDelta = size;
			if (outline.a > 0f)
			{
				Outline val2 = ((Component)val).gameObject.AddComponent<Outline>();
				((Shadow)val2).effectColor = outline;
				((Shadow)val2).effectDistance = new Vector2(1f, -1f);
			}
			return ((Component)val).gameObject;
		}

		private Image CreateImage(string name, Transform parent, Color color)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = color;
			return component;
		}

		private Text CreateText(string name, Transform parent, string value, int size, Color color, TextAnchor alignment)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_005c: 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)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Text)
			});
			val.transform.SetParent(parent, false);
			Text component = val.GetComponent<Text>();
			component.font = _font;
			component.text = value;
			component.fontSize = size;
			((Graphic)component).color = color;
			component.alignment = alignment;
			component.horizontalOverflow = (HorizontalWrapMode)1;
			component.verticalOverflow = (VerticalWrapMode)1;
			return component;
		}

		private Button CreateButton(string name, Transform parent, string label, int fontSize, Color textColor, Vector2 anchorMin, Vector2 anchorMax, Vector2 position, Vector2 size, Action onClick)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Expected O, but got Unknown
			Image val = CreateImage(name, parent, new Color(0.14f, 0.17f, 0.22f, 0.8f));
			RectTransform rectTransform = ((Graphic)val).rectTransform;
			rectTransform.anchorMin = anchorMin;
			rectTransform.anchorMax = anchorMax;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.anchoredPosition = position;
			rectTransform.sizeDelta = size;
			Button val2 = ((Component)val).gameObject.AddComponent<Button>();
			((Selectable)val2).targetGraphic = (Graphic)(object)val;
			ColorBlock colors = ((Selectable)val2).colors;
			((ColorBlock)(ref colors)).normalColor = new Color(0.14f, 0.17f, 0.22f, 0.8f);
			((ColorBlock)(ref colors)).highlightedColor = new Color(0.23f, 0.29f, 0.38f, 0.95f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.1f, 0.13f, 0.18f, 1f);
			((Selectable)val2).colors = colors;
			Text val3 = CreateText(name + "Text", ((Component)val).transform, label, fontSize, textColor, (TextAnchor)4);
			Stretch(((Graphic)val3).rectTransform, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero);
			((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
			return val2;
		}

		private static void Stretch(RectTransform rect, Vector2 min, Vector2 max, Vector2 offsetMin, Vector2 offsetMax)
		{
			//IL_0002: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = min;
			rect.anchorMax = max;
			rect.offsetMin = offsetMin;
			rect.offsetMax = offsetMax;
		}

		private static void SetRect(RectTransform rect, Vector2 min, Vector2 max, Vector2 position, Vector2 size)
		{
			//IL_0002: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = min;
			rect.anchorMax = max;
			rect.pivot = new Vector2(0f, 1f);
			rect.anchoredPosition = position;
			rect.sizeDelta = size;
		}

		private static string EscapeRichText(string value)
		{
			return value.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;");
		}
	}
	internal sealed class BridgeClient : IDisposable
	{
		private readonly string _baseUrl;

		private readonly string _token;

		private readonly Func<string> _playerName;

		private readonly ConcurrentQueue<Action> _mainThread = new ConcurrentQueue<Action>();

		private readonly HttpClient _http = new HttpClient
		{
			Timeout = TimeSpan.FromSeconds(15.0)
		};

		private readonly CancellationTokenSource _stop = new CancellationTokenSource();

		private ClientWebSocket? _socket;

		private Task? _worker;

		private Task? _connectionWorker;

		private string? _lastConnectionTitle;

		private int _accessBlocked;

		private bool AccessBlocked => Volatile.Read(in _accessBlocked) != 0;

		internal event Action<string, string>? DiscordMessageReceived;

		internal event Action<string>? StatusChanged;

		internal event Action<string>? ConnectionTitleChanged;

		internal event Action? AccessBlockedReceived;

		internal BridgeClient(string baseUrl, string token, Func<string> playerName)
		{
			_baseUrl = baseUrl.TrimEnd('/');
			_token = token;
			_playerName = playerName;
			_http.DefaultRequestHeaders.UserAgent.ParseAdd("RepoChat-Mod/1.0");
		}

		internal void Start()
		{
			if (_worker == null)
			{
				_worker = Task.Run((Func<Task?>)RunAsync);
			}
		}

		internal void SendChat(string message)
		{
			if (AccessBlocked)
			{
				return;
			}
			Task.Run(async delegate
			{
				try
				{
					string json = "{\"player_name\":\"" + Escape(_playerName()) + "\",\"content\":\"" + Escape(message) + "\"}";
					using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, _baseUrl + "/api/chat/send");
					request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token);
					request.Content = new StringContent(json, Encoding.UTF8, "application/json");
					using HttpResponseMessage response = await _http.SendAsync(request, _stop.Token).ConfigureAwait(continueOnCapturedContext: false);
					if (HandleAccessDenied(response))
					{
						return;
					}
					if (!response.IsSuccessStatusCode)
					{
						string body = await response.Content.ReadAsStringAsync().ConfigureAwait(continueOnCapturedContext: false);
						QueueStatus("Discord送信失敗: HTTP " + (int)response.StatusCode + " " + body);
					}
				}
				catch (Exception ex)
				{
					Exception ex2 = ex;
					QueueStatus("Discord送信エラー: " + ex2.Message);
				}
			});
		}

		internal void Tick()
		{
			Action result;
			while (_mainThread.TryDequeue(out result))
			{
				try
				{
					result();
				}
				catch (Exception ex)
				{
					RepoDiscordBridge.Logger.LogError((object)ex);
				}
			}
		}

		private async Task RunAsync()
		{
			try
			{
				await RegisterAsync().ConfigureAwait(continueOnCapturedContext: false);
				if (AccessBlocked)
				{
					return;
				}
				if (_connectionWorker == null)
				{
					_connectionWorker = PollConnectionAsync(_stop.Token);
				}
				QueueStatus("Repo Chat サーバー登録完了");
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				QueueStatus("サーバー登録失敗: " + ex2.Message);
				return;
			}
			while (!_stop.IsCancellationRequested && !AccessBlocked)
			{
				try
				{
					await ConnectAndReceiveAsync(_stop.Token).ConfigureAwait(continueOnCapturedContext: false);
				}
				catch (OperationCanceledException)
				{
					break;
				}
				catch (Exception ex4)
				{
					if (AccessBlocked)
					{
						break;
					}
					QueueStatus("Discord接続切断: 再接続します");
					RepoDiscordBridge.Logger.LogWarning((object)ex4.Message);
				}
				try
				{
					await Task.Delay(TimeSpan.FromSeconds(5.0), _stop.Token).ConfigureAwait(continueOnCapturedContext: false);
				}
				catch (OperationCanceledException)
				{
					break;
				}
			}
		}

		private async Task RegisterAsync()
		{
			string json = "{\"player_token\":\"" + Escape(_token) + "\",\"player_name\":\"" + Escape(_playerName()) + "\"}";
			using StringContent content = new StringContent(json, Encoding.UTF8, "application/json");
			using HttpResponseMessage response = await _http.PostAsync(_baseUrl + "/api/devices/register", content, _stop.Token).ConfigureAwait(continueOnCapturedContext: false);
			if (!HandleAccessDenied(response))
			{
				response.EnsureSuccessStatusCode();
			}
		}

		private async Task PollConnectionAsync(CancellationToken cancellationToken)
		{
			while (!cancellationToken.IsCancellationRequested && !AccessBlocked)
			{
				try
				{
					using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, _baseUrl + "/api/devices/status");
					request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token);
					using HttpResponseMessage response = await _http.SendAsync(request, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
					if (HandleAccessDenied(response))
					{
						break;
					}
					response.EnsureSuccessStatusCode();
					BridgeDeviceStatus status = BridgeServerProtocol.ParseDeviceStatus(await response.Content.ReadAsStringAsync().ConfigureAwait(continueOnCapturedContext: false));
					QueueConnectionTitle(status.connection, status.paired == false);
				}
				catch (OperationCanceledException)
				{
					break;
				}
				catch
				{
					_mainThread.Enqueue(delegate
					{
						if (_lastConnectionTitle == null && !AccessBlocked)
						{
							this.ConnectionTitleChanged?.Invoke("接続情報を取得できません");
						}
					});
				}
				try
				{
					await Task.Delay(TimeSpan.FromSeconds(10.0), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
				}
				catch (OperationCanceledException)
				{
					break;
				}
			}
		}

		private void QueueConnectionTitle(BridgeServerMessage? data, bool knownUnpaired = false)
		{
			string title = BridgeServerProtocol.ConnectionTitle(data, knownUnpaired);
			if (title == null)
			{
				return;
			}
			_mainThread.Enqueue(delegate
			{
				if (!AccessBlocked && !(_lastConnectionTitle == title))
				{
					_lastConnectionTitle = title;
					this.ConnectionTitleChanged?.Invoke(title);
					RepoDiscordBridge.Logger.LogInfo((object)("[Repo Chat] 接続先表示: " + title));
				}
			});
		}

		private async Task ConnectAndReceiveAsync(CancellationToken cancellationToken)
		{
			_socket?.Dispose();
			_socket = new ClientWebSocket();
			Uri uri = new Uri(_baseUrl.Replace("https://", "wss://").Replace("http://", "ws://") + "/ws/game");
			await _socket.ConnectAsync(uri, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			byte[] auth = Encoding.UTF8.GetBytes("{\"token\":\"" + Escape(_token) + "\"}");
			await _socket.SendAsync(new ArraySegment<byte>(auth), WebSocketMessageType.Text, endOfMessage: true, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			QueueStatus("Repo Chat 接続中");
			byte[] buffer = new byte[8192];
			while (_socket.State == WebSocketState.Open && !cancellationToken.IsCancellationRequested && !AccessBlocked)
			{
				StringBuilder builder = new StringBuilder();
				WebSocketReceiveResult result;
				do
				{
					result = await _socket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
					if (result.MessageType == WebSocketMessageType.Close)
					{
						return;
					}
					builder.Append(Encoding.UTF8.GetString(buffer, 0, result.Count));
				}
				while (!result.EndOfMessage);
				string json = builder.ToString();
				BridgeServerMessage data = BridgeServerProtocol.ParseMessage(json);
				if (data.type == "access_denied")
				{
					BlockAccess();
					break;
				}
				if (data.type == "connection")
				{
					QueueConnectionTitle(data);
					continue;
				}
				if (data.type == "discord_message")
				{
					if (data != null && !string.IsNullOrWhiteSpace(data.content))
					{
						string name = data.author ?? "Discord";
						string message = data.content;
						_mainThread.Enqueue(delegate
						{
							this.DiscordMessageReceived?.Invoke(name, message);
						});
					}
					continue;
				}
				if (data.type == "auth_error")
				{
					QueueConnectionTitle(null, knownUnpaired: true);
					QueueStatus("未連携です。WebサイトでMODを連携してください。");
					break;
				}
				if (data.type == "ready")
				{
					QueueStatus("Discord連携済み・接続中");
				}
			}
		}

		private void QueueStatus(string text)
		{
			_mainThread.Enqueue(delegate
			{
				this.StatusChanged?.Invoke(text);
			});
		}

		private bool HandleAccessDenied(HttpResponseMessage response)
		{
			if (response.StatusCode != HttpStatusCode.Forbidden || !response.Headers.TryGetValues("X-Repo-Access-Denied", out IEnumerable<string> values))
			{
				return false;
			}
			foreach (string item in values)
			{
				if (string.Equals(item, "true", StringComparison.OrdinalIgnoreCase))
				{
					BlockAccess();
					return true;
				}
			}
			return false;
		}

		private void BlockAccess()
		{
			if (Interlocked.Exchange(ref _accessBlocked, 1) == 0)
			{
				try
				{
					_socket?.Abort();
				}
				catch
				{
				}
				_mainThread.Enqueue(delegate
				{
					this.AccessBlockedReceived?.Invoke();
					this.ConnectionTitleChanged?.Invoke("利用停止中 · 公式サポートへお問い合わせください");
					this.StatusChanged?.Invoke("この接続元は利用停止中です。解除後はゲームを再起動してください。");
				});
			}
		}

		private static string Escape(string value)
		{
			if (value == null)
			{
				return "";
			}
			return value.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\r", "\\r")
				.Replace("\n", "\\n");
		}

		internal static string GenerateToken()
		{
			byte[] array = new byte[32];
			using (RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create())
			{
				randomNumberGenerator.GetBytes(array);
			}
			return Convert.ToBase64String(array).TrimEnd('=').Replace('+', '-')
				.Replace('/', '_');
		}

		public void Dispose()
		{
			_stop.Cancel();
			try
			{
				_socket?.Abort();
				_socket?.Dispose();
			}
			catch
			{
			}
			_http.Dispose();
			_stop.Dispose();
		}
	}
	internal static class BridgeServerProtocol
	{
		internal static BridgeServerMessage ParseMessage(string json)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return JsonConvert.DeserializeObject<BridgeServerMessage>(json) ?? throw new JsonSerializationException("Missing server message");
		}

		internal static BridgeDeviceStatus ParseDeviceStatus(string json)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return JsonConvert.DeserializeObject<BridgeDeviceStatus>(json) ?? throw new JsonSerializationException("Missing device status");
		}

		internal static string? ConnectionTitle(BridgeServerMessage? data, bool knownUnpaired = false)
		{
			if (knownUnpaired)
			{
				return "MOD未連携 · Webで連携してください";
			}
			if (data == null || !data.configured.HasValue)
			{
				return null;
			}
			if (!data.configured.Value)
			{
				return "接続先未設定 · Webで設定してください";
			}
			string text = (string.IsNullOrWhiteSpace(data.guild_name) ? "Discord" : data.guild_name);
			string text2 = (string.IsNullOrWhiteSpace(data.channel_name) ? data.channel_id : data.channel_name);
			return text + " / #" + text2;
		}
	}
	[Serializable]
	internal sealed class BridgeServerMessage
	{
		public string type = "";

		public string author = "";

		public string content = "";

		public bool? configured = null;

		public string guild_name = "";

		public string channel_name = "";

		public string channel_id = "";
	}
	[Serializable]
	internal sealed class BridgeDeviceStatus
	{
		public bool? paired = null;

		public BridgeServerMessage? connection = null;
	}
	[HarmonyPatch]
	internal static class ChatInputPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SemiFunc), "InputMovementX")]
		private static void InputMovementX_Postfix(ref float __result)
		{
			if (BridgeChatUI.IsChatOpen)
			{
				__result = 0f;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SemiFunc), "InputMovementY")]
		private static void InputMovementY_Postfix(ref float __result)
		{
			if (BridgeChatUI.IsChatOpen)
			{
				__result = 0f;
			}
		}
	}
	[HarmonyPatch]
	internal static class ChatGameButtonPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			string[] array = new string[3] { "InputDown", "InputUp", "InputHold" };
			foreach (string name in array)
			{
				yield return AccessTools.Method(typeof(SemiFunc), name, new Type[1] { typeof(InputKey) }, (Type[])null);
			}
		}

		[HarmonyPrefix]
		private static bool Prefix(InputKey key, ref bool __result)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (!BridgeChatUI.BlockGameMenuInput || !IsMenuOrChatAction(key))
			{
				return true;
			}
			__result = false;
			return false;
		}

		private static bool IsMenuOrChatAction(InputKey key)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			switch (((object)key).ToString())
			{
			case "Menu":
			case "Back":
			case "BackEditor":
			case "UIClick":
			case "UITabLeft":
			case "UITabRight":
			case "Chat":
			case "ChatConfirm":
				return true;
			default:
				return false;
			}
		}
	}
	[HarmonyPatch]
	internal static class ChatGameNavigationPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo method = AccessTools.Method(typeof(SemiFunc), "InputUINavigate", Type.EmptyTypes, (Type[])null);
			if (method != null)
			{
				yield return method;
			}
		}

		private static void Postfix(ref Vector2 __result)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (BridgeChatUI.BlockGameMenuInput)
			{
				__result = Vector2.zero;
			}
		}
	}
	[HarmonyPatch]
	internal static class ChatGameTextInputPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			string[] array = new string[2] { "NoTextInputsActive", "NoExternalTextInputActive" };
			foreach (string name in array)
			{
				MethodInfo method = AccessTools.Method(typeof(SemiFunc), name, Type.EmptyTypes, (Type[])null);
				if (method != null)
				{
					yield return method;
				}
			}
		}

		[HarmonyPostfix]
		private static void Postfix(ref bool __result)
		{
			if (BridgeChatUI.BlockGameMenuInput)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(StandaloneInputModule), "SendSubmitEventToSelectedObject")]
	internal static class ChatUISubmitPatch
	{
		private static bool Prefix(ref bool __result)
		{
			if (!BridgeChatUI.IsChatOpen)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(StandaloneInputModule), "SendMoveEventToSelectedObject")]
	internal static class ChatUIMovePatch
	{
		private static bool Prefix(ref bool __result)
		{
			if (!BridgeChatUI.IsChatOpen)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayerController))]
	internal static class ExamplePlayerControllerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void Start_Postfix(PlayerController __instance)
		{
			RepoDiscordBridge.Logger.LogInfo((object)("PlayerController initialized: " + ((Object)__instance).name));
		}
	}
	[BepInPlugin("Rao.RepoDiscordBridge", "RepoDiscordBridge", "1.0")]
	public class RepoDiscordBridge : BaseUnityPlugin
	{
		private BridgeClient? _bridge;

		private ConfigEntry<string> _serverUrl = null;

		private ConfigEntry<string> _playerToken = null;

		internal static RepoDiscordBridge Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

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

		internal Harmony? Harmony { get; set; }

		internal static string PlayerToken => Instance?._playerToken?.Value ?? string.Empty;

		private void Awake()
		{
			Instance = this;
			_serverUrl = ((BaseUnityPlugin)this).Config.Bind<string>("Connection", "ServerUrl", "https://team-ace.jp/repo-bridge", "Repo Chat server URL");
			_playerToken = ((BaseUnityPlugin)this).Config.Bind<string>("Account", "PlayerToken", BridgeClient.GenerateToken(), "Private player token. Do not share this value.");
			BridgeChatUI chatUi = ((Component)this).gameObject.AddComponent<BridgeChatUI>();
			_bridge = new BridgeClient(_serverUrl.Value, _playerToken.Value, GetLocalPlayerName);
			_bridge.DiscordMessageReceived += delegate(string username, string message)
			{
				if ((Object)(object)chatUi != (Object)null)
				{
					chatUi.AddDiscordMessage(username, message);
				}
			};
			_bridge.StatusChanged += delegate(string message)
			{
				Logger.LogInfo((object)("[Repo Chat] " + message));
			};
			_bridge.ConnectionTitleChanged += delegate(string title)
			{
				if ((Object)(object)chatUi != (Object)null)
				{
					chatUi.SetConnectionTitle(title);
				}
			};
			_bridge.AccessBlockedReceived += delegate
			{
				if ((Object)(object)chatUi != (Object)null)
				{
					chatUi.SetAccessBlocked();
				}
			};
			chatUi.MessageSubmitted += delegate(string message)
			{
				_bridge.SendChat(message);
			};
			_bridge.Start();
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

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

		private void Update()
		{
			_bridge?.Tick();
		}

		internal static string GetLocalPlayerName()
		{
			try
			{
				Type type = null;
				Type type2 = null;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					if ((object)type == null)
					{
						type = assembly.GetType("SemiFunc");
					}
					if ((object)type2 == null)
					{
						type2 = assembly.GetType("PlayerAvatar");
					}
					if (type != null && type2 != null)
					{
						break;
					}
				}
				if (type == null || type2 == null)
				{
					return "Player";
				}
				object obj = type2.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) ?? type2.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null);
				return (type.GetMethod("PlayerGetName", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(null, new object[1] { obj }))?.ToString() ?? "Player";
			}
			catch
			{
				return "Player";
			}
		}

		private void OnDestroy()
		{
			_bridge?.Dispose();
			Unpatch();
		}
	}
}