Skip to content

immcrab/Lasting-Utilla

Ownership not verified 1
Open on GitHub

Viewing main at commit a6a25ac430“Add files via upload”· 11 months ago

289 lines · 13 KBRaw on GitHub
// Decompiled with JetBrains decompiler
// Type: Utilla.Behaviours.GamemodeManager
// Assembly: Utilla, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: FDD08D98-E155-49FA-85BC-1930928C3BAA
// Assembly location: C:\Program Files (x86)\Steam\steamapps\common\Gorilla Tag\BepInEx\plugins\Utilla\Utilla.dll

using BepInEx;
using BepInEx.Bootstrap;
using GorillaGameModes;
using GorillaNetworking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using UnityEngine;
using Utilla.Attributes;
using Utilla.Models;
using Utilla.Tools;
using Utilla.Utils;

#nullable disable
namespace Utilla.Behaviours;

internal class GamemodeManager : MonoBehaviour
{
  public Dictionary<GameModeType, Gamemode> DefaultGameModesPerMode = new Dictionary<GameModeType, Gamemode>();
  public Dictionary<GameModeType, Gamemode> ModdedGamemodesPerMode = new Dictionary<GameModeType, Gamemode>();
  public List<Gamemode> CustomGameModes;
  private GameObject customGameModeContainer;
  private List<PluginInfo> pluginInfos;
  private List<string> gtGameModeNames;

  public static GamemodeManager Instance { get; private set; }

  public static bool HasInstance
  {
    get => Object.op_Inequality((Object) GamemodeManager.Instance, (Object) null);
  }

  public static bool Initialized => GamemodeManager.InitializeTask.Task.IsCompleted;

  public static TaskCompletionSource<GamemodeManager> InitializeTask { get; private set; } = new TaskCompletionSource<GamemodeManager>();

  public List<Gamemode> Gamemodes { get; private set; }

  public List<Gamemode> ModdedGamemodes { get; private set; }

  public void Awake()
  {
    if (Object.op_Inequality((Object) GamemodeManager.Instance, (Object) null) && Object.op_Inequality((Object) GamemodeManager.Instance, (Object) this))
    {
      Object.Destroy((Object) this);
    }
    else
    {
      GamemodeManager.Instance = this;
      Events.RoomJoined += new EventHandler<Events.RoomJoinedArgs>(this.OnRoomJoin);
      Events.RoomLeft += new EventHandler<Events.RoomJoinedArgs>(this.OnRoomLeft);
    }
  }

  public void Start()
  {
    if (GamemodeManager.InitializeTask.Task.IsCompleted)
      return;
    this.gtGameModeNames = GameMode.gameModeNames;
    this.customGameModeContainer = new GameObject("Utilla Custom GameModes");
    this.customGameModeContainer.transform.SetParent(((Component) GameMode.instance).gameObject.transform);
    string currentGameMode = PlayerPrefs.GetString("currentGameMode", ((GameModeType) 1).ToString());
    GorillaComputer.instance.currentGameMode.Value = currentGameMode;
    GameModeType[] array = Enum.GetValues(typeof (GameModeType)).Cast<GameModeType>().ToArray<GameModeType>();
    for (int index = 0; index < array.Length && index != 12; ++index)
    {
      GameModeType gameModeType = (GameModeType) (int) array[index];
      if (this.DefaultGameModesPerMode.TryAdd(gameModeType, new Gamemode(gameModeType)))
        this.ModdedGamemodesPerMode.Add(gameModeType, new Gamemode("MODDED_", "Modded " + GameModeUtils.GetGameModeName(gameModeType), new GameModeType?(gameModeType)));
    }
    Logging.Info((object) ("Modded Game Modes: " + string.Join(", ", this.ModdedGamemodesPerMode.Select<KeyValuePair<GameModeType, Gamemode>, Gamemode>((Func<KeyValuePair<GameModeType, Gamemode>, Gamemode>) (item => item.Value)).Select<Gamemode, string>((Func<Gamemode, string>) (mode => mode.DisplayName)).Select<string, string>((Func<string, string>) (displayName => $"\"{displayName}\"")))));
    this.ModdedGamemodes = this.ModdedGamemodesPerMode.Values.ToList<Gamemode>();
    GTZone startZone = PhotonNetworkController.Instance.StartZone;
    UtillaGamemodeSelector gamemodeSelector;
    if (!UtillaGamemodeSelector.SelectorLookup.TryGetValue(startZone, out gamemodeSelector))
    {
      Logging.Fatal((object) $"Game Mode Selector not found for {EnumUtilExt.GetName<GTZone>(startZone)}!!");
      Logging.Info((object) string.Join<KeyValuePair<GTZone, UtillaGamemodeSelector>>(Environment.NewLine, (IEnumerable<KeyValuePair<GTZone, UtillaGamemodeSelector>>) UtillaGamemodeSelector.SelectorLookup));
    }
    else
    {
      this.Gamemodes = this.DefaultGameModesPerMode.Values.ToList<Gamemode>();
      this.pluginInfos = this.GetPluginInfos();
      this.CustomGameModes = this.GetGamemodes(this.pluginInfos);
      Logging.Info((object) ("Custom Game Modes: " + string.Join(", ", this.CustomGameModes.Select<Gamemode, string>((Func<Gamemode, string>) (mode => mode.DisplayName)).Select<string, string>((Func<string, string>) (displayName => $"\"{displayName}\"")))));
      this.Gamemodes.AddRange(this.ModdedGamemodes.Concat<Gamemode>((IEnumerable<Gamemode>) this.CustomGameModes));
      this.Gamemodes.ForEach(new Action<Gamemode>(this.AddGamemodeToPrefabPool));
      Logging.Info((object) ("Game Modes: " + string.Join(", ", this.Gamemodes.Select<Gamemode, string>((Func<Gamemode, string>) (mode => mode.DisplayName)).Select<string, string>((Func<string, string>) (displayName => $"\"{displayName}\"")))));
      gamemodeSelector.CheckGameMode();
      currentGameMode = GorillaComputer.instance.currentGameMode.Value;
      int pageCapacity = gamemodeSelector.PageCapacity;
      List<Gamemode> selectorGameModes = gamemodeSelector.GetSelectorGameModes();
      int index = selectorGameModes.FindIndex((Predicate<Gamemode>) (gm => gm.ID == currentGameMode));
      gamemodeSelector.PageCount = Mathf.CeilToInt((float) selectorGameModes.Count / (float) pageCapacity);
      gamemodeSelector.CurrentPage = index == -1 || index >= selectorGameModes.Count ? 0 : Mathf.FloorToInt((float) index / (float) pageCapacity);
      gamemodeSelector.ShowPage();
      GamemodeManager.InitializeTask.SetResult(this);
    }
  }

