Example #1
0
 void Awake()
 {
     Debug.Log ("SQUARE");
     squareMatrixScript = GameObject.FindGameObjectWithTag ("Block").GetComponent<SquareMatrix> ();
     gadgetsScript = GameObject.FindGameObjectWithTag ("Gadgets").GetComponent<Gadgets> ();
     initSquare ();
     initMazeMatrix ();
 }
Example #2
0
 void Awake()
 {
     progressBar = GameObject.Find ("ProgressBar").guiTexture;
     currWidth = barWidth = Screen.width;
     barHeight = Screen.width/14;
     seconds = 60.0f;
     currWidth = barWidth;
     fadeDuration = 2.0f;
     startColor = guiTexture.color;
     endColor = Color.red;
     transform.position = Vector3.zero;
     transform.localScale = Vector3.zero;
     squareMatrixScript = GameObject.FindGameObjectWithTag ("Block").GetComponent<SquareMatrix> ();
     gadgetsScript = GameObject.FindGameObjectWithTag ("Gadgets").GetComponent<Gadgets> ();
     freezeSeconds = 0f;
 }
Example #3
0
        private bool IsRestartNeeded()
        {
            if (unpackedMods.Count > 0)
            {
                return(true);
            }
            int umfModCount = umfModEntries?.Count ?? 0;

            foreach (GadgetInfo gadget in Gadgets.ListAllGadgetInfos())
            {
                if (GadgetCoreConfig.enabledGadgets[gadget.Attribute.Name] != gadget.Gadget.Enabled)
                {
                    return(true);
                }
                if (originalConfig.ContainsKey(gadget.Attribute.Name))
                {
                    if (!originalConfig[gadget.Attribute.Name].Equals(File.ReadAllText(GadgetPaths.ConfigsPath + "/" + Gadgets.GetGadgetInfo(modIndex).Mod.Name + ".ini")))
                    {
                        return(true);
                    }
                }
            }
            if (GadgetCoreAPI.GetUMFAPI() != null)
            {
                if (!File.Exists(GadgetCoreAPI.GetUMFAPI().GetDisabledModsFile()))
                {
                    File.Create(GadgetCoreAPI.GetUMFAPI().GetDisabledModsFile()).Dispose();
                }
                string[] disabledMods = File.ReadAllLines(GadgetCoreAPI.GetUMFAPI().GetDisabledModsFile()).Where(x => !string.IsNullOrEmpty(x)).ToArray();
                for (int i = 0; i < umfModEntries.Count; i++)
                {
                    if (wasEnabled.ContainsKey(umfModEntries[i].Name))
                    {
                        if (wasEnabled[umfModEntries[i].Name] == disabledMods.Contains(umfModEntries[i].Name))
                        {
                            return(true);
                        }
                    }
                    if (originalConfig.ContainsKey(umfModEntries[i].Name))
                    {
                        if (!originalConfig[umfModEntries[i].Name].Equals(File.ReadAllText(GadgetCoreAPI.GetUMFAPI().GetConfigsPath() + "/" + umfModEntries[i].Name + ".ini")))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Example #4
0
 internal void SendRequiredModList(string modList, NetworkMessageInfo info)
 {
     try
     {
         bool       isCompatible = true;
         int        modCount     = 0;
         string[][] splitModList = string.IsNullOrEmpty(modList) ? new string[0][] : modList.Split(',').Select(x => x.Split(':')).ToArray();
         foreach (GadgetInfo mod in Gadgets.ListAllGadgetInfos().Where(x => x.Gadget.Enabled && x.Attribute.RequiredOnClients))
         {
             modCount++;
             int[] hostVersionNums   = mod.Gadget.GetModVersionString().Split('.').Select(x => int.Parse(x)).ToArray();
             int[] clientVersionNums = splitModList.SingleOrDefault(x => x[0] == mod.Attribute.Name)?[1].Split('.').Select(x => int.Parse(x)).Take(4).ToArray();
             if (clientVersionNums == null)
             {
                 isCompatible = false;
                 break;
             }
             hostVersionNums   = hostVersionNums.Concat(Enumerable.Repeat(0, 4 - hostVersionNums.Length)).ToArray();
             clientVersionNums = clientVersionNums.Concat(Enumerable.Repeat(0, 4 - clientVersionNums.Length)).ToArray();
             if (!((mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MAJOR && clientVersionNums[0] == hostVersionNums[0] && (clientVersionNums[1] > hostVersionNums[1] || (clientVersionNums[1] == hostVersionNums[1] && (clientVersionNums[2] > hostVersionNums[2] || (clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]))))) ||
                   (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MINOR && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && (clientVersionNums[2] > hostVersionNums[2] || (clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]))) ||
                   (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.NONBREAKING && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]) ||
                   (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.BUGFIX && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] == hostVersionNums[3])))
             {
                 isCompatible = false;
                 break;
             }
         }
         if (isCompatible && modCount != splitModList.Length)
         {
             isCompatible = false;
         }
         if (isCompatible)
         {
             if (string.IsNullOrEmpty(info.sender.ipAddress))
             {
                 GadgetCore.CoreLogger.Log("Self-connection succesfully established and identified.");
                 ReceiveIDMatrixData(GadgetNetwork.GenerateIDMatrixData());
             }
             else
             {
                 GadgetCore.CoreLogger.Log("A client connected with compatible mods: " + info.sender.ipAddress);
                 view.RPC("ReceiveIDMatrixData", info.sender, GadgetNetwork.GenerateIDMatrixData());
             }
         }
         else
         {
             GadgetCore.CoreLogger.LogWarning("A client tried to connect with incompatible mods: " + info.sender.ipAddress + Environment.NewLine + modList);
             if (Network.isServer)
             {
                 Network.CloseConnection(info.sender, true);
             }
             else
             {
                 Network.Disconnect();
             }
         }
     }
     catch (Exception e)
     {
         GadgetCore.CoreLogger.LogWarning("The following error occured processing an incoming client's mod list: " + info.sender.ipAddress + Environment.NewLine + modList + Environment.NewLine + e.ToString());
         if (Network.isServer)
         {
             Network.CloseConnection(info.sender, true);
         }
         else
         {
             Network.Disconnect();
         }
     }
 }
Example #5
0
 private static void VerifyCompatible(NetworkPlayer pl)
 {
     if (!GadgetNetwork.MatrixReady && GadgetNetwork.GetTimeSinceConnect() > GadgetNetwork.MatrixTimeout && Gadgets.ListAllGadgetInfos().Any(x => x.Attribute.RequiredOnClients))
     {
         Network.CloseConnection(pl, true);
     }
 }
 private void OnSelectAllExecute()
 {
     Gadgets.ForEach(x => x.IsSelected = true);
 }
 public static bool Prefix(GameScript __instance)
 {
     if (!GadgetNetwork.MatrixReady && GadgetNetwork.GetTimeSinceConnect() < GadgetNetwork.MatrixTimeout)
     {
         if (InstanceTracker.GameScript.gameObject.GetComponent <RPCHooks>() == null)
         {
             InstanceTracker.GameScript.gameObject.AddComponent <RPCHooks>();
         }
         RPCHooks.InitiateGadgetNetwork();
         __instance.StartCoroutine(WaitAndTryAgain(__instance));
         return(false);
     }
     else
     {
         if (GadgetNetwork.GetTimeSinceConnect() > GadgetNetwork.MatrixTimeout && Gadgets.ListAllGadgetInfos().Any(x => x.Attribute.RequiredOnClients))
         {
             GadgetCore.CoreLogger.LogWarning("Disconnecting from server due to timout! You can try raising NetworkTimeout in the config.");
             Network.Disconnect();
             return(false);
         }
         return(true);
     }
 }
