using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using MenuLib;
using MenuLib.MonoBehaviors;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
[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("RED")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+aaa6ba81a3622ca3cfb7a1081aceefda53783ded")]
[assembly: AssemblyProduct("SharePermissions")]
[assembly: AssemblyTitle("SharePermissions")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 SharePermissions
{
internal class Events : IOnEventCallback
{
internal bool registered = false;
internal string clientRandomString = string.Empty;
private static Random random = new Random();
internal const byte EventCode = 184;
internal static Events instance { get; private set; } = null;
public Events()
{
instance = this;
if (!registered)
{
PhotonNetwork.AddCallbackTarget((object)this);
registered = true;
}
}
public static void Init()
{
if (instance == null)
{
new Events();
}
}
internal static void SendCommand(string command, string secret, string fromSteamId, object[] args, ReceiverGroup receiverGroup)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: 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_0062: 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_0071: Expected O, but got Unknown
SharePermissions.Logger.LogInfo((object)("Send command: " + command + "; to: " + ((object)(ReceiverGroup)(ref receiverGroup)).ToString()));
object[] array = new object[3 + args.Length];
array[0] = command;
array[1] = ComputeSha256Hash(secret + fromSteamId);
array[2] = fromSteamId;
args.CopyTo(array, 3);
PhotonNetwork.RaiseEvent((byte)184, (object)array, new RaiseEventOptions
{
Receivers = receiverGroup
}, SendOptions.SendReliable);
}
private static string ComputeSha256Hash(string rawData)
{
using SHA256 sHA = SHA256.Create();
byte[] array = sHA.ComputeHash(Encoding.UTF8.GetBytes(rawData));
StringBuilder stringBuilder = new StringBuilder();
byte[] array2 = array;
foreach (byte b in array2)
{
stringBuilder.Append(b.ToString("x2"));
}
return stringBuilder.ToString();
}
public void OnEvent(EventData photonEvent)
{
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
if (photonEvent.Code != 184)
{
return;
}
object[] array = (object[])photonEvent.CustomData;
int sender = photonEvent.Sender;
Room currentRoom = PhotonNetwork.CurrentRoom;
Player val = ((currentRoom != null) ? currentRoom.GetPlayer(sender, false) : null);
string text = null;
bool flag = val != null && val.IsMasterClient;
if (val != null)
{
foreach (PlayerAvatar item in SemiFunc.PlayerGetAll())
{
PhotonView val2 = ((item != null) ? ((Component)item).GetComponent<PhotonView>() : null);
if ((Object)(object)val2 != (Object)null && val2.Owner != null && val2.Owner.ActorNumber == sender)
{
text = SemiFunc.PlayerGetSteamID(item);
break;
}
}
}
string text2 = array[0].ToString();
if (!SemiFunc.IsMasterClient())
{
if (text2 == "InitModeratorAck" && flag)
{
string steamId = array[3].ToString();
Moderators.Instance.AddModerator(steamId);
}
}
else
{
if (array.Length < 3)
{
return;
}
string value = array[1].ToString();
string nickName = val.NickName;
string text3 = ComputeSha256Hash(SharePermissions.SecretCode.Value + text);
if (text == null)
{
return;
}
SteamId val3 = default(SteamId);
if (ulong.TryParse(text, out var result))
{
SteamId val4 = default(SteamId);
val4.Value = result;
val3 = val4;
}
if (!((SteamId)(ref val3)).IsValid)
{
SharePermissions.Logger.LogWarning((object)("Invalid SteamID received in event from: " + nickName + " (" + text + ")"));
return;
}
if (SharePermissions.SecretCode == null || !text3.Equals(value))
{
SharePermissions.Logger.LogWarning((object)("Secret code is not equal, from: " + nickName + " (" + text + "); (your secret: " + text3 + ")"));
return;
}
switch (text2)
{
case "KickPlayer":
{
string text7 = array[3].ToString();
string text8 = array[4].ToString();
PlayerAvatar val6 = SemiFunc.PlayerGetFromSteamID(text7);
PhotonView val7 = ((val6 != null) ? ((Component)val6).GetComponent<PhotonView>() : null);
bool flag2 = (Object)(object)val7 != (Object)null && val7.Owner != null && val7.Owner.IsMasterClient;
bool flag3 = Moderators.Instance.IsModerator(text7);
if (!flag2 && !flag3)
{
SharePermissions.LogWrite("Banning request " + SemiFunc.PlayerGetName(val6) + " (" + text7 + ") from player:" + nickName + "(" + text + ")");
SharePermissions.Logger.LogInfo((object)("Banning request " + SemiFunc.PlayerGetName(val6) + " (" + text7 + ") from player:" + nickName + "(" + text + ")"));
if (text8 == "kick")
{
NetworkManager.instance.KickPlayer(val6);
}
else
{
NetworkManager.instance.BanPlayer(val6);
}
}
else
{
SharePermissions.Logger.LogWarning((object)("Ignoring banning request for master client or moderator " + SemiFunc.PlayerGetName(val6) + " (" + text7 + ") from player:" + nickName + "(" + text + ")"));
}
break;
}
case "KickGhostPlayer":
{
string text4 = array[3].ToString();
string text5 = array[4].ToString();
if (int.TryParse(text4, out var result2))
{
Room currentRoom2 = PhotonNetwork.CurrentRoom;
Player val5 = ((currentRoom2 != null) ? currentRoom2.GetPlayer(result2, false) : null);
if (val5 != null)
{
if (val5.IsMasterClient)
{
SharePermissions.Logger.LogWarning((object)$"Ignoring ghost kick request for master client (ActorNumber: {result2}) from: {nickName}");
break;
}
string text6 = PlayerSteamIdCache.Instance.GetSteamId(result2) ?? val5.UserId;
if (!string.IsNullOrEmpty(text6) && Moderators.Instance.IsModerator(text6))
{
SharePermissions.Logger.LogWarning((object)$"Ignoring ghost kick request for moderator (ActorNumber: {result2}, SteamID: {text6}) from: {nickName}");
break;
}
PhotonNetwork.CloseConnection(val5);
SharePermissions.LogWrite(string.Format("Ghost player kicked (ActorNumber: {0}, Name: {1}, SteamID: {2}) by: {3} ({4})", result2, val5.NickName, text6 ?? "unknown", nickName, text));
SharePermissions.Logger.LogInfo((object)string.Format("Ghost player connection closed: {0} (ActorNumber: {1}, SteamID: {2})", val5.NickName, result2, text6 ?? "unknown"));
}
else
{
SharePermissions.Logger.LogWarning((object)$"Ghost player with ActorNumber {result2} not found");
}
}
else
{
SharePermissions.Logger.LogWarning((object)("Invalid ActorNumber received for KickGhostPlayer: " + text4));
}
break;
}
case "InitModerator":
SharePermissions.Logger.LogInfo((object)("Network event: InitModerator command received for steamId: " + text));
Moderators.Instance.AddModerator(text);
SendCommand("InitModeratorAck", "", SemiFunc.PlayerGetSteamID(PlayerAvatar.instance), new object[1] { text }, (ReceiverGroup)0);
break;
case "StartGame":
SharePermissions.Logger.LogInfo((object)"Network event: StartGame command received.");
SharePermissions.LogWrite("Start game request from player:" + nickName + "(" + text + ")");
SharePermissions.StartGameClick();
break;
case "BackToLobby":
SharePermissions.Logger.LogInfo((object)"Network event: BackToLobby command received.");
SharePermissions.LogWrite("Return to lobby request from player:" + nickName + "(" + text + ")");
SharePermissions.ReturnLobbyClick();
break;
default:
SharePermissions.Logger.LogInfo((object)("Network event: Unknown command(" + array.Length + "): " + text2));
break;
}
}
}
}
internal class Menu
{
private struct PlayerValidationResult
{
public bool IsValid;
public bool IsSpoofed;
public string Reason;
}
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static BuilderDelegate <>9__3_0;
public static BuilderDelegate <>9__3_1;
public static ShouldCloseMenuDelegate <>9__13_0;
public static Func<PlayerAvatar, bool> <>9__13_1;
internal void <Init>b__3_0(Transform parent)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
REPOButton val = MenuAPI.CreateREPOButton("Mod", (Action)openPlayerListMenu, parent, new Vector2(306f, 12f));
((TMP_Text)val.labelTMP).fontSize = 18f;
}
internal void <Init>b__3_1(Transform parent)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
REPOButton val = MenuAPI.CreateREPOButton("Mod", (Action)openPlayerListMenu, parent, new Vector2(166f, 86f));
((TMP_Text)val.labelTMP).fontSize = 18f;
}
internal bool <openPlayerListMenu>b__13_0()
{
return false;
}
internal bool <openPlayerListMenu>b__13_1(PlayerAvatar pa)
{
return (Object)(object)pa != (Object)null;
}
}
[CompilerGenerated]
private sealed class <openPageInternal>d__21 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public REPOPopupPage page;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <openPageInternal>d__21(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.05f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
page.OpenPage(false);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static bool menuOpened;
private static REPOPopupPage kickPage;
private static MenuButtonPopUp menuButtonPopup;
public static void Init()
{
//IL_0015: 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)
//IL_0020: Expected O, but got Unknown
//IL_003a: 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_0045: Expected O, but got Unknown
object obj = <>c.<>9__3_0;
if (obj == null)
{
BuilderDelegate val = delegate(Transform parent)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
REPOButton val4 = MenuAPI.CreateREPOButton("Mod", (Action)openPlayerListMenu, parent, new Vector2(306f, 12f));
((TMP_Text)val4.labelTMP).fontSize = 18f;
};
<>c.<>9__3_0 = val;
obj = (object)val;
}
MenuAPI.AddElementToLobbyMenu((BuilderDelegate)obj);
object obj2 = <>c.<>9__3_1;
if (obj2 == null)
{
BuilderDelegate val2 = delegate(Transform parent)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
REPOButton val3 = MenuAPI.CreateREPOButton("Mod", (Action)openPlayerListMenu, parent, new Vector2(166f, 86f));
((TMP_Text)val3.labelTMP).fontSize = 18f;
};
<>c.<>9__3_1 = val2;
obj2 = (object)val2;
}
MenuAPI.AddElementToEscapeMenu((BuilderDelegate)obj2);
SharePermissions.Logger.LogInfo((object)"Inited!");
}
public static REPOPopupPage createMenu(string title)
{
REPOPopupPage val = MenuAPI.CreateREPOPopupPage(title, (PresetSide)0, false, true, -5f);
addCloseButton(val);
return val;
}
public static void toggleMenu()
{
if (!menuOpened)
{
openPlayerListMenu();
}
else
{
closePage(kickPage);
}
}
public static void addLabel(REPOPopupPage parent, string text)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
string text2 = text;
parent.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
{
//IL_000a: 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)
REPOLabel val = MenuAPI.CreateREPOLabel(text2, scrollView, default(Vector2));
return ((REPOElement)val).rectTransform;
}, 0f, 0f);
}
public static void addButton(REPOPopupPage parent, string text, Action action)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
string text2 = text;
Action action2 = action;
parent.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
REPOButton val = MenuAPI.CreateREPOButton(text2, action2, scrollView, default(Vector2));
return ((REPOElement)val).rectTransform;
}, 0f, 0f);
}
public static void addKickButton(REPOPopupPage parent, string text, string text2, Action kickAction, Action banAction)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
string text3 = text;
Action kickAction2 = kickAction;
Action banAction2 = banAction;
parent.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
{
//IL_0029: 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_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: 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)
REPOButton val = MenuAPI.CreateREPOButton(text3, (Action)delegate
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
createCustomPopupMenu("Choose punishment", new Color(1f, 0.553f, 0f), "Player " + text3, kickAction2, banAction2, "Kick", "Ban");
}, scrollView, default(Vector2));
if (text3.Length > 24)
{
Vector2 labelSize = val.GetLabelSize();
labelSize.x = 250f;
val.overrideButtonSize = labelSize;
REPOTextScroller val2 = ((Component)val.labelTMP).gameObject.AddComponent<REPOTextScroller>();
val2.maxCharacters = 24;
}
return ((REPOElement)val).rectTransform;
}, 0f, 0f);
}
public static void addPlayerActionButton(REPOPopupPage parent, string playerName, string steamId, Action kickAction, Action banAction, Action muteAction, Action unmuteAction)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Expected O, but got Unknown
string playerName2 = playerName;
string steamId2 = steamId;
Action unmuteAction2 = unmuteAction;
Action muteAction2 = muteAction;
REPOPopupPage parent2 = parent;
Action kickAction2 = kickAction;
Action banAction2 = banAction;
parent2.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
{
//IL_0029: 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_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: 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)
REPOButton val = MenuAPI.CreateREPOButton(playerName2, (Action)delegate
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
bool flag = MutedPlayers.Instance.IsMuted(steamId2);
string muteButtonText = (flag ? "Unmute" : "Mute");
Action onMuteClicked = (flag ? unmuteAction2 : muteAction2);
closePage(parent2);
createPlayerActionPopup("Player Actions", new Color(1f, 0.553f, 0f), "Player: " + playerName2, kickAction2, banAction2, onMuteClicked, muteButtonText);
}, scrollView, default(Vector2));
if (playerName2.Length > 24)
{
Vector2 labelSize = val.GetLabelSize();
labelSize.x = 250f;
val.overrideButtonSize = labelSize;
REPOTextScroller val2 = ((Component)val.labelTMP).gameObject.AddComponent<REPOTextScroller>();
val2.maxCharacters = 24;
}
return ((REPOElement)val).rectTransform;
}, 0f, 0f);
}
private static void createPlayerActionPopup(string title, Color headerColor, string message, Action onKickClicked, Action onBanClicked, Action onMuteClicked, string muteButtonText)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Expected O, but got Unknown
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Expected O, but got Unknown
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Expected O, but got Unknown
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Expected O, but got Unknown
string message2 = message;
Action onKickClicked2 = onKickClicked;
Action onBanClicked2 = onBanClicked;
string muteButtonText2 = muteButtonText;
Action onMuteClicked2 = onMuteClicked;
REPOPopupPage popupPage = MenuAPI.CreateREPOPopupPage(title, (PresetSide)0, false, true, -5f);
popupPage.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
{
//IL_000a: 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)
REPOLabel val4 = MenuAPI.CreateREPOLabel(message2, scrollView, default(Vector2));
return ((REPOElement)val4).rectTransform;
}, 0f, 0f);
popupPage.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
REPOButton val3 = MenuAPI.CreateREPOButton("Kick", (Action)delegate
{
closePage(popupPage);
onKickClicked2?.Invoke();
}, scrollView, default(Vector2));
return ((REPOElement)val3).rectTransform;
}, 0f, 0f);
popupPage.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
REPOButton val2 = MenuAPI.CreateREPOButton("Ban", (Action)delegate
{
closePage(popupPage);
onBanClicked2?.Invoke();
}, scrollView, default(Vector2));
return ((REPOElement)val2).rectTransform;
}, 0f, 0f);
popupPage.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
{
//IL_0029: 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)
REPOButton val = MenuAPI.CreateREPOButton(muteButtonText2, (Action)delegate
{
closePage(popupPage);
onMuteClicked2?.Invoke();
}, scrollView, default(Vector2));
return ((REPOElement)val).rectTransform;
}, 0f, 0f);
popupPage.AddElement((BuilderDelegate)delegate(Transform transform)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
MenuAPI.CreateREPOButton("Cancel", (Action)delegate
{
closePage(popupPage);
}, transform, new Vector2(270f, 20f));
});
openPage(popupPage);
}
public static void closePage(REPOPopupPage page)
{
menuOpened = false;
page.ClosePage(true);
MenuManager.instance.PageRemove(page.menuPage);
}
public static void addCloseButton(REPOPopupPage parent)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
REPOPopupPage parent2 = parent;
parent2.AddElement((BuilderDelegate)delegate(Transform transform)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
MenuAPI.CreateREPOButton("Close", (Action)delegate
{
closePage(parent2);
}, transform, new Vector2(270f, 20f));
});
}
private static void openPlayerListMenu()
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
//IL_05fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0608: Expected O, but got Unknown
REPOPopupPage playersMenu = createMenu("Mod menu");
PlayerAvatar instance = PlayerAvatar.instance;
string fromSteamId = SemiFunc.PlayerGetSteamID(instance);
string secret = SharePermissions.SecretCode.Value;
REPOPopupPage obj = playersMenu;
object obj2 = <>c.<>9__13_0;
if (obj2 == null)
{
ShouldCloseMenuDelegate val = () => false;
<>c.<>9__13_0 = val;
obj2 = (object)val;
}
obj.onEscapePressed = (ShouldCloseMenuDelegate)obj2;
kickPage = playersMenu;
List<PlayerAvatar> list = (from pa in Object.FindObjectsOfType<PlayerAvatar>()
where (Object)(object)pa != (Object)null
select pa).ToList();
List<PlayerAvatar> list2 = new List<PlayerAvatar>();
List<PlayerAvatar> list3 = new List<PlayerAvatar>();
HashSet<int> actorNumbersWithAvatars = new HashSet<int>();
foreach (PlayerAvatar item in list)
{
PlayerValidationResult playerValidationResult = ValidateNetworkPlayer(item);
if (playerValidationResult.IsValid)
{
list2.Add(item);
PhotonView component = ((Component)item).GetComponent<PhotonView>();
if (((component != null) ? component.Owner : null) != null)
{
actorNumbersWithAvatars.Add(component.Owner.ActorNumber);
}
}
else if (playerValidationResult.IsSpoofed)
{
list3.Add(item);
}
}
List<Player> list4 = PhotonNetwork.PlayerList.Where((Player p) => !actorNumbersWithAvatars.Contains(p.ActorNumber)).ToList();
foreach (PlayerAvatar item2 in list2)
{
try
{
string playerSteamId = SemiFunc.PlayerGetSteamID(item2);
if (string.IsNullOrEmpty(playerSteamId))
{
continue;
}
string playerDisplayName = Moderators.Instance.GetPlayerDisplayName(item2);
if (playerSteamId == fromSteamId)
{
addLabel(playersMenu, playerDisplayName + " (You)");
continue;
}
addPlayerActionButton(playersMenu, playerDisplayName, playerSteamId, delegate
{
Events.SendCommand("KickPlayer", secret, fromSteamId, new object[2] { playerSteamId, "kick" }, (ReceiverGroup)2);
closePage(playersMenu);
}, delegate
{
Events.SendCommand("KickPlayer", secret, fromSteamId, new object[2] { playerSteamId, "ban" }, (ReceiverGroup)2);
closePage(playersMenu);
}, delegate
{
MutedPlayers.Instance.MutePlayer(playerSteamId);
closePage(playersMenu);
}, delegate
{
MutedPlayers.Instance.UnmutePlayer(playerSteamId);
closePage(playersMenu);
});
}
catch (Exception ex)
{
SharePermissions.Logger.LogWarning((object)$"Failed to add player to the menu: {item2} - {ex.Message}");
}
}
if (list4.Count > 0)
{
foreach (Player ghostPlayer in list4)
{
try
{
string text = ghostPlayer.NickName ?? $"Unknown_{ghostPlayer.ActorNumber}";
int actorNumber = ghostPlayer.ActorNumber;
string text2 = PlayerSteamIdCache.Instance.GetSteamId(actorNumber) ?? ghostPlayer.UserId;
string steamNickname = GetSteamNickname(text2);
if (!string.IsNullOrEmpty(steamNickname) && steamNickname != text)
{
text = text + " (" + steamNickname + ")";
}
string text3 = "<color=#FFAA00>[GHOST]</color> " + text;
addGhostPlayerButton(playersMenu, text3, ghostPlayer, delegate
{
KickGhostPlayer(ghostPlayer, "kick");
closePage(playersMenu);
}, delegate
{
KickGhostPlayer(ghostPlayer, "ban");
closePage(playersMenu);
});
SharePermissions.Logger.LogWarning((object)string.Format("Ghost player detected: {0} (ActorNumber: {1}, SteamID: {2}, SteamNick: {3})", text, actorNumber, text2 ?? "null", steamNickname ?? "null"));
}
catch (Exception ex2)
{
SharePermissions.Logger.LogWarning((object)("Failed to add ghost player to menu: " + ex2.Message));
}
}
}
if (list3.Count > 0)
{
foreach (PlayerAvatar spoofedPlayer in list3)
{
try
{
string text4 = ((Object)spoofedPlayer).name;
string text5 = null;
string text6 = null;
try
{
text5 = SemiFunc.PlayerGetSteamID(spoofedPlayer);
text4 = SemiFunc.PlayerGetName(spoofedPlayer) ?? text4;
text6 = GetSteamNickname(text5);
}
catch
{
}
string text7 = text4;
if (!string.IsNullOrEmpty(text6) && text6 != text4)
{
text7 = text4 + " (" + text6 + ")";
}
string text8 = "<color=#FF6600>[SPOOF]</color> " + text7;
addSpoofedPlayerButton(playersMenu, text8, spoofedPlayer, delegate
{
KickSpoofedPlayer(spoofedPlayer, "kick");
closePage(playersMenu);
}, delegate
{
KickSpoofedPlayer(spoofedPlayer, "ban");
closePage(playersMenu);
});
SharePermissions.Logger.LogWarning((object)("Spoofed player added to menu: " + text4 + " (SteamID: " + (text5 ?? "null") + ", SteamNick: " + (text6 ?? "null") + ")"));
}
catch (Exception ex3)
{
SharePermissions.Logger.LogWarning((object)("Failed to add spoofed player to menu: " + ex3.Message));
}
}
}
playersMenu.AddElement((BuilderDelegate)delegate(Transform transform)
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
if (SemiFunc.RunIsLobbyMenu())
{
MenuAPI.CreateREPOButton("Start game", (Action)delegate
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
MenuAPI.OpenPopup("Confirm", new Color(1f, 0.553f, 0f), "Start the game or maybe 5 minutes wait?", (Action)delegate
{
Events.SendCommand("StartGame", secret, fromSteamId, Array.Empty<object>(), (ReceiverGroup)2);
closePage(playersMenu);
}, (Action)null);
}, transform, new Vector2(150f, 20f));
}
else
{
MenuAPI.CreateREPOButton("Back to lobby", (Action)delegate
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
MenuAPI.OpenPopup("Confirm", new Color(1f, 0.553f, 0f), "Back to the lobby?", (Action)delegate
{
Events.SendCommand("BackToLobby", secret, fromSteamId, Array.Empty<object>(), (ReceiverGroup)2);
closePage(playersMenu);
}, (Action)null);
}, transform, new Vector2(150f, 20f));
}
});
openPage(playersMenu);
}
public static void addSpoofedPlayerButton(REPOPopupPage parent, string text, PlayerAvatar spoofedPlayer, Action kickAction, Action banAction)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
string text2 = text;
Action kickAction2 = kickAction;
Action banAction2 = banAction;
parent.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
{
//IL_0029: 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_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: 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)
REPOButton val = MenuAPI.CreateREPOButton(text2, (Action)delegate
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
createCustomPopupMenu("Suspicious Player", new Color(1f, 0.2f, 0f), "This player may be spoofed!\n" + text2, kickAction2, banAction2, "Kick", "Ban");
}, scrollView, default(Vector2));
if (text2.Length > 24)
{
Vector2 labelSize = val.GetLabelSize();
labelSize.x = 250f;
val.overrideButtonSize = labelSize;
REPOTextScroller val2 = ((Component)val.labelTMP).gameObject.AddComponent<REPOTextScroller>();
val2.maxCharacters = 24;
}
return ((REPOElement)val).rectTransform;
}, 0f, 0f);
}
private static void KickSpoofedPlayer(PlayerAvatar spoofedPlayer, string type)
{
try
{
string text = null;
try
{
text = SemiFunc.PlayerGetSteamID(spoofedPlayer);
}
catch
{
}
if (!string.IsNullOrEmpty(text))
{
string fromSteamId = SemiFunc.PlayerGetSteamID(PlayerAvatar.instance);
string value = SharePermissions.SecretCode.Value;
Events.SendCommand("KickPlayer", value, fromSteamId, new object[2] { text, type }, (ReceiverGroup)2);
SharePermissions.Logger.LogInfo((object)("Sent kick command for spoofed player via SteamID: " + text));
return;
}
PhotonView component = ((Component)spoofedPlayer).GetComponent<PhotonView>();
if ((Object)(object)component != (Object)null && component.Owner != null && SemiFunc.IsMasterClient())
{
if (type == "kick")
{
NetworkManager.instance.KickPlayer(spoofedPlayer);
}
else
{
NetworkManager.instance.BanPlayer(spoofedPlayer);
}
SharePermissions.Logger.LogInfo((object)("Kicked spoofed player directly: " + ((Object)spoofedPlayer).name));
}
else if (SemiFunc.IsMasterClient())
{
PhotonNetwork.Destroy(((Component)spoofedPlayer).gameObject);
SharePermissions.Logger.LogInfo((object)("Destroyed spoofed player object: " + ((Object)spoofedPlayer).name));
}
else
{
SharePermissions.Logger.LogWarning((object)"Cannot kick spoofed player - not master client and no valid identifiers");
}
}
catch (Exception ex)
{
SharePermissions.Logger.LogError((object)("Failed to kick spoofed player: " + ex.Message));
}
}
public static void addGhostPlayerButton(REPOPopupPage parent, string text, Player ghostPlayer, Action kickAction, Action banAction)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
string text2 = text;
Player ghostPlayer2 = ghostPlayer;
Action kickAction2 = kickAction;
Action banAction2 = banAction;
parent.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
{
//IL_0029: 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_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: 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)
REPOButton val = MenuAPI.CreateREPOButton(text2, (Action)delegate
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
string message = $"Player: {ghostPlayer2.NickName}\nActorNumber: {ghostPlayer2.ActorNumber}\nNo avatar spawned!";
createCustomPopupMenu("Ghost Player", new Color(1f, 0.67f, 0f), message, kickAction2, banAction2, "Kick", "Ban");
}, scrollView, default(Vector2));
if (text2.Length > 24)
{
Vector2 labelSize = val.GetLabelSize();
labelSize.x = 250f;
val.overrideButtonSize = labelSize;
REPOTextScroller val2 = ((Component)val.labelTMP).gameObject.AddComponent<REPOTextScroller>();
val2.maxCharacters = 24;
}
return ((REPOElement)val).rectTransform;
}, 0f, 0f);
}
private static void KickGhostPlayer(Player ghostPlayer, string type)
{
try
{
if (ghostPlayer == null)
{
SharePermissions.Logger.LogWarning((object)"Cannot kick null ghost player");
return;
}
string text = PlayerSteamIdCache.Instance.GetSteamId(ghostPlayer.ActorNumber) ?? ghostPlayer.UserId;
if (!string.IsNullOrEmpty(text))
{
PlayerAvatar val = SemiFunc.PlayerGetFromSteamID(text);
if ((Object)(object)val != (Object)null)
{
if (SemiFunc.IsMasterClient())
{
if (type == "kick")
{
NetworkManager.instance.KickPlayer(val);
}
else
{
NetworkManager.instance.BanPlayer(val);
}
SharePermissions.Logger.LogInfo((object)("Kicked ghost player via found avatar: " + ghostPlayer.NickName));
}
else
{
string fromSteamId = SemiFunc.PlayerGetSteamID(PlayerAvatar.instance);
string value = SharePermissions.SecretCode.Value;
Events.SendCommand("KickPlayer", value, fromSteamId, new object[2] { text, type }, (ReceiverGroup)2);
SharePermissions.Logger.LogInfo((object)("Sent kick command for ghost player: " + ghostPlayer.NickName));
}
return;
}
}
if (SemiFunc.IsMasterClient())
{
PhotonNetwork.CloseConnection(ghostPlayer);
SharePermissions.Logger.LogInfo((object)$"Closed connection for ghost player: {ghostPlayer.NickName} (ActorNumber: {ghostPlayer.ActorNumber})");
return;
}
string fromSteamId2 = SemiFunc.PlayerGetSteamID(PlayerAvatar.instance);
string value2 = SharePermissions.SecretCode.Value;
Events.SendCommand("KickGhostPlayer", value2, fromSteamId2, new object[2]
{
ghostPlayer.ActorNumber.ToString(),
type
}, (ReceiverGroup)2);
SharePermissions.Logger.LogInfo((object)$"Sent kick ghost command for: {ghostPlayer.NickName} (ActorNumber: {ghostPlayer.ActorNumber})");
}
catch (Exception ex)
{
SharePermissions.Logger.LogError((object)("Failed to kick ghost player: " + ex.Message));
}
}
private static string GetSteamNickname(string steamIdString)
{
//IL_002e: 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_003e: 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)
if (string.IsNullOrEmpty(steamIdString))
{
return null;
}
try
{
if (!ulong.TryParse(steamIdString, out var result))
{
return null;
}
SteamId val = default(SteamId);
val.Value = result;
SteamId val2 = val;
if (!((SteamId)(ref val2)).IsValid)
{
return null;
}
Friend val3 = default(Friend);
((Friend)(ref val3))..ctor(val2);
string name = ((Friend)(ref val3)).Name;
if (string.IsNullOrEmpty(name) || name == steamIdString)
{
return null;
}
return name;
}
catch (Exception ex)
{
SharePermissions.Logger.LogWarning((object)("Failed to get Steam nickname for " + steamIdString + ": " + ex.Message));
return null;
}
}
private static PlayerValidationResult ValidateNetworkPlayer(PlayerAvatar player)
{
//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)player == (Object)null)
{
PlayerValidationResult result = default(PlayerValidationResult);
result.IsValid = false;
result.IsSpoofed = false;
result.Reason = "Null player";
return result;
}
try
{
PhotonView component = ((Component)player).GetComponent<PhotonView>();
PlayerValidationResult result;
if ((Object)(object)component == (Object)null)
{
result = default(PlayerValidationResult);
result.IsValid = false;
result.IsSpoofed = true;
result.Reason = "No PhotonView component";
return result;
}
if (component.Owner == null)
{
result = default(PlayerValidationResult);
result.IsValid = false;
result.IsSpoofed = true;
result.Reason = "PhotonView has no owner";
return result;
}
int actorNumber = component.Owner.ActorNumber;
if (!PhotonNetwork.PlayerList.Any((Player p) => p.ActorNumber == actorNumber))
{
result = default(PlayerValidationResult);
result.IsValid = false;
result.IsSpoofed = true;
result.Reason = $"ActorNumber {actorNumber} not in PhotonNetwork.PlayerList";
return result;
}
string text = SemiFunc.PlayerGetSteamID(player);
if (string.IsNullOrEmpty(text))
{
result = default(PlayerValidationResult);
result.IsValid = false;
result.IsSpoofed = false;
result.Reason = "No Steam ID";
return result;
}
if (!ulong.TryParse(text, out var result2))
{
result = default(PlayerValidationResult);
result.IsValid = false;
result.IsSpoofed = true;
result.Reason = "Invalid Steam ID format: " + text;
return result;
}
SteamId val = default(SteamId);
val.Value = result2;
SteamId val2 = val;
if (!((SteamId)(ref val2)).IsValid)
{
result = default(PlayerValidationResult);
result.IsValid = false;
result.IsSpoofed = true;
result.Reason = "Steam ID not valid: " + text;
return result;
}
result = default(PlayerValidationResult);
result.IsValid = true;
result.IsSpoofed = false;
result.Reason = "Valid";
return result;
}
catch (Exception ex)
{
PlayerValidationResult result = default(PlayerValidationResult);
result.IsValid = false;
result.IsSpoofed = false;
result.Reason = "Exception: " + ex.Message;
return result;
}
}
[IteratorStateMachine(typeof(<openPageInternal>d__21))]
private static IEnumerator openPageInternal(REPOPopupPage page)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <openPageInternal>d__21(0)
{
page = page
};
}
public static void openPage(REPOPopupPage page)
{
menuOpened = true;
((MonoBehaviour)MenuManager.instance).StartCoroutine(openPageInternal(page));
}
private static void createCustomPopupMenu(string title, Color headerColor, string message, Action onLeftClicked, Action onRightClicked, string leftTitle = "Yes", string rightTitle = "No")
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Expected O, but got Unknown
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
//IL_009f: 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_0092: Expected O, but got Unknown
if (!Object.op_Implicit((Object)(object)menuButtonPopup))
{
menuButtonPopup = ((Component)MenuManager.instance).gameObject.AddComponent<MenuButtonPopUp>();
}
menuButtonPopup.option1Event = new UnityEvent();
menuButtonPopup.option2Event = new UnityEvent();
if (onLeftClicked != null)
{
menuButtonPopup.option1Event.AddListener(new UnityAction(onLeftClicked.Invoke));
}
if (onRightClicked != null)
{
menuButtonPopup.option2Event.AddListener(new UnityAction(onRightClicked.Invoke));
}
MenuManager.instance.PagePopUpTwoOptions(menuButtonPopup, title, headerColor, message, leftTitle, rightTitle, true);
}
}
[HarmonyPatch(typeof(LoadBalancingClient))]
internal class LoadBalancingClientPatch
{
private const byte VoiceEventCode = 203;
[HarmonyPatch("OnEvent")]
[HarmonyPrefix]
private static bool OnEvent_Prefix(EventData photonEvent)
{
if (photonEvent.Code == 203)
{
int sender = photonEvent.Sender;
if (MutedPlayers.Instance.IsActorMuted(sender))
{
return false;
}
Room currentRoom = PhotonNetwork.CurrentRoom;
Player val = ((currentRoom != null) ? currentRoom.GetPlayer(sender, false) : null);
if (val != null)
{
foreach (PlayerAvatar item in SemiFunc.PlayerGetAll())
{
PhotonView val2 = ((item != null) ? ((Component)item).GetComponent<PhotonView>() : null);
if ((Object)(object)val2 != (Object)null && val2.Owner != null && val2.Owner.ActorNumber == sender)
{
string text = SemiFunc.PlayerGetSteamID(item);
if (!string.IsNullOrEmpty(text))
{
MutedPlayers.Instance.RegisterActorNumber(text, sender);
if (MutedPlayers.Instance.IsMuted(text))
{
return false;
}
break;
}
break;
}
}
}
}
return true;
}
}
internal class Moderators
{
private static Moderators _instance;
private HashSet<string> moderatorSteamIds = new HashSet<string>();
private const string ModeratorIcon = "[M]";
private const string HostIcon = "[H]";
internal static Moderators Instance
{
get
{
if (_instance == null)
{
_instance = new Moderators();
}
return _instance;
}
}
public Moderators()
{
_instance = this;
}
public void AddModerator(string steamId)
{
if (!string.IsNullOrEmpty(steamId) && !moderatorSteamIds.Contains(steamId))
{
moderatorSteamIds.Add(steamId);
SharePermissions.Logger.LogInfo((object)("Added moderator: " + steamId));
}
}
public void RemoveModerator(string steamId)
{
if (moderatorSteamIds.Contains(steamId))
{
moderatorSteamIds.Remove(steamId);
SharePermissions.Logger.LogInfo((object)("Removed moderator: " + steamId));
}
}
public bool IsModerator(string steamId)
{
return !string.IsNullOrEmpty(steamId) && moderatorSteamIds.Contains(steamId);
}
public bool IsModerator(PlayerAvatar player)
{
if ((Object)(object)player == (Object)null)
{
return false;
}
string steamId = SemiFunc.PlayerGetSteamID(player);
return IsModerator(steamId);
}
public bool IsHost(PlayerAvatar player)
{
if ((Object)(object)player == (Object)null)
{
return false;
}
PhotonView component = ((Component)player).GetComponent<PhotonView>();
return (Object)(object)component != (Object)null && component.Owner != null && component.Owner.IsMasterClient;
}
public string GetPlayerDisplayName(PlayerAvatar player)
{
if ((Object)(object)player == (Object)null)
{
return "";
}
string text = SemiFunc.PlayerGetName(player);
string playerIcon = GetPlayerIcon(player);
return string.IsNullOrEmpty(playerIcon) ? text : ("<color=#FFD700>" + playerIcon + "</color> " + text);
}
public string GetPlayerIcon(PlayerAvatar player)
{
if ((Object)(object)player == (Object)null)
{
return "";
}
if (IsHost(player))
{
return "[H]";
}
if (IsModerator(player))
{
return "[M]";
}
return "";
}
public string GetPlayerEmoji(PlayerAvatar player)
{
if ((Object)(object)player == (Object)null)
{
return "";
}
if (IsHost(player))
{
return "[H]";
}
if (IsModerator(player))
{
return "[M]";
}
return "";
}
public List<string> GetAllModerators()
{
return moderatorSteamIds.ToList();
}
public void ClearModerators()
{
moderatorSteamIds.Clear();
SharePermissions.Logger.LogInfo((object)"Cleared all moderators");
}
public int GetModeratorCount()
{
return moderatorSteamIds.Count;
}
public bool HasPermissions(PlayerAvatar player)
{
return IsHost(player) || IsModerator(player);
}
public bool HasPermissions(string steamId)
{
if (string.IsNullOrEmpty(steamId))
{
return false;
}
PlayerAvatar val = SemiFunc.PlayerGetFromSteamID(steamId);
if ((Object)(object)val == (Object)null)
{
return IsModerator(steamId);
}
return HasPermissions(val);
}
public static void Init()
{
if (_instance == null)
{
new Moderators();
SharePermissions.Logger.LogInfo((object)"Moderators system initialized");
}
}
}
internal class MutedPlayers
{
private static MutedPlayers _instance;
private HashSet<string> mutedSteamIds = new HashSet<string>();
private Dictionary<string, int> steamIdToActorNumber = new Dictionary<string, int>();
internal static MutedPlayers Instance
{
get
{
if (_instance == null)
{
_instance = new MutedPlayers();
}
return _instance;
}
}
public MutedPlayers()
{
_instance = this;
}
public void MutePlayer(string steamId)
{
if (!string.IsNullOrEmpty(steamId) && !mutedSteamIds.Contains(steamId))
{
mutedSteamIds.Add(steamId);
SharePermissions.Logger.LogInfo((object)("Muted player: " + steamId));
}
}
public void UnmutePlayer(string steamId)
{
if (mutedSteamIds.Contains(steamId))
{
mutedSteamIds.Remove(steamId);
SharePermissions.Logger.LogInfo((object)("Unmuted player: " + steamId));
}
}
public bool IsMuted(string steamId)
{
return !string.IsNullOrEmpty(steamId) && mutedSteamIds.Contains(steamId);
}
public bool IsMuted(PlayerAvatar player)
{
if ((Object)(object)player == (Object)null)
{
return false;
}
string steamId = SemiFunc.PlayerGetSteamID(player);
return IsMuted(steamId);
}
public void ToggleMute(string steamId)
{
if (IsMuted(steamId))
{
UnmutePlayer(steamId);
}
else
{
MutePlayer(steamId);
}
}
public void RegisterActorNumber(string steamId, int actorNumber)
{
if (!string.IsNullOrEmpty(steamId))
{
steamIdToActorNumber[steamId] = actorNumber;
}
}
public bool IsActorMuted(int actorNumber)
{
foreach (KeyValuePair<string, int> item in steamIdToActorNumber)
{
if (item.Value == actorNumber && mutedSteamIds.Contains(item.Key))
{
return true;
}
}
return false;
}
public string GetSteamIdByActorNumber(int actorNumber)
{
foreach (KeyValuePair<string, int> item in steamIdToActorNumber)
{
if (item.Value == actorNumber)
{
return item.Key;
}
}
return null;
}
public List<string> GetAllMutedPlayers()
{
return mutedSteamIds.ToList();
}
public void ClearMutedPlayers()
{
mutedSteamIds.Clear();
steamIdToActorNumber.Clear();
SharePermissions.Logger.LogInfo((object)"Cleared all muted players");
}
public int GetMutedCount()
{
return mutedSteamIds.Count;
}
public static void Init()
{
if (_instance == null)
{
new MutedPlayers();
SharePermissions.Logger.LogInfo((object)"MutedPlayers system initialized");
}
}
}
[HarmonyPatch(typeof(NetworkConnect))]
internal class NetworkConnectPatch
{
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void Start_Postfix()
{
Events.Init();
PlayerSteamIdCache.Init();
}
[HarmonyPatch("OnCreatedRoom")]
[HarmonyPostfix]
private static void OnCreatedRoom_Postfix()
{
SharePermissions.Logger.LogInfo((object)"onCreateRoom");
}
[HarmonyPatch("OnJoinedRoom")]
[HarmonyPostfix]
private static void OnJoinedRoom_Postfix()
{
SharePermissions.Logger.LogInfo((object)"onJoinRoom");
PlayerSteamIdCache.Instance.RefreshFromAvatars();
if (!SemiFunc.IsMasterClient())
{
PlayerAvatar instance = PlayerAvatar.instance;
string fromSteamId = SemiFunc.PlayerGetSteamID(instance);
string value = SharePermissions.SecretCode.Value;
Events.SendCommand("InitModerator", value, fromSteamId, Array.Empty<object>(), (ReceiverGroup)2);
}
}
[HarmonyPatch("OnDisconnected")]
[HarmonyPostfix]
private static void OnDisconnected_Postfix()
{
SharePermissions.Logger.LogInfo((object)"Left room - clearing all moderators");
Moderators.Instance.ClearModerators();
MutedPlayers.Instance.ClearMutedPlayers();
PlayerSteamIdCache.Instance.Clear();
}
}
[HarmonyPatch(typeof(NetworkManager))]
internal class NetworkManagerPatch
{
[HarmonyPatch("OnPlayerEnteredRoom")]
[HarmonyPostfix]
private static void OnPlayerEnteredRoom_Postfix(Player newPlayer)
{
if (newPlayer == null)
{
return;
}
foreach (PlayerAvatar item in SemiFunc.PlayerGetAll())
{
if ((Object)(object)item == (Object)null)
{
continue;
}
PhotonView component = ((Component)item).GetComponent<PhotonView>();
if (((component != null) ? component.Owner : null) == null || component.Owner.ActorNumber != newPlayer.ActorNumber)
{
continue;
}
string text = SemiFunc.PlayerGetSteamID(item);
if (!string.IsNullOrEmpty(text))
{
PlayerSteamIdCache.Instance.RegisterPlayer(newPlayer.ActorNumber, text);
}
break;
}
}
[HarmonyPatch("OnPlayerLeftRoom")]
[HarmonyPostfix]
private static void OnPlayerLeftRoom_Postfix(Player otherPlayer)
{
if (otherPlayer == null)
{
return;
}
string text = PlayerSteamIdCache.Instance.GetSteamId(otherPlayer.ActorNumber) ?? otherPlayer.UserId;
if (!string.IsNullOrEmpty(text))
{
if (Moderators.Instance.IsModerator(text))
{
Moderators.Instance.RemoveModerator(text);
SharePermissions.Logger.LogInfo((object)("Player " + otherPlayer.NickName + " (" + text + ") left - removed moderator status"));
}
if (MutedPlayers.Instance.IsMuted(text))
{
MutedPlayers.Instance.UnmutePlayer(text);
SharePermissions.Logger.LogInfo((object)("Player " + otherPlayer.NickName + " (" + text + ") left - removed mute status"));
}
}
PlayerSteamIdCache.Instance.UnregisterPlayer(otherPlayer.ActorNumber);
}
}
internal class PlayerSteamIdCache
{
private static PlayerSteamIdCache _instance;
private readonly Dictionary<int, string> actorToSteamId = new Dictionary<int, string>();
internal static PlayerSteamIdCache Instance
{
get
{
if (_instance == null)
{
_instance = new PlayerSteamIdCache();
}
return _instance;
}
}
public PlayerSteamIdCache()
{
_instance = this;
}
public void RegisterPlayer(int actorNumber, string steamId)
{
if (actorNumber > 0 && !string.IsNullOrEmpty(steamId))
{
if (actorToSteamId.TryGetValue(actorNumber, out string value) && value != steamId)
{
SharePermissions.Logger.LogWarning((object)$"ActorNumber {actorNumber} already registered with different SteamID: {value} -> {steamId}");
}
actorToSteamId[actorNumber] = steamId;
SharePermissions.Logger.LogInfo((object)$"Registered player mapping: ActorNumber {actorNumber} -> SteamID {steamId}");
}
}
public string GetSteamId(int actorNumber)
{
if (actorToSteamId.TryGetValue(actorNumber, out string value))
{
return value;
}
return null;
}
public string GetSteamId(Player player)
{
if (player == null)
{
return null;
}
return GetSteamId(player.ActorNumber);
}
public void UnregisterPlayer(int actorNumber)
{
if (actorToSteamId.Remove(actorNumber))
{
SharePermissions.Logger.LogInfo((object)$"Unregistered player mapping for ActorNumber {actorNumber}");
}
}
public void Clear()
{
actorToSteamId.Clear();
SharePermissions.Logger.LogInfo((object)"Cleared player Steam ID cache");
}
public void RefreshFromAvatars()
{
List<PlayerAvatar> list = SemiFunc.PlayerGetAll();
if (list == null)
{
return;
}
foreach (PlayerAvatar item in list)
{
if ((Object)(object)item == (Object)null)
{
continue;
}
PhotonView component = ((Component)item).GetComponent<PhotonView>();
if (((component != null) ? component.Owner : null) != null)
{
int actorNumber = component.Owner.ActorNumber;
string text = SemiFunc.PlayerGetSteamID(item);
if (!string.IsNullOrEmpty(text))
{
RegisterPlayer(actorNumber, text);
}
}
}
}
public static void Init()
{
if (_instance == null)
{
new PlayerSteamIdCache();
SharePermissions.Logger.LogInfo((object)"PlayerSteamIdCache initialized");
}
}
}
[HarmonyPatch(typeof(RunManager))]
internal class RunPatch
{
private static bool lastKeyState;
[HarmonyPatch("Update")]
[HarmonyPostfix]
private static void Update_Postfix(RunPatch __instance)
{
bool key = Input.GetKey((KeyCode)32);
if (!lastKeyState && key)
{
if (SemiFunc.RunIsLobbyMenu())
{
Menu.toggleMenu();
}
lastKeyState = key;
}
else if (lastKeyState && !key)
{
lastKeyState = key;
}
}
[HarmonyPrefix]
[HarmonyPatch("RestartScene")]
[HarmonyWrapSafe]
private static void RestartScene_Prefix(RunManager __instance)
{
if (SharePermissions.IsReturningToLobby && __instance.restarting && !__instance.restartingDone && (Object)(object)GameDirector.instance != (Object)null && GameDirector.instance.PlayerList.All((PlayerAvatar p) => p.outroDone))
{
SharePermissions.IsReturningToLobby = false;
NetworkManager.instance.DestroyAll();
}
}
}
[BepInPlugin("RED.SharePermissions", "SharePermissions", "1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class SharePermissions : BaseUnityPlugin
{
private static string _logPath;
public static bool IsReturningToLobby;
internal static SharePermissions Instance { get; private set; }
internal static ManualLogSource Logger => Instance._logger;
private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;
internal Harmony? Harmony { get; set; }
public static ConfigEntry<string> SecretCode { get; private set; }
private static string LogPath
{
get
{
if (!string.IsNullOrEmpty(_logPath))
{
return _logPath;
}
try
{
_logPath = Path.Combine(Paths.ConfigPath, "sharepermissions.log");
}
catch
{
_logPath = Path.Combine(Application.persistentDataPath, "sharepermissions.log");
}
return _logPath;
}
}
private void Awake()
{
Instance = this;
((Component)this).gameObject.transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
Patch();
Menu.Init();
Moderators.Init();
Configuration(((BaseUnityPlugin)this).Config);
Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
}
public static void LogWrite(string line)
{
try
{
string text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string text2 = "[" + text + "] " + line;
string directoryName = Path.GetDirectoryName(LogPath);
if (!Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
File.AppendAllText(LogPath, text2 + Environment.NewLine);
}
catch (Exception arg)
{
Logger.LogError((object)$"[SharePermissions] Log save failed: {arg}");
}
}
internal void Configuration(ConfigFile config)
{
SecretCode = config.Bind<string>("General", "SecretCode", "", "Code for share permission");
}
public static void ReturnLobbyClick()
{
IsReturningToLobby = true;
RunManager instance = RunManager.instance;
int num = ((instance.levelCurrent == instance.levelShop) ? 1 : 0);
instance.ChangeLevel(true, SemiFunc.RunIsArena(), (ChangeLevelType)3);
SemiFunc.StatSetSaveLevel(num);
instance.loadLevel = num;
StatsManager.instance.SaveFileSave();
}
public static void StartGameClick()
{
RunManager instance = RunManager.instance;
instance.ChangeLevel(false, SemiFunc.RunIsArena(), (ChangeLevelType)0);
}
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()
{
}
}
}