  public List<Gamemode> GetGamemodes(List<PluginInfo> infos)
  {
    List<Gamemode> gamemodes = new List<Gamemode>();
    HashSet<Gamemode> collection = new HashSet<Gamemode>();
    foreach (PluginInfo info in infos)
      collection.UnionWith((IEnumerable<Gamemode>) info.Gamemodes);
    foreach (Gamemode moddedGamemode in this.ModdedGamemodes)
      collection.Remove(moddedGamemode);
    gamemodes.AddRange((IEnumerable<Gamemode>) collection);
    return gamemodes;
  }

  private List<PluginInfo> GetPluginInfos()
  {
    List<PluginInfo> pluginInfos = new List<PluginInfo>();
    foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
    {
      if (pluginInfo.Value != null)
      {
        BaseUnityPlugin instance = pluginInfo.Value.Instance;
        if (instance != null)
        {
          Type type = instance.GetType();
          IEnumerable<Gamemode> gamemodes = (IEnumerable<Gamemode>) this.GetGamemodes(type);
          if (gamemodes.Any<Gamemode>())
            pluginInfos.Add(new PluginInfo()
            {
              Plugin = instance,
              Gamemodes = gamemodes.ToArray<Gamemode>(),
              OnGamemodeJoin = this.CreateJoinLeaveAction(instance, type, typeof (ModdedGamemodeJoinAttribute)),
              OnGamemodeLeave = this.CreateJoinLeaveAction(instance, type, typeof (ModdedGamemodeLeaveAttribute))
            });
        }
      }
    }
    return pluginInfos;
  }

  private Action<string> CreateJoinLeaveAction(
    BaseUnityPlugin plugin,
    Type baseType,
    Type attribute)
  {
    ParameterExpression parameterExpression = Expression.Parameter(typeof (string));
    ParameterExpression[] parameterExpressionArray = new ParameterExpression[1]
    {
      parameterExpression
    };
    ConstantExpression instance = Expression.Constant((object) plugin);
    BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
    Action<string> joinLeaveAction = (Action<string>) null;
    foreach (MethodInfo method in ((IEnumerable<MethodInfo>) baseType.GetMethods(bindingAttr)).Where<MethodInfo>((Func<MethodInfo, bool>) (m => m.GetCustomAttribute(attribute) != null)))
    {
      ParameterInfo[] parameters = method.GetParameters();
      MethodCallExpression body;
      if (parameters.Length == 0)
        body = Expression.Call((Expression) instance, method);
      else if (parameters.Length == 1 && parameters[0].ParameterType == typeof (string))
        body = Expression.Call((Expression) instance, method, (Expression) parameterExpression);
      else
        continue;
      joinLeaveAction += Expression.Lambda<Action<string>>((Expression) body, parameterExpressionArray).Compile();
    }
    return joinLeaveAction;
  }

