// Convert Hex string to Color32
        public static Il2CppSystem.Object HexToColor(this Il2CppSystem.String hexString)
        {
            string tmp = hexString;

            if (tmp.IndexOf('#') != -1)
            {
                tmp = tmp.Replace("#", "");
            }

            byte r = 0, g = 0, b = 0, a = 0;

            r = Il2CppSystem.Convert.ToByte(tmp.Substring(0, 2), 16);
            g = Il2CppSystem.Convert.ToByte(tmp.Substring(2, 2), 16);
            b = Il2CppSystem.Convert.ToByte(tmp.Substring(4, 2), 16);
            if (tmp.Length == 8)
            {
                a = Il2CppSystem.Convert.ToByte(tmp.Substring(6, 2), 16);
            }

            #region [Another way but Il2Cpp doesn't like it]

            /*
             * r = int.Parse(hexString.Substring(0, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
             * g = int.Parse(hexString.Substring(2, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
             * b = int.Parse(hexString.Substring(4, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
             * if (hexString.Length == 8)
             *  a = int.Parse(hexString.Substring(6, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
             */
            #endregion

            //BepInExLoader.log.LogMessage("[Trainer] HexString: " + hexString + " RGBA(" + r.ToString() + "," + g.ToString() + "," + b.ToString() + " ," + a.ToString() + ")");

            return((new Color32(r, g, b, a)).BoxIl2CppObject());
        }
        public Texture2D createDefaultTexture(Il2CppSystem.String htmlcolorstring)
        {
            Color32 color = HTMLString2Color(htmlcolorstring).Unbox <Color32>();

            // Make a new sprite from a texture
            Texture2D SpriteTexture = new Texture2D(1, 1);

            SpriteTexture.SetPixel(0, 0, color);
            SpriteTexture.Apply();

            return(SpriteTexture);
        }
        /// <summary>
        /// Send a string to players or a player in the lobby
        /// </summary>
        /// <param name="objectToSend">string message to send. Can be JSON</param>
        /// <param name="peerId">The id of the peer you want the message to go to. Leave null if you want to send to all players</param>
        /// <param name="code">Coop code used to distinguish this message from others. Like a lock and key for reading messages</param>
        public static void SendMessage(this NKMultiGameInterface nkGI, Il2CppSystem.String objectToSend, byte?peerId = null, string code = "")
        {
            Message message = MessageUtils.CreateMessage(objectToSend, code);

            if (peerId.HasValue && peerId != null)
            {
                nkGI.SendToPeer(peerId.Value, message);
            }
            else
            {
                nkGI.relayConnection.Writer.Write(message);
            }
        }
        public Il2CppSystem.Object HTMLString2Color(Il2CppSystem.String htmlcolorstring)
        {
            Color32 color = new Color32();

            #region [DevNote]
            // Unity ref: https://docs.unity3d.com/ScriptReference/ColorUtility.TryParseHtmlString.html
            // Note: Color strings can also set alpha: "#7AB900" vs. w/alpha "#7AB90003"
            //ColorUtility.TryParseHtmlString(htmlcolorstring, out color); // Unity's Method, This may have been stripped
            #endregion

            color = htmlcolorstring.HexToColor().Unbox <Color32>();
            //log.LogMessage("HexString: " + htmlcolorstring  + "RGBA(" + color.r.ToString() + "," + color.g.ToString() + "," + color.b.ToString() + "," + color.a.ToString() + ")");

            return(color.BoxIl2CppObject());
        }
        /// <summary>
        /// Send a string to players or a player in the lobby
        /// </summary>
        /// <param name="objectToSend">string message to send. Can be JSON</param>
        /// <param name="peerId">The id of the peer you want the message to go to. Leave null if you want to send to all players</param>
        /// <param name="code">Coop code used to distinguish this message from others. Like a lock and key for reading messages</param>
        public static void SendMessage(this NKMultiGameInterface nkGI, Il2CppSystem.String objectToSend, byte?peerId = null, string code = "")
        {
            Message message = MessageUtils.CreateMessage(objectToSend, code);

            var str = Il2CppSystem.Text.Encoding.Default.GetString(message.bytes);

            MelonLoader.MelonLogger.Msg($"str: {str}");

            if (peerId.HasValue && peerId != null)
            {
                nkGI.SendToPeer(peerId.Value, message);
            }
            else
            {
                nkGI.relayConnection.Writer.Write(message);
            }
        }
        public Texture2D createTextureFromFile(Il2CppSystem.String FilePath)
        {
            // Load a PNG or JPG file from disk to a Texture2D
            Texture2D Tex2D;
            Il2CppStructArray <byte> FileData;

            if (File.Exists(FilePath))
            {
                FileData = File.ReadAllBytes(FilePath);
                Tex2D    = new Texture2D(265, 198);
                //Tex2D.LoadRawTextureData(FileData); // This is Broke. Unhollower/Texture2D doesn't like it...
                Tex2D.LoadImage(FileData, false);
                Tex2D.Apply();
                return(Tex2D);
            }
            return(null);
        }
        public GameObject createUIText(GameObject parent, Sprite BgSprite, Il2CppSystem.String textColor)
        {
            UIControls.Resources uiResources = new UIControls.Resources();

            uiResources.background = BgSprite;

            log.LogMessage("   Creating UI Text");
            GameObject uiText = UIControls.CreateText(uiResources);

            uiText.transform.SetParent(parent.transform, false);

            Text text = uiText.GetComponent <Text>();

            //uiText.transform.GetChild(0).GetComponent<Text>().font = (Font)Resources.GetBuiltinResource(Font.Il2CppType, "Arial.ttf"); // Invalid Cast
            text.color = HTMLString2Color(textColor).Unbox <Color32>();

            return(uiText);
        }
        public GameObject createUIInputField(GameObject parent, Sprite BgSprite, Il2CppSystem.String textColor)
        {
            UIControls.Resources uiResources = new UIControls.Resources();

            uiResources.inputField = BgSprite;

            log.LogMessage("   Creating UI InputField");
            GameObject uiInputField = UIControls.CreateInputField(uiResources);

            uiInputField.transform.SetParent(parent.transform, false);

            var textComps = uiInputField.GetComponentsInChildren <Text>();

            foreach (var text in textComps)
            {
                text.color = HTMLString2Color(textColor).Unbox <Color32>();
            }

            return(uiInputField);
        }
        public GameObject createUIPanel(GameObject canvas, Il2CppSystem.String height, Il2CppSystem.String width, Sprite BgSprite = null)
        {
            UIControls.Resources uiResources = new UIControls.Resources();

            uiResources.background = BgSprite;

            log.LogMessage("   Creating UI Panel");
            GameObject uiPanel = UIControls.CreatePanel(uiResources);

            uiPanel.transform.SetParent(canvas.transform, false);

            RectTransform rectTransform = uiPanel.GetComponent <RectTransform>();

            float size;

            size = Il2CppSystem.Single.Parse(height); // Their is no float support in Unhollower, this avoids errors
            rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size);
            size = Il2CppSystem.Single.Parse(width);
            rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, size);
            // You can also use rectTransform.sizeDelta = new Vector2(width, height);

            return(uiPanel);
        }