Example #8
0
 private void RefreshGadgets()
 {
     Gadgets.Clear();
     service.GetAllGadgets().ForEach(g => Gadgets.Add(g));
 }
Example #9
0
 private static void LoadGadgetMod(GadgetMod mod)
 {
     Logger.Log("Loading mod '" + mod.Name + "'");
     if (mod.ModDependencies.Any(x => GadgetMods.GetModByName(x) == null))
     {
         m_IncompatibleMods.Add(mod);
         Logger.LogWarning("Aborted loading mod '" + mod.Name + "' because of the following missing dependencies: " + mod.ModDependencies.Where(x => GadgetMods.GetModByName(x) == null).Concat());
         return;
     }
     Type[] gadgetTypes = mod.Assembly.GetExportedTypes().Where(x => x.IsSubclassOf(typeof(Gadget)) && x.GetCustomAttributes(typeof(GadgetAttribute), true).FirstOrDefault() != null).ToArray();
     if (gadgetTypes.Length == 0)
     {
         m_EmptyMods.Add(mod);
         Logger.LogWarning("Aborted loading mod '" + mod.Name + "' because it does not contain any Gadgets");
     }
     mod.m_LoadedGadgets   = new List <GadgetInfo>();
     mod.LoadedGadgets     = new ReadOnlyCollection <GadgetInfo>(mod.m_LoadedGadgets);
     mod.m_UnloadedGadgets = new List <GadgetInfo>();
     mod.UnloadedGadgets   = new ReadOnlyCollection <GadgetInfo>(mod.m_UnloadedGadgets);
     for (int i = 0; i < gadgetTypes.Length; i++)
     {
         Type            type      = gadgetTypes[i];
         GadgetAttribute attribute = (GadgetAttribute)type.GetCustomAttributes(typeof(GadgetAttribute), true).FirstOrDefault();
         if (mod.m_LoadedGadgets.Any(x => x.Attribute.Name == attribute.Name))
         {
             throw new InvalidOperationException("It is illegal for a mod to contain multiple Gadgets with the same name: " + attribute.Name);
         }
         int[] targetVersionNums = attribute.TargetGCVersion.Split('.').Select(x => int.Parse(x)).ToArray();
         if (targetVersionNums.Length != 4)
         {
             Array.Resize(ref targetVersionNums, 4);
         }
         if ((attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MAJOR && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && (GadgetCoreAPI.currentVersionNums[1] > targetVersionNums[1] || (GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && (GadgetCoreAPI.currentVersionNums[2] > targetVersionNums[2] || (GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] >= targetVersionNums[3]))))) ||
             (attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MINOR && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && (GadgetCoreAPI.currentVersionNums[2] > targetVersionNums[2] || (GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] >= targetVersionNums[3]))) ||
             (attribute.GadgetCoreVersionSpecificity == VersionSpecificity.NONBREAKING && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] >= targetVersionNums[3]) ||
             (attribute.GadgetCoreVersionSpecificity == VersionSpecificity.BUGFIX && GadgetCoreAPI.currentVersionNums[0] == targetVersionNums[0] && GadgetCoreAPI.currentVersionNums[1] == targetVersionNums[1] && GadgetCoreAPI.currentVersionNums[2] == targetVersionNums[2] && GadgetCoreAPI.currentVersionNums[3] == targetVersionNums[3]))
         {
             Gadget gadget = null;
             try
             {
                 gadget = Activator.CreateInstance(type) as Gadget;
             }
             catch (Exception e)
             {
                 Logger.LogWarning("Found Gadget that could not be constructed: " + attribute.Name + ", in mod: {" + mod.Name + "}: Error: " + e);
             }
             if (gadget != null)
             {
                 try
                 {
                     Logger.Log("Found Gadget to load: " + attribute.Name + ", in mod: {" + mod.Name + "}");
                     gadget.CreateSingleton(gadget);
                     GadgetInfo info = new GadgetInfo(gadget, attribute, mod);
                     gadget.Logger = new GadgetLogger(mod.Name, attribute.Name);
                     string configFileName    = Path.Combine(GadgetPaths.ConfigsPath, mod.Assembly.GetName().Name) + ".ini";
                     string oldConfigFileName = Path.Combine(GadgetPaths.ConfigsPath, mod.Name + ".ini");
                     if (!File.Exists(configFileName) && File.Exists(oldConfigFileName))
                     {
                         File.Move(oldConfigFileName, configFileName);
                     }
                     gadget.Config = new GadgetConfig(configFileName, Regex.Replace(attribute.Name, @"\s+", ""));
                     Gadgets.RegisterGadget(info);
                     mod.m_LoadedGadgets.Add(info);
                     if (!BatchLoading)
                     {
                         QueuedGadgets.Add(info);
                         EnableQueuedGadgets();
                     }
                 }
                 catch (Exception e)
                 {
                     Logger.LogWarning("Found Gadget that had an error during registration: " + attribute.Name + ", in mod: {" + mod.Name + "}. Error: " + e);
                     if (Gadgets.GetGadgetInfo(attribute.Name) != null)
                     {
                         Gadgets.UnregisterGadget(Gadgets.GetGadgetInfo(attribute.Name));
                     }
                 }
             }
         }
         else
         {
             int rD = (int)attribute.GadgetCoreVersionSpecificity;
             Logger.LogWarning("Found Gadget with an incompatible version: " + attribute.Name + ", in mod: {" + mod.Name + "}. Requires at least version: " + attribute.TargetGCVersion + ", but no greater than version: " + new string(attribute.TargetGCVersion.TakeWhile(x => (x == '.' ? --rD : rD) > 0).ToArray()));
         }
     }
     mod.IsLoaded = true;
 }
Example #10
0
 /// <summary>
 /// Hard-reloads the given GadgetMod. (Loads it freshly from the disk).
 /// Also reloads all mods that are dependent on this mod.
 /// Causes a permanent increase in the game's RAM usage, as the old instance of the mod assembly that is stored in RAM cannot be fully removed.
 /// WARNING: Will trigger an immediate GC collection, causing a short freeze!
 /// </summary>
 public static GadgetMod ReloadMod(GadgetMod mod)
 {
     try
     {
         if (mod.Name == "GadgetCore")
         {
             throw new InvalidOperationException(GadgetMods.GetModByAssembly(Assembly.GetCallingAssembly()).Name + " seriously just tried to reload GadgetCore... Really?");
         }
         string           modPath      = mod.ModPath;
         List <GadgetMod> modsToReload = mod.LoadedGadgets.SelectMany(x => Gadgets.LoadOrderTree.Find(x).FlattenUniqueByBreadth()).Where(x => x != null).Select(x => x.Mod).Distinct().ToList();
         foreach (GadgetMod modToUnload in modsToReload)
         {
             if (modToUnload.Name != "GadgetCore")
             {
                 UnloadModInternal(modToUnload);
             }
         }
         GC.Collect();
         BatchLoading = true;
         Logger.Log("Loading mod files...");
         for (int i = 0; i < modsToReload.Count; i++)
         {
             if (modsToReload[i].Name != "GadgetCore")
             {
                 if (modsToReload[i].IsArchive)
                 {
                     if (modsToReload[i].ModPath == modPath)
                     {
                         modsToReload[i] = mod = LoadModFile(modsToReload[i].ModPath);
                     }
                     else
                     {
                         modsToReload[i] = LoadModFile(modsToReload[i].ModPath);
                     }
                 }
                 else
                 {
                     if (modsToReload[i].ModPath == modPath)
                     {
                         modsToReload[i] = mod = LoadModDir(modsToReload[i].ModPath);
                     }
                     else
                     {
                         modsToReload[i] = LoadModDir(modsToReload[i].ModPath);
                     }
                 }
             }
             else
             {
                 RefreshMod(modsToReload[i]);
             }
         }
         Logger.Log("Done loading mod files.");
         Logger.Log("Loading mods...");
         foreach (GadgetMod modToReload in modsToReload)
         {
             LoadGadgetMod(modToReload);
         }
         Logger.Log("Done loading mods.");
         Logger.Log("Sorting Gadgets...");
         Gadgets.SortGadgets();
         Logger.Log("Done sorting Gadgets.");
         Logger.Log("Queueing Gadgets for initialization...");
         foreach (GadgetInfo gadget in modsToReload.SelectMany(x => x.LoadedGadgets))
         {
             QueuedGadgets.Add(gadget);
         }
         Logger.Log("Done queueing Gadgets.");
         EnableQueuedGadgets();
         BatchLoading = false;
     }
     catch (Exception e)
     {
         Logger.LogError("Error reloading " + mod.Name + ": " + e);
     }
     return(mod);
 }
