C#:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
namespace Oxide.Plugins;
[Info("ServerPanel Migrations", "Mevent", "2.0.5")]
public class ServerPanelMigrations : RustPlugin
{
#region Fields
[PluginReference] private Plugin ServerPanel;
private Dictionary<string, IMigration> availableMigrations;
private static ServerPanelMigrations Instance;
#endregion
#region Hooks
private void Init()
{
Instance = this;
InitializeMigrations();
}
private void Unload()
{
Instance = null;
}
#endregion
#region Commands
[ConsoleCommand("sp.migrations")]
private void CmdConsoleMigrations(ConsoleSystem.Arg arg)
{
if (!arg.IsServerside) return;
var command = arg.GetString(0);
switch (command?.ToLower())
{
case "list":
ListMigrations(arg);
break;
case "run":
RunMigration(arg);
break;
default:
ShowHelp(arg);
break;
}
}
private void ListMigrations(ConsoleSystem.Arg arg)
{
if (availableMigrations.Count == 0)
{
SendReply(arg, "No migrations available");
return;
}
var sb = Pool.Get<StringBuilder>();
try
{
sb.Append("Available migrations:");
sb.AppendLine();
foreach (var kvp in availableMigrations)
{
var migration = kvp.Value;
sb.AppendLine($"{kvp.Key}: {migration.Name}");
sb.AppendLine($" Needed: {(migration.IsNeeded() ? "YES" : "NO")}");
sb.AppendLine();
}
SendReply(arg, sb.ToString());
}
finally
{
Pool.FreeUnmanaged(ref sb);
}
}
private void RunMigration(ConsoleSystem.Arg arg)
{
var migrationKey = arg.GetString(1);
if (string.IsNullOrEmpty(migrationKey))
{
SendReply(arg, "Specify migration key. Use 'sp.migrations list' to see available migrations");
return;
}
if (!availableMigrations.TryGetValue(migrationKey, out var migration))
{
SendReply(arg, $"Migration '{migrationKey}' not found");
return;
}
var force = arg.GetString(2) == "force";
SendReply(arg, $"Running migration: {migration.Name}");
if (force)
SendReply(arg, "WARNING: Forced execution!");
timer.Once(1f, () => ExecuteMigration(migration, force));
}
private void ShowHelp(ConsoleSystem.Arg arg)
{
var sb = Pool.Get<StringBuilder>();
try
{
sb.Append("Usage: sp.migrations <command> [parameters]");
sb.AppendLine();
sb.AppendLine("Commands:");
sb.AppendLine(" list - show all available migrations");
sb.AppendLine(" run <key> [force] - execute migration");
sb.AppendLine(" info - show system information");
SendReply(arg, sb.ToString());
}
finally
{
Pool.FreeUnmanaged(ref sb);
}
}
#endregion
#region Migrations
public interface IMigration
{
string Name { get; }
bool IsNeeded();
void Execute();
}
public class CategoryTitleUiRefactoring : IMigration
{
public string Name => "1.3.0";
public bool IsNeeded()
{
try
{
var templatePath = Path.Combine(Interface.Oxide.DataDirectory, "ServerPanel", "Template.json");
if (!File.Exists(templatePath))
return false;
var templateJson = File.ReadAllText(templatePath);
var templateData = JsonConvert.DeserializeObject<JObject>(templateJson);
var categoryTitleToken = templateData?["UI Settings"]?["Categories"]?["Category Title"];
if (categoryTitleToken is JObject categoryTitleObj)
return categoryTitleObj.Property("Background Color") != null ||
categoryTitleObj.Property("Selected Background Color") != null ||
categoryTitleObj.Property("Background Sprite") != null ||
categoryTitleObj.Property("Background Material") != null;
return false;
}
catch
{
return false;
}
}
public void Execute()
{
var templatePath = Path.Combine(Interface.Oxide.DataDirectory, "ServerPanel", "Template.json");
var templateJson = File.ReadAllText(templatePath);
var templateData = JsonConvert.DeserializeObject<JObject>(templateJson);
MigrateCategoryTitleUi(templateData);
var updatedJson = JsonConvert.SerializeObject(templateData, Formatting.Indented);
File.WriteAllText(templatePath, updatedJson);
}
private void MigrateCategoryTitleUi(JObject templateData)
{
var categoryTitleToken = templateData?["UI Settings"]?["Categories"]?["Category Title"];
if (categoryTitleToken is not JObject categoryTitleObj)
return;
var backgroundObj = new JObject();
var selectedBackgroundObj = new JObject();
if (categoryTitleObj.TryGetValue("Background Color", out var backgroundColorToken))
{
backgroundObj["Color"] = backgroundColorToken;
categoryTitleObj.Remove("Background Color");
}
if (categoryTitleObj.TryGetValue("Selected Background Color", out var selectedBackgroundColorToken))
{
selectedBackgroundObj["Color"] = selectedBackgroundColorToken;
categoryTitleObj.Remove("Selected Background Color");
}
if (categoryTitleObj.TryGetValue("Background Sprite", out var backgroundSpriteToken))
{
var spriteValue = backgroundSpriteToken.Value<string>();
if (!string.IsNullOrEmpty(spriteValue))
{
backgroundObj["Sprite"] = spriteValue;
selectedBackgroundObj["Sprite"] = spriteValue;
}
categoryTitleObj.Remove("Background Sprite");
}
if (categoryTitleObj.TryGetValue("Background Material", out var backgroundMaterialToken))
{
var materialValue = backgroundMaterialToken.Value<string>();
if (!string.IsNullOrEmpty(materialValue))
{
backgroundObj["Material"] = materialValue;
selectedBackgroundObj["Material"] = materialValue;
}
categoryTitleObj.Remove("Background Material");
}
EnsureUiElementFields(backgroundObj);
EnsureUiElementFields(selectedBackgroundObj);
categoryTitleObj["Background"] = backgroundObj;
categoryTitleObj["Selected Background"] = selectedBackgroundObj;
}
private void EnsureUiElementFields(JObject uiElementObj)
{
if (uiElementObj.Property("Enabled?") == null)
uiElementObj["Enabled?"] = true;
if (uiElementObj.Property("Visible") == null)
uiElementObj["Visible"] = true;
if (uiElementObj.Property("Name") == null)
uiElementObj["Name"] = "";
if (uiElementObj.Property("Type (Label/Panel/Button/Image)") == null)
uiElementObj["Type (Label/Panel/Button/Image)"] = "Panel";
if (uiElementObj.Property("Color") == null)
uiElementObj["Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100
};
if (uiElementObj.Property("Text") == null)
uiElementObj["Text"] = new JArray();
if (uiElementObj.Property("Font Size") == null)
uiElementObj["Font Size"] = 14;
if (uiElementObj.Property("Font") == null)
uiElementObj["Font"] = "RobotoCondensedBold";
if (uiElementObj.Property("Align") == null)
uiElementObj["Align"] = "UpperLeft";
if (uiElementObj.Property("Text Color") == null)
uiElementObj["Text Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100
};
if (uiElementObj.Property("Command ({user} - user steamid)") == null)
uiElementObj["Command ({user} - user steamid)"] = "";
if (uiElementObj.Property("Image") == null)
uiElementObj["Image"] = "";
if (uiElementObj.Property("Cursor Enabled") == null)
uiElementObj["Cursor Enabled"] = false;
if (uiElementObj.Property("Keyboard Enabled") == null)
uiElementObj["Keyboard Enabled"] = false;
if (uiElementObj.Property("Sprite") == null)
uiElementObj["Sprite"] = "";
if (uiElementObj.Property("Material") == null)
uiElementObj["Material"] = "";
if (uiElementObj.Property("AnchorMin (X)") == null)
uiElementObj["AnchorMin (X)"] = 0f;
if (uiElementObj.Property("AnchorMin (Y)") == null)
uiElementObj["AnchorMin (Y)"] = 0f;
if (uiElementObj.Property("AnchorMax (X)") == null)
uiElementObj["AnchorMax (X)"] = 1f;
if (uiElementObj.Property("AnchorMax (Y)") == null)
uiElementObj["AnchorMax (Y)"] = 1f;
if (uiElementObj.Property("OffsetMin (X)") == null)
uiElementObj["OffsetMin (X)"] = 0f;
if (uiElementObj.Property("OffsetMin (Y)") == null)
uiElementObj["OffsetMin (Y)"] = 0f;
if (uiElementObj.Property("OffsetMax (X)") == null)
uiElementObj["OffsetMax (X)"] = 0f;
if (uiElementObj.Property("OffsetMax (Y)") == null)
uiElementObj["OffsetMax (Y)"] = 0f;
}
}
public class LocalizationFormatMigration : IMigration
{
public string Name => "1.2.3";
public bool IsNeeded()
{
try
{
var localizationPath = Path.Combine(Interface.Oxide.DataDirectory, "ServerPanel", "Localization.json");
if (!File.Exists(localizationPath))
return false;
var localizationJson = File.ReadAllText(localizationPath);
var localizationData = JObject.Parse(localizationJson);
var localizationSettings = localizationData["Localization Settings"];
if (localizationSettings == null)
return false;
var elements = localizationSettings["UI Elements"] as JObject;
if (elements == null)
return false;
foreach (var kvp in elements)
{
var key = kvp.Key;
if (!key.Contains('_') || key.Split('_').Length < 3) return true;
}
return false;
}
catch (Exception ex)
{
Instance?.PrintError($"Error checking localization migration need: {ex.Message}");
return false;
}
}
public void Execute()
{
try
{
var localizationPath = Path.Combine(Interface.Oxide.DataDirectory, "ServerPanel", "Localization.json");
var categoriesPath = Path.Combine(Interface.Oxide.DataDirectory, "ServerPanel", "Categories.json");
if (!File.Exists(localizationPath) || !File.Exists(categoriesPath))
{
Instance?.PrintWarning("Required files not found for localization migration");
return;
}
var localizationJson = File.ReadAllText(localizationPath);
var categoriesJson = File.ReadAllText(categoriesPath);
var localizationData = JObject.Parse(localizationJson);
var categoriesData = JObject.Parse(categoriesJson);
MigrateLocalizationFormat(localizationData, categoriesData);
File.WriteAllText(localizationPath, localizationData.ToString(Formatting.Indented));
Instance?.Puts("Localization format migration completed");
}
catch (Exception ex)
{
Instance?.PrintError($"Localization migration failed: {ex.Message}");
throw;
}
}
private void MigrateLocalizationFormat(JObject localizationData, JObject categoriesData)
{
var localizationSettings = localizationData["Localization Settings"];
if (localizationSettings == null)
return;
var elements = localizationSettings["UI Elements"] as JObject;
if (elements == null)
return;
var categories = categoriesData["Categories"] as JArray;
if (categories == null)
return;
var elementsToMigrate = new List<(string oldKey, string newKey, JToken data)>();
foreach (var kvp in elements)
{
var key = kvp.Key;
var elementData = kvp.Value;
if (!key.Contains('_') || key.Split('_').Length < 3)
foreach (var categoryToken in categories)
{
var category = categoryToken as JObject;
if (category == null) continue;
var categoryId = category["ID"]?.Value<int>() ?? 0;
var pages = category["Pages"] as JArray;
if (pages == null) continue;
for (var pageIndex = 0; pageIndex < pages.Count; pageIndex++)
{
var page = pages[pageIndex] as JObject;
if (page == null) continue;
var pageElements = page["UI Elements"] as JArray;
if (pageElements == null) continue;
foreach (var elementToken in pageElements)
{
var element = elementToken as JObject;
if (element == null) continue;
var elementName = element["Name"]?.Value<string>();
if (elementName == key)
{
var newKey = $"{categoryId}_{pageIndex}_{key}";
elementsToMigrate.Add((key, newKey, elementData));
}
}
}
}
}
foreach (var migration in elementsToMigrate)
if (elements[migration.newKey] == null)
elements[migration.newKey] = migration.data;
}
}
public class V1ToV2Migration : IMigration
{
public string Name => "2.0.0";
public bool IsNeeded()
{
try
{
var configPath = Path.Combine(Interface.Oxide.ConfigDirectory, "ServerPanel.json");
if (!File.Exists(configPath)) return false;
var configJson = File.ReadAllText(configPath);
var configData = JObject.Parse(configJson);
var version = configData["Version"]?.ToObject<VersionNumber>();
return version == default || version == null || version < new VersionNumber(2, 0, 0);
}
catch (Exception ex)
{
Instance?.PrintError($"Error checking V1 to V2 migration need: {ex.Message}");
return false;
}
}
public void Execute()
{
try
{
MigrateTemplateData();
MigrateCategoriesData();
Instance?.Puts("=== Migration completed! ===");
}
catch (Exception ex)
{
Instance?.PrintError($"Migration failed: {ex.Message}");
throw;
}
}
private void MigrateCategoriesData()
{
var categoriesPath = Path.Combine(Interface.Oxide.DataDirectory, "ServerPanel", "Categories.json");
if (!File.Exists(categoriesPath)) return;
var categoriesJson = File.ReadAllText(categoriesPath);
var categoriesData = JObject.Parse(categoriesJson);
if (categoriesData["Categories"] is not JArray categories) return;
foreach (var category in categories)
if (category["Pages"] is JArray pages)
foreach (var page in pages)
{
var pageType = page["Type (Plugin/UI)"]?.Value<string>();
if (pageType == "Plugin") category["Show Pages?"] = false;
}
var updatedJson = JsonConvert.SerializeObject(categoriesData, Formatting.Indented);
File.WriteAllText(categoriesPath, updatedJson);
Instance?.Puts(" Categories.json migrated");
}
private void MigrateTemplateData()
{
var templatePath = Path.Combine(Interface.Oxide.DataDirectory, "ServerPanel", "Template.json");
if (!File.Exists(templatePath))
return;
var json = File.ReadAllText(templatePath);
var data = JObject.Parse(json);
var templateName = data?["UI Settings"]?["ID (DONT CHANGE)"]?.Value<string>();
if (templateName == null)
{
Instance?.PrintError("Template name not found");
return;
}
#region Parent
if (data?["UI Settings"]?["Background"]?["Parent (Overlay/Hud)"] is JObject parentLayer)
parentLayer["Parent (Overlay/Hud)"] = "OverlayNonScaled";
#endregion Parent
#region Text Pagination Settings
if (data?["UI Settings"]?["Content"]?["Pagination"]?["Text Pagination Settings"] is JObject
textPaginationSettings)
{
if (textPaginationSettings["Button Back"] is JObject buttonBack)
{
buttonBack["Use Icon"] = true;
buttonBack["Icon"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0f,
["AnchorMin (Y)"] = 0f,
["AnchorMax (X)"] = 1f,
["AnchorMax (Y)"] = 1f,
["OffsetMin (X)"] = 0f,
["OffsetMin (Y)"] = 0f,
["OffsetMax (X)"] = 0f,
["OffsetMax (Y)"] = 0f
};
}
if (textPaginationSettings["Button Next"] is JObject buttonNext)
{
buttonNext["Use Icon"] = true;
buttonNext["Icon"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0f,
["AnchorMin (Y)"] = 0f,
["AnchorMax (X)"] = 1f,
["AnchorMax (Y)"] = 1f,
["OffsetMin (X)"] = 0f,
["OffsetMin (Y)"] = 0f,
["OffsetMax (X)"] = 0f,
["OffsetMax (Y)"] = 0f
};
}
}
#endregion Text Pagination Settings
#region Multiple Buttons Settings
if (data?["UI Settings"]?["Content"]?["Pagination"]?["Multiple Buttons Settings"] is JObject
multipleButtonsSettings)
{
if (multipleButtonsSettings["Button Back"] is JObject buttonBack)
{
buttonBack["Use Icon"] = true;
buttonBack["Icon"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0f,
["AnchorMin (Y)"] = 0f,
["AnchorMax (X)"] = 1f,
["AnchorMax (Y)"] = 1f,
["OffsetMin (X)"] = 0f,
["OffsetMin (Y)"] = 0f,
["OffsetMax (X)"] = 0f,
["OffsetMax (Y)"] = 0f
};
}
if (multipleButtonsSettings["Button Next"] is JObject buttonNext)
{
buttonNext["Use Icon"] = true;
buttonNext["Icon"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0f,
["AnchorMin (Y)"] = 0f,
["AnchorMax (X)"] = 1f,
["AnchorMax (Y)"] = 1f,
["OffsetMin (X)"] = 0f,
["OffsetMin (Y)"] = 0f,
["OffsetMax (X)"] = 0f,
["OffsetMax (Y)"] = 0f
};
}
}
#endregion Multiple Buttons Settings
#region Sub Categories Settings
if (data?["UI Settings"]?["Content"]?["Pagination"] is JObject paginationSettings)
paginationSettings["Sub Categories Settings"] = new JObject
{
["Background"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0.0,
["AnchorMin (Y)"] = 0.0,
["AnchorMax (X)"] = 1.0,
["AnchorMax (Y)"] = 1.0,
["OffsetMin (X)"] = 0.0,
["OffsetMin (Y)"] = 0.0,
["OffsetMax (X)"] = 0.0,
["OffsetMax (Y)"] = 0.0
},
["Scroll Settings"] = new JObject
{
["Scroll Type"] = "Horizontal",
["Movement Type"] = "Unrestricted",
["Elasticity"] = 0.0,
["Deceleration Rate"] = 0.0,
["Scroll Sensitivity"] = 0.0,
["Scrollbar Settings"] = new JObject
{
["Invert"] = false,
["Auto Hide"] = false,
["Handle Sprite"] = null,
["Size"] = 0.0,
["Handle Color"] = null,
["Highlight Color"] = null,
["Pressed Color"] = null,
["Track Sprite"] = null,
["Track Color"] = null
},
["Scroll Size"] = 0.0,
["AnchorMin (X)"] = 0.0,
["AnchorMin (Y)"] = 0.0,
["AnchorMax (X)"] = 1.0,
["AnchorMax (Y)"] = 1.0,
["OffsetMin (X)"] = 0.0,
["OffsetMin (Y)"] = 0.0,
["OffsetMax (X)"] = 0.0,
["OffsetMax (Y)"] = 0.0
},
["Sub Category Button"] = new JObject
{
["Width"] = 0.0,
["Margin"] = 0.0,
["Background"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0.0,
["AnchorMin (Y)"] = 0.0,
["AnchorMax (X)"] = 1.0,
["AnchorMax (Y)"] = 1.0,
["OffsetMin (X)"] = 0.0,
["OffsetMin (Y)"] = 0.0,
["OffsetMax (X)"] = 0.0,
["OffsetMax (Y)"] = 0.0
},
["Title"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0.0,
["AnchorMin (Y)"] = 0.0,
["AnchorMax (X)"] = 1.0,
["AnchorMax (Y)"] = 1.0,
["OffsetMin (X)"] = 0.0,
["OffsetMin (Y)"] = 0.0,
["OffsetMax (X)"] = 0.0,
["OffsetMax (Y)"] = 0.0
},
["Use Icon"] = false,
["Icon"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0f,
["AnchorMin (Y)"] = 0f,
["AnchorMax (X)"] = 1f,
["AnchorMax (Y)"] = 1f,
["OffsetMin (X)"] = 0f,
["OffsetMin (Y)"] = 0f,
["OffsetMax (X)"] = 0f,
["OffsetMax (Y)"] = 0f
}
},
["Sub Category Selected Button"] = new JObject
{
["Width"] = 0.0,
["Margin"] = 0.0,
["Background"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0.0,
["AnchorMin (Y)"] = 0.0,
["AnchorMax (X)"] = 1.0,
["AnchorMax (Y)"] = 1.0,
["OffsetMin (X)"] = 0.0,
["OffsetMin (Y)"] = 0.0,
["OffsetMax (X)"] = 0.0,
["OffsetMax (Y)"] = 0.0
},
["Title"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0.0,
["AnchorMin (Y)"] = 0.0,
["AnchorMax (X)"] = 1.0,
["AnchorMax (Y)"] = 1.0,
["OffsetMin (X)"] = 0.0,
["OffsetMin (Y)"] = 0.0,
["OffsetMax (X)"] = 0.0,
["OffsetMax (Y)"] = 0.0
},
["Use Icon"] = false,
["Icon"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject {["HEX"] = "#FFFFFF", ["Opacity (0 - 100)"] = 100f},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0f,
["AnchorMin (Y)"] = 0f,
["AnchorMax (X)"] = 1f,
["AnchorMax (Y)"] = 1f,
["OffsetMin (X)"] = 0f,
["OffsetMin (Y)"] = 0f,
["OffsetMax (X)"] = 0f,
["OffsetMax (Y)"] = 0f
}
},
["Edit Page Button"] = null,
["AnchorMin (X)"] = 0.0,
["AnchorMin (Y)"] = 0.0,
["AnchorMax (X)"] = 1.0,
["AnchorMax (Y)"] = 1.0,
["OffsetMin (X)"] = 0.0,
["OffsetMin (Y)"] = 0.0,
["OffsetMax (X)"] = 0.0,
["OffsetMax (Y)"] = 0.0
};
#endregion Sub Categories Settings
#region Edit Button
if (data?["UI Settings"]?["Content"]?["Edit Button"] is JObject contentEditButton)
{
#region Background
contentEditButton["Background"] = new JObject
{
["Enabled?"] = true,
["Visible"] = true,
["Name"] = GenerateElementGUID("Panel"),
["Type (Label/Panel/Button/Image)"] = "Panel",
["Color"] = new JObject
{
["HEX"] = "#175782",
["Opacity (0 - 100)"] = 100.0
},
["Text"] = new JArray(),
["Font Size"] = 14,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0.0,
["AnchorMin (Y)"] = 0.0,
["AnchorMax (X)"] = 0.0,
["AnchorMax (Y)"] = 0.0,
["OffsetMin (X)"] = 40.0,
["OffsetMin (Y)"] = 10.0,
["OffsetMax (X)"] = 140.0,
["OffsetMax (Y)"] = 36.0
};
#endregion Background
#region Title
contentEditButton["Title"] = new JObject
{
["Enabled?"] = true,
["Visible"] = true,
["Name"] = GenerateElementGUID("Label"),
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Text"] = new JArray("EDIT CONTENT"),
["Font Size"] = 10,
["Font"] = 0,
["Align"] = "MiddleLeft",
["Text Color"] = new JObject
{
["HEX"] = "#68C2FF",
["Opacity (0 - 100)"] = 100.0
},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0.0,
["AnchorMin (Y)"] = 0.0,
["AnchorMax (X)"] = 1.0,
["AnchorMax (Y)"] = 1.0,
["OffsetMin (X)"] = 27.0,
["OffsetMin (Y)"] = 0.0,
["OffsetMax (X)"] = 0.0,
["OffsetMax (Y)"] = 0.0
};
#endregion Title
#region Icon
contentEditButton["Icon"] = new JObject
{
["Enabled?"] = true,
["Visible"] = true,
["Name"] = GenerateElementGUID("Image"),
["Type (Label/Panel/Button/Image)"] = "Image",
["Color"] = new JObject
{
["HEX"] = "#68C2FF",
["Opacity (0 - 100)"] = 100.0
},
["Text"] = new JArray(),
["Font Size"] = 14,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Command ({user} - user steamid)"] = "",
["Image"] = "assets/icons/level_metal.png",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0.0,
["AnchorMin (Y)"] = 0.5,
["AnchorMax (X)"] = 0.0,
["AnchorMax (Y)"] = 0.5,
["OffsetMin (X)"] = 10.0,
["OffsetMin (Y)"] = -6.0,
["OffsetMax (X)"] = 22.0,
["OffsetMax (Y)"] = 6.0
};
#endregion Icon
contentEditButton["Description Background"] = null;
contentEditButton["Description Title"] = null;
}
#endregion Edit Button
#region Header
if (data?["UI Settings"]?["Header"] is JObject header)
{
header["Show line?"] = false;
header["Line"] = new JObject
{
["Enabled?"] = false,
["Visible"] = true,
["Name"] = "",
["Type (Label/Panel/Button/Image)"] = "Label",
["Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Text"] = new JArray(),
["Font Size"] = 0,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject
{
["HEX"] = "#FFFFFF",
["Opacity (0 - 100)"] = 100.0
},
["Command ({user} - user steamid)"] = "",
["Image"] = "",
["Cursor Enabled"] = false,
["Keyboard Enabled"] = false,
["Sprite"] = "",
["Material"] = "",
["AnchorMin (X)"] = 0.0,
["AnchorMin (Y)"] = 0.0,
["AnchorMax (X)"] = 1.0,
["AnchorMax (Y)"] = 1.0,
["OffsetMin (X)"] = 0.0,
["OffsetMin (Y)"] = 0.0,
["OffsetMax (X)"] = 0.0,
["OffsetMax (Y)"] = 0.0
};
header["Edit Button"] = new JObject
{
["Background"] = new JObject
{
["Enabled?"] = true,
["Visible"] = true,
["Name"] = GenerateElementGUID("Panel"),
["Type (Label/Panel/Button/Image)"] = "Panel",
["Color"] = new JObject
{
["HEX"] = "#175782",
["Opacity (0 - 100)"] = 100.0
},
["Text"] = new JArray(),
["Font Size"] = 14,
["Font"] = 0,
["Align"] = "UpperLeft",
["Text Color"] = new JObject
{
["HEX"] = "#FFF
// ... [Code preview truncated due to length. Full source in attached file] ...