  private HashSet<Gamemode> GetGamemodes(Type type)
  {
    IEnumerable<ModdedGamemodeAttribute> customAttributes = type.GetCustomAttributes<ModdedGamemodeAttribute>();
    HashSet<Gamemode> gamemodes = new HashSet<Gamemode>();
    if (customAttributes != null)
    {
      foreach (ModdedGamemodeAttribute gamemodeAttribute in customAttributes)
      {
        if (gamemodeAttribute.gamemode != null)
          gamemodes.Add(gamemodeAttribute.gamemode);
        else
          gamemodes.UnionWith((IEnumerable<Gamemode>) this.ModdedGamemodes);
      }
    }
    return gamemodes;
  }

  private void AddGamemodeToPrefabPool(Gamemode gamemode)
  {
    if ((object) gamemode.GameManager == null)
      return;
    if (GameMode.gameModeKeyByName.ContainsKey(gamemode.ID))
    {
      Logging.Warning((object) ("Game Mode already exists: has ID " + gamemode.ID));
    }
    else
    {
      Type gameManager = gamemode.GameManager;
      if ((object) gameManager == null || !gameManager.IsSubclassOf(typeof (GorillaGameManager)))
      {
        GameModeType? baseGamemode = gamemode.BaseGamemode;
        if (!baseGamemode.HasValue)
        {
          Logging.Warning((object) ("Game Mode not made cuz lack of info: has ID " + gamemode.ID));
        }
        else
        {
          GameMode.gameModeKeyByName[gamemode.ID] = (int) baseGamemode.Value;
          this.gtGameModeNames.Add(gamemode.ID);
        }
      }
      else
      {
        GameObject gameObject = new GameObject($"{gamemode.ID}: {gameManager.Name}");
        gameObject.SetActive(false);
        GorillaGameManager gorillaGameManager = gameObject.AddComponent(gameManager) as GorillaGameManager;
        int key = (int) gorillaGameManager.GameType();
        if (GameMode.gameModeTable.ContainsKey(key))
        {
          Logging.Error((object) $"Game Mode with name '{GameMode.gameModeTable[key].GameModeName()}' is already using GameType '{key}'.");
          Object.Destroy((Object) gameObject);
        }
        else
        {
          GameMode.gameModeTable[key] = gorillaGameManager;
          GameMode.gameModeKeyByName[gamemode.ID] = key;
          this.gtGameModeNames.Add(gamemode.ID);
          GameMode.gameModes.Add(gorillaGameManager);
          gameObject.transform.SetParent(this.customGameModeContainer.transform);
          gameObject.SetActive(true);
          if ((double) gorillaGameManager.fastJumpLimit != 0.0 && (double) gorillaGameManager.fastJumpMultiplier != 0.0)
            return;
          Logging.Warning((object) $"FAST JUMP SPEED AREN'T ASSIGNED FOR {gameManager.Name}!!! ASSIGN THESE ASAP");
          float[] numArray = gorillaGameManager.LocalPlayerSpeed();
          gorillaGameManager.fastJumpLimit = numArray[0];
          gorillaGameManager.fastJumpMultiplier = numArray[1];
        }
      }
    }
  }

  internal void OnRoomJoin(object sender, Events.RoomJoinedArgs args)
  {
    string gamemode = args.Gamemode;
    Logging.Info((object) ("Joined room: with game mode " + gamemode));
    foreach (PluginInfo pluginInfo in this.pluginInfos)
    {
      Logging.Info((object) $"Plugin {pluginInfo.Plugin.Info.Metadata.Name}: {string.Join(", ", ((IEnumerable<Gamemode>) pluginInfo.Gamemodes).Select<Gamemode, string>((Func<Gamemode, string>) (gm => gm.ID)))}");
      try
      {
        Action<string> onGamemodeJoin = pluginInfo.OnGamemodeJoin;
        if (onGamemodeJoin != null)
          onGamemodeJoin(gamemode);
        Logging.Message((object) "Plugin is suitable for game mode");
      }
      catch (Exception ex)
      {
        Logging.Fatal((object) "Join action could not be called");
        Logging.Error((object) ex);
      }
    }
  }

  internal void OnRoomLeft(object sender, Events.RoomJoinedArgs args)
  {
    string gamemode = args.Gamemode;
    Logging.Info((object) ("Left room: with game mode " + gamemode));
    foreach (PluginInfo pluginInfo in this.pluginInfos)
    {
      try
      {
        Action<string> onGamemodeLeave = pluginInfo.OnGamemodeLeave;
        if (onGamemodeLeave != null)
          onGamemodeLeave(gamemode);
      }
      catch (Exception ex)
      {
        Logging.Fatal((object) "Leave action could not be called");
        Logging.Error((object) ex);
      }
    }
  }
}

Code is shown from GitHub as-is. Linking a repository doesn’t prove that a release file on Canopy was built from it.