Example #11
0
    void InitializeGadgets()
    {
        DataManager dataManager = GameObject.FindGameObjectWithTag("DataManager").GetComponent <DataManager>();

        gadgetList = new List <Gadgets>();
        PersistentGadget[] allGadgets;
        allGadgets = dataManager.Gadgets;


        foreach (PersistentGadget g in allGadgets)
        {
            if (!g.isLocked)
            {
                if (g.gadgetName == "Turbo Boots")
                {
                    gadgetList.Add(new Turbo_boots(g.gadgetName, g.image, g.coolDown, g.boostDuration, player));
                }
                else if (g.gadgetName == "Vibrating Stone")
                {
                    gadgetList.Add(new Rock(g.gadgetName, g.image, g.coolDown, g.boostDuration, player));
                    rockPosition = gadgetList.Count - 1;
                }
                else if (g.gadgetName == "Lock Pick")
                {
                    gadgetList.Add(new Lock_pick(g.gadgetName, g.image, g.coolDown, g.boostDuration, player));
                }
                else if (g.gadgetName == "Electronic Cracker")
                {
                    gadgetList.Add(new Electronic_safe_opener(g.gadgetName, g.image, g.coolDown, g.boostDuration, player));
                }
                else if (g.gadgetName == "Banana")
                {
                    gadgetList.Add(new Banana(g.gadgetName, g.image, g.coolDown, g.boostDuration, player));
                    bananaPosition = gadgetList.Count - 1;
                }
                else if (g.gadgetName == "Laser Visor")
                {
                    gadgetList.Add(new Laser_visor(g.gadgetName, g.image, g.coolDown, g.boostDuration, player));
                }
                else
                {
                    gadgetList.Add(new Gadgets(g.gadgetName, g.image, g.coolDown, g.boostDuration, player));
                }
            }
        }

        gadgetNumber = gadgetList.Count;
        if (gadgetList.Count > 0 && sceneIndex != homeScene)
        {
            gadgetPanel.SetActive(true);
            currentGadget = gadgetList[0];

            gadgetImage.sprite = currentGadget.sprite;
            gadgetText.text    = currentGadget.name;
            gadgetPanelActive  = true;
        }
        else
        {
            gadgetPanel.SetActive(false);
            gadgetPanelActive = false;
        }
    }
        private async Task ExecuteLoadItemsCommand()
        {
            IsBusy = true;

            try
            {
                Gadgets.Clear();
                var gadgets = await _gadgetDataStore.GetAllAsync(true);

                if (gadgets == null || gadgets.Count() == 0)
                {
                    return;
                }


                var unsortedGadgetList = new List <GadgetViewModel>();

                foreach (Gadget gadget in gadgets)
                {
                    GadgetStatus gadgetStatus = await _webRequestService.GetStatusAsync(gadget);

                    var statusIndicatorColor = GadgetHelper.GetStatusIndicatorColor(gadgetStatus);

                    if (gadgetStatus == null)
                    {
                        gadgetStatus = new GadgetStatus
                        {
                            temperature        = 0.00,
                            overtemperature    = false,
                            temperature_status = "undefined",
                            mac     = "",
                            voltage = 0.00
                        };
                    }

                    var viewModel = new GadgetViewModel
                    {
                        Id                   = gadget.Id,
                        DeviceId             = gadgetStatus.mac,
                        Name                 = gadget.Name,
                        Location             = gadget.Location,
                        IpAddress            = gadget.IpAddress,
                        Description          = gadget.Description,
                        IsStatusOk           = gadgetStatus.temperature_status == "Normal",
                        StatusIndicatorColor = statusIndicatorColor.ToString(),
                        TemperatureStatus    = gadgetStatus.temperature_status,
                        Temperature          = gadgetStatus.temperature,
                        TemperatureC         = $"{ gadgetStatus.temperature } °C",
                        Voltage              = gadgetStatus.voltage,
                        VoltageV             = $"{ gadgetStatus.voltage } V"
                    };

                    if (gadgetStatus.temperature_status == "undefined")
                    {
                        viewModel.TemperatureC = AppTranslations.Page_GadgetDetail_Fallback_NotAvailable;
                    }


                    unsortedGadgetList.Add(viewModel);
                }

                List <GadgetViewModel> sortedGadgetList = await GadgetHelper.SortGadgetListBySettingAsync(unsortedGadgetList);



                sortedGadgetList.ForEach(Gadgets.Add);
            }
            catch (Exception ex)
            {
                var properties = new Dictionary <string, string> {
                    { "Method", "ExecuteLoadItemsCommand" },
                    { "Event", "Could not Add GadgetViewModel" }
                };

                AppHelper.TrackError(ex, properties);
            }
            finally
            {
                IsBusy = false;
            }
        }
Example #13
0
 void initVariables()
 {
     rows = 7;
     columns = 7;
     offset = 3.8f;
     score = 0;
     combo = 0;
     paintedSquares = 0;
     randomSquaresPainted = 4;
     listLeft = new List<string>();
     listRight = new List<string>();
     listDown = new List<string>();
     listUp = new List<string>();
     listLine = new List<string>();
     selectedSquare = null;
     selectedSquareDest = null;
     selectedSquareColor = Color.clear;
     selectedSquareDestColor = Color.clear;
     colors = new SquareColors ();
     gadgetsScript = GameObject.FindGameObjectWithTag ("Gadgets").GetComponent<Gadgets> ();
 }
Example #14
0
        public async Task <IActionResult> GetGadgets(int id)
        {
            Gadgets gadgets = await dataContx.Gadgets.Where(x => x.OwnerID == id).FirstAsync();

            return(Ok(gadgets));
        }
Example #15
0
 public static bool Prefix(GameScript __instance)
 {
     if (!GadgetNetwork.MatrixReady && GadgetNetwork.GetTimeSinceConnect() < GadgetNetwork.MatrixTimeout)
     {
         if (InstanceTracker.GameScript.gameObject.GetComponent <RPCHooks>() == null)
         {
             InstanceTracker.GameScript.gameObject.AddComponent <RPCHooks>();
         }
         __instance.StartCoroutine(WaitAndTryAgain(__instance));
         return(false);
     }
     else
     {
         if (GadgetNetwork.GetTimeSinceConnect() > GadgetNetwork.MatrixTimeout && Gadgets.ListAllGadgetInfos().Any(x => x.Attribute.RequiredOnClients))
         {
             Network.Disconnect();
             return(false);
         }
         return(true);
     }
 }
 private static void VerifyCompatible(NetworkPlayer pl)
 {
     if (!GadgetNetwork.MatrixReady && GadgetNetwork.GetTimeSinceConnect() > GadgetNetwork.MatrixTimeout && Gadgets.ListAllGadgetInfos().Any(x => x.Attribute.RequiredOnClients))
     {
         GadgetCore.CoreLogger.LogWarning("Disconnecting client " + pl.ipAddress + " due to timout! You can try raising NetworkTimeout in the config.");
         Network.CloseConnection(pl, true);
     }
 }
        private static void BuildModMenu()
        {
            GadgetCore.CoreLogger.Log("Injecting Mod Menu into Main Menu");

            ModMenu = new GameObject("MODMENU");
            ModMenu.SetActive(false);
            ModMenuBackButtonBeam      = UnityEngine.Object.Instantiate(InstanceTracker.Menuu.menuOptions.transform.Find("beamm").gameObject, ModMenu.transform);
            ModMenuBackButtonBeam.name = "beamm";
            ModMenuBackButtonBeam.transform.localScale = new Vector3(30, 0, 1);
            ModMenuBackButtonBeam.transform.position   = new Vector3(0, -13.5f, 1);
            ModMenuBackButtonHolder      = UnityEngine.Object.Instantiate(InstanceTracker.Menuu.menuOptions.transform.Find("BUTTONHOLDER").gameObject, ModMenu.transform);
            ModMenuBackButtonHolder.name = "BUTTONHOLDER";
            ModMenuBackButtonHolder.transform.position = new Vector3(0, -13.5f, 0);
            ModMenuBackButtonHolder.GetComponent <Animation>().RemoveClip("bbbac2");
            ModMenuBackButtonHolder.GetComponent <Animation>().AddClip(BuildModMenuButtonAnimClip(true), "bbbac2");
            ModMenuBackButtonHolder.GetComponent <Animation>().clip = ModMenuBackButtonHolder.GetComponent <Animation>().GetClip("bbbac2");
            ModMenuCanvas = new GameObject("Mod Menu Canvas", typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster), typeof(CanvasGroup)).GetComponent <Canvas>();
            ModMenuCanvas.GetComponent <CanvasGroup>().alpha          = 0;
            ModMenuCanvas.GetComponent <CanvasGroup>().interactable   = false;
            ModMenuCanvas.GetComponent <CanvasGroup>().blocksRaycasts = false;
            ModMenuCanvas.GetComponent <RectTransform>().pivot        = new Vector2(0.5f, 0.5f);
            ModMenuCanvas.renderMode   = RenderMode.ScreenSpaceOverlay;
            ModMenuCanvas.pixelPerfect = true;
            CanvasScaler scaler = ModMenuCanvas.GetComponent <CanvasScaler>();

            scaler.scaleFactor                        = 2;
            scaler.referencePixelsPerUnit             = 100;
            ModConfigMenuText                         = UnityEngine.Object.Instantiate(InstanceTracker.Menuu.menuOptions.transform.Find("txt0").gameObject, ModMenu.transform);
            ModConfigMenuText.name                    = "txt0";
            ModConfigMenuText.transform.localPosition = new Vector3(0, 14, -1);
            Array.ForEach(ModConfigMenuText.GetComponentsInChildren <TextMesh>(), x => { x.text = "MOD CONFIG MENU"; x.anchor = TextAnchor.UpperCenter; });
            GameObject restartRequiredText = UnityEngine.Object.Instantiate(ModConfigMenuText, ModMenu.transform);

            restartRequiredText.SetActive(false);
            restartRequiredText.name = "Restart Required Text";
            restartRequiredText.transform.localPosition = new Vector3(0, -10.5f, -1);
            restartRequiredText.transform.localScale   *= 0.75f;
            Array.ForEach(restartRequiredText.GetComponentsInChildren <TextMesh>(), x => { x.text = "Restart Required!"; x.anchor = TextAnchor.UpperCenter; });
            ModMenuPanel = new GameObject("Panel", typeof(RectTransform), typeof(ModMenuController)).GetComponent <ModMenuController>();
            ModMenuPanel.GetComponent <RectTransform>().SetParent(ModMenuCanvas.transform);
            ModMenuPanel.GetComponent <RectTransform>().anchorMin = new Vector2(0.15f, 0.15f);
            ModMenuPanel.GetComponent <RectTransform>().anchorMax = new Vector2(0.85f, 0.85f);
            ModMenuPanel.GetComponent <RectTransform>().offsetMin = Vector2.zero;
            ModMenuPanel.GetComponent <RectTransform>().offsetMax = Vector2.zero;
            ModConfigMenus = new GameObject("Mod Config Menus", typeof(RectTransform)).GetComponent <RectTransform>();
            ModConfigMenus.SetParent(ModMenuCanvas.transform);
            ModConfigMenus.anchorMin = new Vector2(0.15f, 0.15f);
            ModConfigMenus.anchorMax = new Vector2(0.85f, 0.85f);
            ModConfigMenus.offsetMin = Vector2.zero;
            ModConfigMenus.offsetMax = Vector2.zero;
            Image background = new GameObject("Background", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <Image>();

            background.transform.SetParent(ModMenuPanel.transform);
            background.rectTransform.anchorMin = new Vector2(0f, 0f);
            background.rectTransform.anchorMax = new Vector2(01f, 1f);
            background.rectTransform.offsetMin = Vector2.zero;
            background.rectTransform.offsetMax = Vector2.zero;
            background.type       = Image.Type.Sliced;
            background.fillCenter = true;
            background.sprite     = BoxSprite;

            ModMenuDescPanel = new GameObject("Mod Desc Panel", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(ScrollRect)).GetComponent <ScrollRect>();
            ModMenuDescPanel.GetComponent <RectTransform>().SetParent(ModMenuPanel.transform);
            ModMenuDescPanel.GetComponent <RectTransform>().anchorMin = new Vector2(0.4f, 0.25f);
            ModMenuDescPanel.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 1f);
            ModMenuDescPanel.GetComponent <RectTransform>().offsetMin = new Vector2(0, 5);
            ModMenuDescPanel.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuDescPanel.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuDescPanel.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuDescPanel.GetComponent <Image>().fillCenter = true;
            Mask modMenuDescPanelMask = new GameObject("Mask", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Mask)).GetComponent <Mask>();

            modMenuDescPanelMask.GetComponent <RectTransform>().SetParent(ModMenuDescPanel.transform);
            modMenuDescPanelMask.GetComponent <RectTransform>().anchorMin = new Vector2(0f, 0f);
            modMenuDescPanelMask.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 1f);
            modMenuDescPanelMask.GetComponent <RectTransform>().offsetMin = Vector2.zero;
            modMenuDescPanelMask.GetComponent <RectTransform>().offsetMax = Vector2.zero;
            modMenuDescPanelMask.GetComponent <Image>().sprite            = BoxMask;
            modMenuDescPanelMask.GetComponent <Image>().type       = Image.Type.Sliced;
            modMenuDescPanelMask.GetComponent <Image>().fillCenter = true;
            modMenuDescPanelMask.showMaskGraphic = false;
            RectTransform modMenuDescViewport = new GameObject("Viewport", typeof(RectTransform)).GetComponent <RectTransform>();

            modMenuDescViewport.SetParent(modMenuDescPanelMask.transform);
            modMenuDescViewport.anchorMin = new Vector2(0f, 0f);
            modMenuDescViewport.anchorMax = new Vector2(1f, 1f);
            modMenuDescViewport.offsetMin = new Vector2(10, 10);
            modMenuDescViewport.offsetMax = new Vector2(-10, -10);
            Text modMenuDescText = new GameObject("Description", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text), typeof(ContentSizeFitter)).GetComponent <Text>();

            modMenuDescText.rectTransform.SetParent(modMenuDescViewport);
            modMenuDescText.rectTransform.anchorMin = new Vector2(0f, 0f);
            modMenuDescText.rectTransform.anchorMax = new Vector2(1f, 1f);
            modMenuDescText.rectTransform.offsetMin = Vector2.zero;
            modMenuDescText.rectTransform.offsetMax = Vector2.zero;
            modMenuDescText.rectTransform.pivot     = new Vector2(0.5f, 1f);
            modMenuDescText.font               = ModConfigMenuText.GetComponent <TextMesh>().font;
            modMenuDescText.fontSize           = 12;
            modMenuDescText.horizontalOverflow = HorizontalWrapMode.Wrap;
            modMenuDescText.GetComponent <ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
            ModMenuDescPanel.GetComponent <ScrollRect>().content           = modMenuDescText.rectTransform;
            ModMenuDescPanel.GetComponent <ScrollRect>().horizontal        = false;
            ModMenuDescPanel.GetComponent <ScrollRect>().scrollSensitivity = 5;
            ModMenuDescPanel.GetComponent <ScrollRect>().viewport          = modMenuDescViewport;
            ModMenuPanel.descText            = modMenuDescText;
            ModMenuPanel.restartRequiredText = restartRequiredText;
            Image modMenuButtonPanel = new GameObject("Button Panel", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <Image>();

            modMenuButtonPanel.GetComponent <RectTransform>().SetParent(ModMenuPanel.transform);
            modMenuButtonPanel.GetComponent <RectTransform>().anchorMin = new Vector2(0.4f, 0f);
            modMenuButtonPanel.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 0.25f);
            modMenuButtonPanel.GetComponent <RectTransform>().offsetMin = new Vector2(0, 10);
            modMenuButtonPanel.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -5);
            modMenuButtonPanel.GetComponent <Image>().sprite            = BoxSprite;
            modMenuButtonPanel.GetComponent <Image>().type       = Image.Type.Sliced;
            modMenuButtonPanel.GetComponent <Image>().fillCenter = true;
            ModMenuPanel.enableButton = new GameObject("Enable Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
            ModMenuPanel.enableButton.GetComponent <RectTransform>().SetParent(modMenuButtonPanel.transform);
            ModMenuPanel.enableButton.GetComponent <RectTransform>().anchorMin = new Vector2(0f, 0f);
            ModMenuPanel.enableButton.GetComponent <RectTransform>().anchorMax = new Vector2(1f / 3f, 1f);
            ModMenuPanel.enableButton.GetComponent <RectTransform>().offsetMin = new Vector2(10, 10);
            ModMenuPanel.enableButton.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuPanel.enableButton.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuPanel.enableButton.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuPanel.enableButton.GetComponent <Image>().fillCenter = true;
            ModMenuPanel.enableButton.targetGraphic = ModMenuPanel.enableButton.GetComponent <Image>();
            ModMenuPanel.enableButton.onClick.AddListener(ModMenuPanel.EnableButton);
            Text enableButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            enableButtonText.rectTransform.SetParent(ModMenuPanel.enableButton.transform);
            enableButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            enableButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            enableButtonText.rectTransform.offsetMin = Vector2.zero;
            enableButtonText.rectTransform.offsetMax = Vector2.zero;
            enableButtonText.alignment = TextAnchor.MiddleCenter;
            enableButtonText.font      = modMenuDescText.font;
            enableButtonText.fontSize  = 12;
            enableButtonText.text      = "Enable";
            ModMenuPanel.reloadButton  = new GameObject("Reload Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
            ModMenuPanel.reloadButton.GetComponent <RectTransform>().SetParent(modMenuButtonPanel.transform);
            ModMenuPanel.reloadButton.GetComponent <RectTransform>().anchorMin = new Vector2(1f / 3f, 0f);
            ModMenuPanel.reloadButton.GetComponent <RectTransform>().anchorMax = new Vector2(2f / 3f, 1f);
            ModMenuPanel.reloadButton.GetComponent <RectTransform>().offsetMin = new Vector2(10, 10);
            ModMenuPanel.reloadButton.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuPanel.reloadButton.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuPanel.reloadButton.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuPanel.reloadButton.GetComponent <Image>().fillCenter = true;
            ModMenuPanel.reloadButton.targetGraphic = ModMenuPanel.reloadButton.GetComponent <Image>();
            ModMenuPanel.reloadButton.onClick.AddListener(ModMenuPanel.ReloadButton);
            Text reloadButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            reloadButtonText.rectTransform.SetParent(ModMenuPanel.reloadButton.transform);
            reloadButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            reloadButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            reloadButtonText.rectTransform.offsetMin = Vector2.zero;
            reloadButtonText.rectTransform.offsetMax = Vector2.zero;
            reloadButtonText.alignment = TextAnchor.MiddleCenter;
            reloadButtonText.font      = modMenuDescText.font;
            reloadButtonText.fontSize  = 12;
            reloadButtonText.text      = "Reload";
            ModMenuPanel.configButton  = new GameObject("Config Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
            ModMenuPanel.configButton.GetComponent <RectTransform>().SetParent(modMenuButtonPanel.transform);
            ModMenuPanel.configButton.GetComponent <RectTransform>().anchorMin = new Vector2(2f / 3f, 0f);
            ModMenuPanel.configButton.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 1f);
            ModMenuPanel.configButton.GetComponent <RectTransform>().offsetMin = new Vector2(10, 10);
            ModMenuPanel.configButton.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuPanel.configButton.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuPanel.configButton.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuPanel.configButton.GetComponent <Image>().fillCenter = true;
            ModMenuPanel.configButton.targetGraphic = ModMenuPanel.configButton.GetComponent <Image>();
            ModMenuPanel.configButton.onClick.AddListener(ModMenuPanel.ConfigButton);
            Text configButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            configButtonText.rectTransform.SetParent(ModMenuPanel.configButton.transform);
            configButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            configButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            configButtonText.rectTransform.offsetMin = Vector2.zero;
            configButtonText.rectTransform.offsetMax = Vector2.zero;
            configButtonText.alignment = TextAnchor.MiddleCenter;
            configButtonText.font      = modMenuDescText.font;
            configButtonText.fontSize  = 12;
            configButtonText.text      = "Configure";
            if (GadgetCoreAPI.GetUMFAPI() != null)
            {
                ModMenuPanel.umfConfigButton = new GameObject("UMF Config Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
                ModMenuPanel.umfConfigButton.GetComponent <RectTransform>().SetParent(ModMenuCanvas.transform);
                ModMenuPanel.umfConfigButton.GetComponent <RectTransform>().anchorMin = new Vector2(0.025f, 0.4f);
                ModMenuPanel.umfConfigButton.GetComponent <RectTransform>().anchorMax = new Vector2(0.125f, 0.6f);
                ModMenuPanel.umfConfigButton.GetComponent <RectTransform>().offsetMin = new Vector2(0, 0);
                ModMenuPanel.umfConfigButton.GetComponent <RectTransform>().offsetMax = new Vector2(0, 0);
                ModMenuPanel.umfConfigButton.GetComponent <Image>().sprite            = BoxSprite;
                ModMenuPanel.umfConfigButton.GetComponent <Image>().type       = Image.Type.Sliced;
                ModMenuPanel.umfConfigButton.GetComponent <Image>().fillCenter = true;
                ModMenuPanel.umfConfigButton.targetGraphic = ModMenuPanel.umfConfigButton.GetComponent <Image>();
                ModMenuPanel.umfConfigButton.onClick.AddListener(ModMenuPanel.UMFConfigButton);
                Text umfConfigButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();
                umfConfigButtonText.rectTransform.SetParent(ModMenuPanel.umfConfigButton.transform);
                umfConfigButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
                umfConfigButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
                umfConfigButtonText.rectTransform.offsetMin = Vector2.zero;
                umfConfigButtonText.rectTransform.offsetMax = Vector2.zero;
                umfConfigButtonText.alignment = TextAnchor.MiddleCenter;
                umfConfigButtonText.font      = modMenuDescText.font;
                umfConfigButtonText.fontSize  = 12;
                umfConfigButtonText.text      = "Configure UMF";
            }
            Button configReloadButton = new GameObject("Config Reload Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();

            configReloadButton.GetComponent <RectTransform>().SetParent(ModMenuCanvas.transform);
            configReloadButton.GetComponent <RectTransform>().anchorMin = new Vector2(0.875f, 0.4f);
            configReloadButton.GetComponent <RectTransform>().anchorMax = new Vector2(0.975f, 0.6f);
            configReloadButton.GetComponent <RectTransform>().offsetMin = new Vector2(0, 0);
            configReloadButton.GetComponent <RectTransform>().offsetMax = new Vector2(0, 0);
            configReloadButton.GetComponent <Image>().sprite            = BoxSprite;
            configReloadButton.GetComponent <Image>().type       = Image.Type.Sliced;
            configReloadButton.GetComponent <Image>().fillCenter = true;
            configReloadButton.targetGraphic = configReloadButton.GetComponent <Image>();
            configReloadButton.onClick.AddListener(() =>
            {
                foreach (GadgetInfo gadget in Gadgets.ListAllEnabledGadgetInfos())
                {
                    if (gadget.Attribute.AllowConfigReloading)
                    {
                        gadget.Gadget.ReloadConfig();
                    }
                }
                if (GadgetCore.UMFAPI != null)
                {
                    foreach (string mod in GadgetCore.UMFAPI.GetModNames())
                    {
                        GadgetCore.UMFAPI.SendCommand("cfgReload " + mod);
                    }
                }
                GadgetModConfigs.ResetAllConfigMenus();
            });
            Text configReloadButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            configReloadButtonText.rectTransform.SetParent(configReloadButton.transform);
            configReloadButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            configReloadButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            configReloadButtonText.rectTransform.offsetMin = Vector2.zero;
            configReloadButtonText.rectTransform.offsetMax = Vector2.zero;
            configReloadButtonText.alignment = TextAnchor.MiddleCenter;
            configReloadButtonText.font      = modMenuDescText.font;
            configReloadButtonText.fontSize  = 12;
            configReloadButtonText.text      = "Reload Configs";

            GadgetModConfigs.ConfigMenus.Clear();
        }
Example #18
0
 internal void SendRequiredModList(string modList, NetworkMessageInfo info)
 {
     GadgetCore.CoreLogger.Log("Client has sent local mod list. Processing...");
     try
     {
         bool             isCompatible        = true;
         List <string>    incompatibleReasons = new List <string>();
         HashSet <string> handledGadgets      = new HashSet <string>();
         string[][]       splitModList        = string.IsNullOrEmpty(modList) ? new string[0][] : modList.Split(',').Select(x => x.Split(':')).ToArray();
         foreach (GadgetInfo mod in Gadgets.ListAllGadgetInfos().Where(x => x.Gadget.Enabled && x.Attribute.RequiredOnClients))
         {
             handledGadgets.Add(mod.Attribute.Name);
             string clientVersion = splitModList.SingleOrDefault(x => x[0] == mod.Attribute.Name)?[1];
             if (clientVersion == null)
             {
                 isCompatible = false;
                 incompatibleReasons.Add($"The Gadget '{mod.Attribute.Name}' (From the mod '{mod.ModName}') is not present on the client");
                 continue;
             }
             int[] clientVersionNums = clientVersion.Split('.').Select(x => int.Parse(x)).Take(4).ToArray();
             int[] hostVersionNums   = mod.Gadget.GetModVersionString().Split('.').Select(x => int.Parse(x)).ToArray();
             hostVersionNums   = hostVersionNums.Concat(Enumerable.Repeat(0, 4 - hostVersionNums.Length)).ToArray();
             clientVersionNums = clientVersionNums.Concat(Enumerable.Repeat(0, 4 - clientVersionNums.Length)).ToArray();
             if (!((mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MAJOR && clientVersionNums[0] == hostVersionNums[0] && (clientVersionNums[1] > hostVersionNums[1] || (clientVersionNums[1] == hostVersionNums[1] && (clientVersionNums[2] > hostVersionNums[2] || (clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]))))) ||
                   (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.MINOR && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && (clientVersionNums[2] > hostVersionNums[2] || (clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]))) ||
                   (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.NONBREAKING && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] >= hostVersionNums[3]) ||
                   (mod.Attribute.GadgetCoreVersionSpecificity == VersionSpecificity.BUGFIX && clientVersionNums[0] == hostVersionNums[0] && clientVersionNums[1] == hostVersionNums[1] && clientVersionNums[2] == hostVersionNums[2] && clientVersionNums[3] == hostVersionNums[3])))
             {
                 isCompatible = false;
                 incompatibleReasons.Add($"The Gadget '{mod.Attribute.Name}' (From the mod '{mod.ModName}') is of incompatible versions: Host: {mod.Gadget.GetModVersionString()}, Client: {clientVersion}");
                 continue;
             }
         }
         if (handledGadgets.Count != splitModList.Length)
         {
             isCompatible = false;
             foreach (string[] modEntry in splitModList.Where(x => !handledGadgets.Contains(x[0])))
             {
                 incompatibleReasons.Add($"The Gadget '{modEntry[0]}' (From an unknown mod) is present on the client, but not on the host");
             }
         }
         if (isCompatible)
         {
             if (info.Equals(serverNMI))
             {
                 GadgetCore.CoreLogger.Log("Self-connection succesfully established and identified.");
                 ReceiveIDMatrixData(GadgetNetwork.GenerateIDMatrixData());
             }
             else
             {
                 GadgetCore.CoreLogger.Log("A client connected with compatible mods: " + info.sender.ipAddress);
                 string matrixData = GadgetNetwork.GenerateIDMatrixData();
                 if (matrixData.Length <= 4096)
                 {
                     GadgetCore.CoreLogger.Log("Sending ID Matrix data as a single block...");
                     view.RPC("ReceiveIDMatrixData", info.sender, matrixData);
                 }
                 else
                 {
                     string[] splitMatrixData = matrixData.SplitOnLength(MaxChunkSize).ToArray();
                     GadgetCore.CoreLogger.Log($"Sending ID Matrix data as {splitMatrixData.Length} chunks...");
                     for (int i = 0; i < splitMatrixData.Length; i++)
                     {
                         view.RPC("ReceiveIDMatrixDataChunk", info.sender, splitMatrixData[i], i, splitMatrixData.Length);
                     }
                 }
             }
         }
         else
         {
             GadgetCore.CoreLogger.LogWarning("A client tried to connect with incompatible mods: " + info.sender.ipAddress +
                                              Environment.NewLine + " - " + incompatibleReasons.Concat(Environment.NewLine + " - "));
             if (Network.isServer)
             {
                 DisconnectWithMessage(info.sender, "Your mods are incompatible with the server:" + Environment.NewLine + " - " + incompatibleReasons.Concat(Environment.NewLine + " - "));
             }
             else
             {
                 Network.Disconnect();
             }
         }
     }
     catch (Exception e)
     {
         GadgetCore.CoreLogger.LogWarning("The following error occured processing an incoming client's mod list: " + info.sender.ipAddress + Environment.NewLine + modList + Environment.NewLine + e.ToString());
         if (Network.isServer)
         {
             DisconnectWithMessage(info.sender, "An error occured processing your mod list:" + Environment.NewLine + modList + Environment.NewLine + e.ToString());
         }
         else
         {
             Network.Disconnect();
         }
     }
 }
Example #19
0
        internal static void EnableQueuedGadgets()
        {
            List <GadgetInfo> preFilteredQueuedGadgets = QueuedGadgets;

            QueuedGadgets = new List <GadgetInfo>();
            foreach (GadgetInfo gadget in preFilteredQueuedGadgets)
            {
                bool valid = true;
                foreach (string dependency in gadget.Attribute.Dependencies)
                {
                    string[]   splitDependency  = dependency.Split(':');
                    GadgetInfo dependencyGadget = Gadgets.GetGadgetInfo(splitDependency[0]);
                    valid = dependencyGadget != null && dependencyGadget.Gadget.Enabled;
                    if (valid)
                    {
                        if (splitDependency.Length == 2)
                        {
                            string versionString     = splitDependency[1].TrimStart('v');
                            int[]  targetVersionNums = versionString.Split('.').Select(x => int.Parse(x)).ToArray();
                            if (targetVersionNums.Length > 4)
                            {
                                continue;
                            }
                            int[] actualVersionNums = dependencyGadget.Mod.Version.ToString().Split('.').Select(x => int.Parse(x)).ToArray();
                            if (targetVersionNums.Length != 4)
                            {
                                Array.Resize(ref targetVersionNums, 4);
                            }
                            if (actualVersionNums.Length != 4)
                            {
                                Array.Resize(ref actualVersionNums, 4);
                            }
                            valid = actualVersionNums[0] == targetVersionNums[0] && actualVersionNums[1] == targetVersionNums[1] && (actualVersionNums[2] > targetVersionNums[2] || (actualVersionNums[2] == targetVersionNums[2] && actualVersionNums[3] >= targetVersionNums[3]));
                        }
                        else if (splitDependency.Length == 3)
                        {
                            string versionString     = splitDependency[1].TrimStart('v');
                            int[]  targetVersionNums = versionString.Split('.').Select(x => int.Parse(x)).ToArray();
                            if (targetVersionNums.Length > 4)
                            {
                                continue;
                            }
                            int[] actualVersionNums = dependencyGadget.Mod.Version.ToString().Split('.').Select(x => int.Parse(x)).ToArray();
                            VersionSpecificity versionSpecificity;
                            try
                            {
                                versionSpecificity = (VersionSpecificity)Enum.Parse(typeof(VersionSpecificity), splitDependency[2], true);
                            }
                            catch (ArgumentException)
                            {
                                Logger.LogWarning("Gadget " + gadget.Attribute.Name + " has an improperly-formatted dependency version string: " + dependency);
                                versionSpecificity = VersionSpecificity.MINOR;
                            }
                            if (targetVersionNums.Length != 4)
                            {
                                Array.Resize(ref targetVersionNums, 4);
                            }
                            if (actualVersionNums.Length != 4)
                            {
                                Array.Resize(ref actualVersionNums, 4);
                            }
                            valid = (versionSpecificity == VersionSpecificity.MAJOR && actualVersionNums[0] == targetVersionNums[0] && (actualVersionNums[1] > targetVersionNums[1] || (actualVersionNums[1] == targetVersionNums[1] && (actualVersionNums[2] > targetVersionNums[2] || (actualVersionNums[2] == targetVersionNums[2] && actualVersionNums[3] >= targetVersionNums[3]))))) ||
                                    (versionSpecificity == VersionSpecificity.MINOR && actualVersionNums[0] == targetVersionNums[0] && actualVersionNums[1] == targetVersionNums[1] && (actualVersionNums[2] > targetVersionNums[2] || (actualVersionNums[2] == targetVersionNums[2] && actualVersionNums[3] >= targetVersionNums[3]))) ||
                                    (versionSpecificity == VersionSpecificity.NONBREAKING && actualVersionNums[0] == targetVersionNums[0] && actualVersionNums[1] == targetVersionNums[1] && actualVersionNums[2] == targetVersionNums[2] && actualVersionNums[3] >= targetVersionNums[3]) ||
                                    (versionSpecificity == VersionSpecificity.BUGFIX && actualVersionNums[0] == targetVersionNums[0] && actualVersionNums[1] == targetVersionNums[1] && actualVersionNums[2] == targetVersionNums[2] && actualVersionNums[3] == targetVersionNums[3]);
                        }
                    }
                }
                if (valid)
                {
                    QueuedGadgets.Add(gadget);
                }
                else
                {
                    gadget.Gadget.Enabled = false;
                    GadgetCoreConfig.enabledGadgets[gadget.Attribute.Name] = false;
                    Gadgets.UnregisterGadget(gadget);
                    Logger.LogWarning("Aborted loading Gadget " + gadget.Attribute.Name + " due to missing dependencies.");
                }
            }
            Logger.Log("Loading Gadget configs...");
            foreach (GadgetInfo gadget in QueuedGadgets.ToList())
            {
                Logger.Log("Loading Config for Gadget '" + gadget.Attribute.Name + "'");
                try
                {
                    gadget.Gadget.LoadConfig();
                }
                catch (Exception e)
                {
                    gadget.Gadget.Enabled = false;
                    GadgetCoreConfig.enabledGadgets[gadget.Attribute.Name] = false;
                    Gadgets.UnregisterGadget(gadget);
                    QueuedGadgets.Remove(gadget);
                    Logger.LogError("Exception Loading Config For Gadget '" + gadget.Attribute.Name + "':" + Environment.NewLine + e.ToString());
                }
            }
            Logger.Log("Done loading Gadget configs.");
            Logger.Log("Preparing Gadgets for patching...");
            foreach (GadgetInfo gadget in QueuedGadgets.ToList())
            {
                Logger.Log("PrePatching Gadget '" + gadget.Attribute.Name + "'");
                try
                {
                    gadget.Gadget.HarmonyInstance = new Harmony(gadget.Mod.Name + "." + gadget.Attribute.Name + ".gadget");
                    gadget.Gadget.PrePatch();
                }
                catch (Exception e)
                {
                    gadget.Gadget.Enabled = false;
                    GadgetCoreConfig.enabledGadgets[gadget.Attribute.Name] = false;
                    Gadgets.UnregisterGadget(gadget);
                    QueuedGadgets.Remove(gadget);
                    Logger.LogError("Exception PrePatching Gadget '" + gadget.Attribute.Name + "':" + Environment.NewLine + e.ToString());
                }
            }
            Logger.Log("Done preparing Gadgets for patching.");
            Logger.Log("Patching Gadgets...");
            foreach (GadgetInfo gadget in QueuedGadgets.ToList())
            {
                int patches = 0, totalMethods = 0, errorPatching = 0, targetMissing = 0;
                try
                {
                    gadget.Mod.Assembly.GetExportedTypes().Do(delegate(Type type)
                    {
                        HarmonyGadgetAttribute attribute = type.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(HarmonyGadgetAttribute)) as HarmonyGadgetAttribute;
                        if (attribute?.Gadget == gadget.Attribute.Name && attribute.RequiredGadgets.All(x => Gadgets.GetGadget(x) != null))
                        {
                            try
                            {
                                List <MethodInfo> methods = gadget.Gadget.HarmonyInstance.CreateClassProcessor(type).Patch();
                                totalMethods += methods?.Count ?? 0;
                                if (methods == null || methods.Count == 0)
                                {
                                    Logger.Log("Skipping patch '" + type.Name + "' for Gadget '" + gadget.Attribute.Name + "': Attribute target does not exist.");
                                    targetMissing++;
                                }
                                else
                                {
                                    patches++;
                                }
                            }
                            catch (Exception e)
                            {
                                if (e.InnerException == null || !e.InnerException.Message.EndsWith("returned an unexpected result: null"))
                                {
                                    Logger.LogError("Exception running patch '" + type.Name + "' for Gadget '" + gadget.Attribute.Name + "': " + Environment.NewLine + e.ToString());
                                    errorPatching++;
                                }
                                else
                                {
                                    Logger.Log("Skipping patch '" + type.Name + "' for Gadget '" + gadget.Attribute.Name + "': TargetMethod returned null.");
                                    targetMissing++;
                                }
                            }
                        }
                    });
                    Logger.Log("Performed " + patches + " patches for '" + gadget.Attribute.Name + "'" + (totalMethods > 0 ? $" ({totalMethods} total methods patched)" : string.Empty) + (errorPatching > 0 ? targetMissing > 0 ? $" ({errorPatching} skipped due to errors, {targetMissing} skipped due to missing targets)" : $" ({errorPatching} skipped due to errors)" : targetMissing > 0 ? $" ({targetMissing} skipped due to missing targets)" : string.Empty));
                }
                catch (Exception e)
                {
                    gadget.Gadget.Enabled = false;
                    GadgetCoreConfig.enabledGadgets[gadget.Attribute.Name] = false;
                    Gadgets.UnregisterGadget(gadget);
                    QueuedGadgets.Remove(gadget);
                    Logger.LogError("Exception patching Gadget '" + gadget.Attribute.Name + "':" + Environment.NewLine + e.ToString());
                }
            }
            Logger.Log("Done patching Gadgets.");
            bool logOverrideWarnings = false;

            foreach (MethodBase patchedMethod in Harmony.GetAllPatchedMethods())
            {
                HarmonyLib.Patches patches = Harmony.GetPatchInfo(patchedMethod);
                if (patches == null)
                {
                    continue;
                }
                Dictionary <string, string> owners = new Dictionary <string, string>();
                List <Patch> overridingPrefixes    = patches.Prefixes.Where(x => x.PatchMethod.ReturnType == typeof(bool) && (x.PatchMethod.GetCustomAttributes(true).FirstOrDefault(a => a.GetType() == typeof(HarmonyOverridesAttribute)) as HarmonyOverridesAttribute)?.Overrides.Length != 0).ToList();
                if (overridingPrefixes != null && overridingPrefixes.Count > 0)
                {
                    foreach (string ownerID in patches.Owners)
                    {
                        if (ownerID == GadgetCore.HarmonyInstance.Id)
                        {
                            owners[ownerID] = "GadgetCore";
                        }
                        else
                        {
                            string[] splitOwnerID = ownerID.Split('.');
                            if (splitOwnerID.Length == 3 && splitOwnerID[2] == "gadget")
                            {
                                GadgetMod  mod    = GadgetMods.GetModByName(splitOwnerID[0]);
                                GadgetInfo gadget = mod?.LoadedGadgets.SingleOrDefault(x => x.Attribute.Name == splitOwnerID[1]);
                                if (gadget != null)
                                {
                                    owners[ownerID] = $"'{splitOwnerID[1]}' from the mod {{{splitOwnerID[0]}}}";
                                }
                                else
                                {
                                    owners[ownerID] = $"Unrecognized patcher '{ownerID}'";
                                }
                            }
                            else
                            {
                                owners[ownerID] = $"Unrecognized patcher '{ownerID}'";
                            }
                        }
                    }
                    IEnumerable <Patch> problematicPrefixes = patches.Prefixes.Where(x => !overridingPrefixes.Contains(x) && (x.PatchMethod.GetCustomAttributes(true).FirstOrDefault(a => a.GetType() == typeof(HarmonyOverriddenAttribute)) as HarmonyOverriddenAttribute)?.Overrides.Length != 0 && overridingPrefixes.Any(
                                                                                         p => x.owner != p.owner &&
                                                                                         (x.PatchMethod.GetCustomAttributes(true).FirstOrDefault(a => a.GetType() == typeof(HarmonyOverriddenAttribute)) as HarmonyOverriddenAttribute)?.Overrides.Contains(p.owner) != true &&
                                                                                         (p.PatchMethod.GetCustomAttributes(true).FirstOrDefault(a => a.GetType() == typeof(HarmonyOverridesAttribute)) as HarmonyOverridesAttribute)?.Overrides.Contains(x.owner) != true &&
                                                                                         x.priority <= p.priority &&
                                                                                         !x.before.Contains(p.owner) &&
                                                                                         !p.after.Contains(x.owner)));
                    IEnumerable <Patch> problematicTranspilers = patches.Transpilers.Where(x => (x.PatchMethod.GetCustomAttributes(true).FirstOrDefault(a => a.GetType() == typeof(HarmonyOverriddenAttribute)) as HarmonyOverriddenAttribute)?.Overrides.Length != 0 && overridingPrefixes.Any(
                                                                                               p => x.owner != p.owner &&
                                                                                               (x.PatchMethod.GetCustomAttributes(true).FirstOrDefault(a => a.GetType() == typeof(HarmonyOverriddenAttribute)) as HarmonyOverriddenAttribute)?.Overrides.Contains(p.owner) != true &&
                                                                                               (p.PatchMethod.GetCustomAttributes(true).FirstOrDefault(a => a.GetType() == typeof(HarmonyOverridesAttribute)) as HarmonyOverridesAttribute)?.Overrides.Contains(x.owner) != true));
                    if (problematicPrefixes != null && problematicPrefixes.Any() || problematicTranspilers != null && problematicTranspilers.Any())
                    {
                        if (!logOverrideWarnings)
                        {
                            logOverrideWarnings = true;
                            Logger.LogWarning("Possibly problematic patch overrides detected!", false);
                        }
                        Logger.Log($"Patches to {patchedMethod.DeclaringType.FullName}.{patchedMethod.Name} by {overridingPrefixes.Select(x => owners[x.owner]).Concat()} may override the following patch{(problematicPrefixes.Count() + problematicTranspilers.Count() > 1 ? "es" : "")}:");
                        if (problematicPrefixes != null)
                        {
                            foreach (Patch patch in problematicPrefixes)
                            {
                                Logger.Log($" - Prefix from {owners[patch.owner]}");
                            }
                        }
                        if (problematicTranspilers != null)
                        {
                            foreach (Patch patch in problematicTranspilers)
                            {
                                Logger.Log($" - Transpiler from {owners[patch.owner]}");
                            }
                        }
                    }
                }
            }
            if (logOverrideWarnings)
            {
                Logger.Log("End of possibly problematic patch overrides.");
            }
            Logger.Log("Creating registries...");
            foreach (GadgetInfo gadget in QueuedGadgets.ToList())
            {
                if (gadget.Gadget.Enabled)
                {
                    foreach (Registry registry in gadget.Gadget.CreateRegistries())
                    {
                        GameRegistry.RegisterRegistry(registry);
                    }
                }
            }
            Logger.Log("Done creating registries.");
            Logger.Log("Initializing Gadgets...");
            foreach (GadgetInfo gadget in QueuedGadgets.ToList())
            {
                Logger.Log("Initializing Gadget '" + gadget.Attribute.Name + "'");
                try
                {
                    Registry.gadgetRegistering = gadget.Gadget.ModID;
                    gadget.Gadget.LoadInternal();
                }
                catch (Exception e)
                {
                    gadget.Gadget.Enabled = false;
                    GadgetCoreConfig.enabledGadgets[gadget.Attribute.Name] = false;
                    Gadgets.UnregisterGadget(gadget);
                    QueuedGadgets.Remove(gadget);
                    Logger.LogError("Exception Initializing Gadget '" + gadget.Attribute.Name + "':" + Environment.NewLine + e.ToString());
                }
                finally
                {
                    Registry.gadgetRegistering = -1;
                }
            }
            Logger.Log("Done initializing Gadgets.");
            QueuedGadgets.Clear();
            GadgetCoreConfig.Update();
        }