Untitled
unknown
plain_text
9 months ago
45 kB
10
Indexable
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("PRZCore", "ShapedByFire", "1.0.0")]
[Description("Plugin Manager, Config Editor and Permission Manager for PRZ plugins, with limited support for other plugins.")]
public class PRZCore : CovalencePlugin
{
private const string UiPrefix = "PRZCoreUI_";
private const string UiConfigPrefix = "PRZCoreConfig_";
private const string UiPermPrefix = "PRZCorePerm_";
private const string PermissionUse = "przcore.use";
private readonly HashSet<string> ExcludedPlugins = new(StringComparer.OrdinalIgnoreCase) { "RustCore", "PRZCore", "UnityCore" };
private HashSet<string> TrackedPlugins = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private HashSet<string> PluginsStatus = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private Dictionary<string, int> _pagePositions = new Dictionary<string, int>();
private Dictionary<string, string> _configEditBuffer = new Dictionary<string, string>();
private void Init()
{
TrackPlugins();
permission.RegisterPermission(PermissionUse, this);
AddCovalenceCommand("przcore", "CmdPrzcore");
AddCovalenceCommand("przcore.reload", "CmdPrzcoreReload");
AddCovalenceCommand("przcore.unload", "CmdPrzcoreUnload");
AddCovalenceCommand("przcore.reloadall", "CmdPrzcoreReloadAll");
AddCovalenceCommand("przcore.scan", "CmdPrzCoreScan");
AddCovalenceCommand("przcore.closeui", "CmdPrzcoreCloseUI");
AddCovalenceCommand("przcore.changepage", "CmdPrzcoreChangePage");
AddCovalenceCommand("przcore.openconfig", "CmdPrzcoreOpenConfig");
AddCovalenceCommand("przcore.saveconfig", "CmdPrzcoreSaveConfig");
AddCovalenceCommand("przcore.resetconfig", "CmdPrzcoreResetConfig");
AddCovalenceCommand("przcore.closeconfig", "CmdPrzcoreCloseConfig");
AddCovalenceCommand("przcore.updateconfig", "CmdPrzcoreUpdateConfig");
AddCovalenceCommand("przcore.manageperm", "CmdPrzcoreManagePerm");
AddCovalenceCommand("przcore.toggleperm", "CmdPrzcoreTogglePerm");
AddCovalenceCommand("przcore.toggleadmin", "CmdPrzcoreToggleAdmin");
AddCovalenceCommand("przcore.closeperm", "CmdPrzcoreClosePerm");
AddCovalenceCommand("przcore.changepageperm", "CmdPrzcoreChangePagePerm");
}
private void OnPluginLoaded(Plugin plugin)
{
if (!ExcludedPlugins.Contains(plugin.Name))
TrackedPlugins.Add(plugin.Name);
PluginsStatus.Add(plugin.Name);
}
private void OnPluginUnloaded(Plugin plugin)
{
PluginsStatus.Remove(plugin.Name);
}
private void TrackPlugins()
{
var allPlugins = plugins.GetAll().Select(p => p.Name);
if (!PluginsStatus.SetEquals(allPlugins))
{
PluginsStatus.Clear();
foreach (var name in allPlugins)
PluginsStatus.Add(name);
}
foreach (var name in allPlugins)
{
if (!ExcludedPlugins.Contains(name))
TrackedPlugins.Add(name);
}
}
#region Commands
private void CmdPrzcore(IPlayer player, string command, string[] args)
{
if (!player.HasPermission(PermissionUse)) { player.Reply("You don't have permission to use this command."); return; }
_pagePositions[player.Id] = 0;
ShowMainUI(player);
}
private void CmdPrzcoreChangePage(IPlayer player, string command, string[] args)
{
if (!player.HasPermission(PermissionUse)) { player.Reply("You don't have permission to use this command."); return; }
if (args.Length < 1) return;
int page = int.Parse(args[0]);
_pagePositions[player.Id] = Math.Max(0, page);
UpdateMainUIContent(player);
}
private void CmdPrzcoreReload(IPlayer player, string command, string[] args)
{
if (args.Length < 1) return;
string pluginName = args[0];
Interface.Oxide.ReloadPlugin(pluginName);
player.Reply($"Reloaded {pluginName}");
timer.Once(0.1f, () => UpdateMainUIContent(player));
}
private void CmdPrzcoreUnload(IPlayer player, string command, string[] args)
{
if (args.Length < 1) return;
string pluginName = args[0];
if (pluginName.Equals("PRZCore", StringComparison.OrdinalIgnoreCase))
{
player.Reply("Cannot unload PRZCore");
return;
}
Interface.Oxide.UnloadPlugin(pluginName);
player.Reply($"Unloaded {pluginName}");
timer.Once(0.1f, () => UpdateMainUIContent(player));
}
private void CmdPrzcoreReloadAll(IPlayer player, string command, string[] args)
{
var pluginstoreload = TrackedPlugins.ToList();
int count = 0;
foreach (var p in pluginstoreload)
{
try
{
Interface.Oxide.ReloadPlugin(p);
count++;
}
catch { }
}
player.Reply($"Reloaded {count} plugins.");
UpdateMainUIContent(player);
}
private void CmdPrzCoreScan(IPlayer player, string command, string[] args)
{
int before = TrackedPlugins.Count;
TrackPlugins();
int after = TrackedPlugins.Count;
int newPlugins = after - before;
if (newPlugins > 0)
player.Reply($"Found {newPlugins} new plugin(s). Total tracked: {after}");
else
player.Reply($"No new plugins found. Total tracked: {after}");
UpdateMainUIContent(player);
}
private void CmdPrzcoreCloseUI(IPlayer player, string command, string[] args)
{
DestroyAllUI(player);
_pagePositions.Remove(player.Id);
}
private void CmdPrzcoreOpenConfig(IPlayer player, string command, string[] args)
{
if (args.Length < 1) return;
ShowConfigUI(player, args[0]);
}
private void CmdPrzcoreUpdateConfig(IPlayer player, string command, string[] args)
{
if (args.Length < 2) return;
string pluginName = args[0];
string newJson = string.Join(" ", args.Skip(1));
_configEditBuffer[$"{player.Id}_{pluginName}"] = newJson;
}
private void CmdPrzcoreSaveConfig(IPlayer player, string command, string[] args)
{
if (args.Length < 1) return;
string pluginName = args[0];
if (!_configEditBuffer.ContainsKey($"{player.Id}_{pluginName}"))
{
player.Reply("No config data to save.");
return;
}
string json = _configEditBuffer[$"{player.Id}_{pluginName}"];
SaveConfig(player, pluginName, json);
}
private void CmdPrzcoreResetConfig(IPlayer player, string command, string[] args)
{
if (args.Length < 1) return;
string pluginName = args[0];
string filePath = $"{Interface.Oxide.ConfigDirectory}/{pluginName}.json";
try
{
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
player.Reply($"Deleted config file for {pluginName}. Reloading plugin to generate defaults...");
}
else
{
player.Reply($"No config file found for {pluginName}. Reloading plugin to generate defaults...");
}
_configEditBuffer.Remove($"{player.Id}_{pluginName}");
timer.Once(0.5f, () =>
{
try
{
Interface.Oxide.ReloadPlugin(pluginName);
player.Reply($"{pluginName} reloaded with default configuration.");
}
catch (Exception ex)
{
player.Reply($"Error reloading {pluginName}: {ex.Message}");
}
timer.Once(1f, () =>
{
var basePlayer = player.Object as BasePlayer;
if (basePlayer != null)
{
var iplayer = covalence.Players.FindPlayerById(player.Id);
if (iplayer != null)
ShowConfigUI(iplayer, pluginName);
}
});
});
}
catch (Exception ex)
{
player.Reply($"Error resetting config: {ex.Message}");
}
}
private void CmdPrzcoreCloseConfig(IPlayer player, string command, string[] args)
{
DestroyConfigUI(player);
}
private void CmdPrzcoreManagePerm(IPlayer player, string command, string[] args)
{
_pagePositions[$"{player.Id}_perm"] = 0;
ShowPermissionsUI(player);
}
private void CmdPrzcoreChangePagePerm(IPlayer player, string command, string[] args)
{
if (args.Length < 1) return;
int page = int.Parse(args[0]);
string key = $"{player.Id}_perm";
_pagePositions[key] = Math.Max(0, page);
UpdatePermissionsUIContent(player);
}
private void CmdPrzcoreTogglePerm(IPlayer player, string command, string[] args)
{
if (args.Length < 1) return;
string targetPlayerId = args[0];
var targetPlayer = players.FindPlayer(targetPlayerId);
if (targetPlayer == null)
{
player.Reply("Player not found.");
return;
}
var baseTargetPlayer = targetPlayer.Object as BasePlayer;
int authLevel = GetPlayerAuthLevel(baseTargetPlayer);
// Check if player is owner - can grant but not revoke
if (authLevel >= 3)
{
if (!permission.UserHasPermission(targetPlayer.Id, PermissionUse))
{
permission.GrantUserPermission(targetPlayer.Id, PermissionUse, null);
player.Reply($"Granted przcore.use to {targetPlayer.Name} (Owner)");
}
else
{
player.Reply($"Cannot revoke permission from server owner {targetPlayer.Name}");
}
timer.Once(0.1f, () => UpdatePermissionsUIContent(player));
return;
}
if (permission.UserHasPermission(targetPlayer.Id, PermissionUse))
{
permission.RevokeUserPermission(targetPlayer.Id, PermissionUse);
player.Reply($"Revoked przcore.use from {targetPlayer.Name}");
}
else
{
permission.GrantUserPermission(targetPlayer.Id, PermissionUse, null);
player.Reply($"Granted przcore.use to {targetPlayer.Name}");
}
timer.Once(0.1f, () => UpdatePermissionsUIContent(player));
}
private int GetPlayerAuthLevel(BasePlayer player)
{
if (player == null) return 0;
// Check ServerUsers for persistent auth level
if (ServerUsers.Is(player.userID, ServerUsers.UserGroup.Owner))
return 3;
if (ServerUsers.Is(player.userID, ServerUsers.UserGroup.Moderator))
return 2;
// Fallback to connection auth level
if (player.net?.connection != null)
return (int)player.net.connection.authLevel;
return 0;
}
private void CmdPrzcoreToggleAdmin(IPlayer player, string command, string[] args)
{
if (args.Length < 1) return;
string targetPlayerId = args[0];
var targetPlayer = players.FindPlayer(targetPlayerId);
if (targetPlayer == null)
{
player.Reply("Player not found.");
return;
}
var basePlayer = targetPlayer.Object as BasePlayer;
if (basePlayer == null)
{
player.Reply("Unable to access player object.");
return;
}
// Check if player is owner (auth level 3) - cannot be changed
int authLevel = GetPlayerAuthLevel(basePlayer);
if (authLevel >= 3)
{
player.Reply($"Cannot modify owner privileges for {targetPlayer.Name}");
timer.Once(0.1f, () => UpdatePermissionsUIContent(player));
return;
}
if (authLevel >= 2)
{
// Revoke admin
ServerUsers.Remove(basePlayer.userID);
basePlayer.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, false);
basePlayer.SendNetworkUpdateImmediate();
if (basePlayer.net?.connection != null)
basePlayer.net.connection.authLevel = 0;
ServerUsers.Save();
player.Reply($"Revoked admin from {targetPlayer.Name} (persistent)");
}
else
{
// Grant admin
ServerUsers.Set(basePlayer.userID, ServerUsers.UserGroup.Moderator, basePlayer.displayName, "Granted by PRZCore");
basePlayer.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, true);
basePlayer.SendNetworkUpdateImmediate();
if (basePlayer.net?.connection != null)
basePlayer.net.connection.authLevel = (uint)2;
ServerUsers.Save();
player.Reply($"Granted admin to {targetPlayer.Name} (persistent)");
}
timer.Once(0.1f, () => UpdatePermissionsUIContent(player));
}
private void CmdPrzcoreClosePerm(IPlayer player, string command, string[] args)
{
DestroyPermissionsUI(player);
_pagePositions.Remove($"{player.Id}_perm");
}
#endregion
#region Main UI
private void ShowMainUI(IPlayer iplayer)
{
var player = iplayer.Object as BasePlayer;
if (player == null) return;
DestroyUi(iplayer);
string panelName = UiPrefix + player.userID;
var elements = new CuiElementContainer();
// Main background panel
elements.Add(new CuiPanel
{
Image = { Color = "0.05 0.05 0.05 1" },
RectTransform = { AnchorMin = "0.2 0.15", AnchorMax = "0.8 0.85" },
CursorEnabled = true
}, "Overlay", panelName);
// Title
elements.Add(new CuiLabel
{
Text = { Text = "PRZCore - Plugin Manager", FontSize = 20, Align = TextAnchor.MiddleCenter },
RectTransform = { AnchorMin = "0.02 0.93", AnchorMax = "0.98 0.98" }
}, panelName);
// Footer hint
elements.Add(new CuiLabel
{
Text = { Text = "Bind the Plugin Manager to F2 using this console command: bind f2 chat.say /przcore", FontSize = 11, Align = TextAnchor.MiddleCenter, Color = "0.6 0.6 0.3 1" },
RectTransform = { AnchorMin = "0.25 0.02", AnchorMax = "0.75 0.05" }
}, panelName);
// Close button
elements.Add(new CuiButton
{
Button = { Command = "przcore.closeui", Color = "0.8 0.2 0.2 1" },
RectTransform = { AnchorMin = "0.88 0.94", AnchorMax = "0.98 0.98" },
Text = { Text = "✖ Close", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, panelName);
// Top buttons
elements.Add(new CuiButton
{
Button = { Command = "przcore.scan", Color = "0.3 0.4 0.5 1" },
RectTransform = { AnchorMin = "0.02 0.86", AnchorMax = "0.245 0.91" },
Text = { Text = "Update Plugins List", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, panelName);
elements.Add(new CuiButton
{
Button = { Command = "przcore.reloadall", Color = "0.25 0.5 0.5 1" },
RectTransform = { AnchorMin = "0.265 0.86", AnchorMax = "0.49 0.91" },
Text = { Text = "Reload All Plugins", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, panelName);
elements.Add(new CuiButton
{
Button = { Command = "przcore.manageperm", Color = "0.5 0.35 0.25 1" },
RectTransform = { AnchorMin = "0.51 0.86", AnchorMax = "0.735 0.91" },
Text = { Text = "Permissions Manager", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, panelName);
CuiHelper.AddUi(player, elements);
// Show the content panel separately
UpdateMainUIContent(iplayer);
}
private void UpdateMainUIContent(IPlayer iplayer)
{
var player = iplayer.Object as BasePlayer;
if (player == null) return;
string panelName = UiPrefix + player.userID;
string contentPanelName = panelName + "_content";
// Destroy only the content panel
CuiHelper.DestroyUi(player, contentPanelName);
var Pluginslist = TrackedPlugins.OrderBy(n => n).ToList();
var elements = new CuiElementContainer();
// Content container panel (lighter gray)
elements.Add(new CuiPanel
{
Image = { Color = "0.08 0.08 0.08 1" },
RectTransform = { AnchorMin = "0.02 0.08", AnchorMax = "0.98 0.84" }
}, panelName, contentPanelName);
// Column headers
elements.Add(new CuiLabel
{
Text = { Text = "Plugin Name", FontSize = 14, Align = TextAnchor.MiddleLeft, Color = "0.8 0.8 0.8 1" },
RectTransform = { AnchorMin = "0.02 0.94", AnchorMax = "0.22 0.99" }
}, contentPanelName);
elements.Add(new CuiLabel
{
Text = { Text = "Status", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0.8 0.8 0.8 1" },
RectTransform = { AnchorMin = "0.22 0.94", AnchorMax = "0.32 0.99" }
}, contentPanelName);
elements.Add(new CuiLabel
{
Text = { Text = "Actions", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0.8 0.8 0.8 1" },
RectTransform = { AnchorMin = "0.34 0.94", AnchorMax = "0.98 0.99" }
}, contentPanelName);
int itemsPerPage = 10;
int totalPages = (int)Math.Ceiling((double)Pluginslist.Count / itemsPerPage);
int currentPage = _pagePositions.ContainsKey(iplayer.Id) ? _pagePositions[iplayer.Id] : 0;
// Ensure page is within bounds
if (currentPage >= totalPages && totalPages > 0)
currentPage = totalPages - 1;
if (currentPage < 0)
currentPage = 0;
_pagePositions[iplayer.Id] = currentPage;
// Pagination controls
if (totalPages > 1)
{
// Previous page button
if (currentPage > 0)
{
elements.Add(new CuiButton
{
Button = { Command = $"przcore.changepage {currentPage - 1}", Color = "0.3 0.3 0.3 1" },
RectTransform = { AnchorMin = "0.35 0.01", AnchorMax = "0.42 0.05" },
Text = { Text = "◄ Previous", FontSize = 12, Align = TextAnchor.MiddleCenter }
}, contentPanelName);
}
// Page indicator
elements.Add(new CuiLabel
{
Text = { Text = $"Page {currentPage + 1} of {totalPages}", FontSize = 12, Align = TextAnchor.MiddleCenter, Color = "0.8 0.8 0.8 1" },
RectTransform = { AnchorMin = "0.43 0.01", AnchorMax = "0.57 0.05" }
}, contentPanelName);
// Next page button
if (currentPage < totalPages - 1)
{
elements.Add(new CuiButton
{
Button = { Command = $"przcore.changepage {currentPage + 1}", Color = "0.3 0.3 0.3 1" },
RectTransform = { AnchorMin = "0.58 0.01", AnchorMax = "0.65 0.05" },
Text = { Text = "Next ►", FontSize = 12, Align = TextAnchor.MiddleCenter }
}, contentPanelName);
}
}
// Calculate item range for current page
int startIndex = currentPage * itemsPerPage;
int endIndex = Math.Min(startIndex + itemsPerPage, Pluginslist.Count);
float startY = 0.91f, rowHeight = 0.08f;
for (int i = startIndex; i < endIndex; i++)
{
string name = Pluginslist[i];
int displayIndex = i - startIndex;
float top = startY - displayIndex * rowHeight;
float bottom = top - rowHeight + 0.005f;
bool isLoaded = PluginsStatus.Contains(name);
string statusText = isLoaded ? "● Active" : "○ Inactive";
string statusColor = isLoaded ? "0.2 0.8 0.2 1" : "0.8 0.2 0.2 1";
elements.Add(new CuiLabel
{
Text = { Text = name, FontSize = 14, Align = TextAnchor.MiddleLeft },
RectTransform = { AnchorMin = $"0.02 {bottom}", AnchorMax = $"0.22 {top}" }
}, contentPanelName);
elements.Add(new CuiLabel
{
Text = { Text = statusText, FontSize = 14, Align = TextAnchor.MiddleCenter, Color = statusColor },
RectTransform = { AnchorMin = $"0.22 {bottom}", AnchorMax = $"0.32 {top}" }
}, contentPanelName);
elements.Add(new CuiButton
{
Button = { Command = $"przcore.reload {name}", Color = "0.25 0.5 0.25 1" },
RectTransform = { AnchorMin = $"0.34 {bottom}", AnchorMax = $"0.5 {top}" },
Text = { Text = "↻ Reload", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, contentPanelName);
elements.Add(new CuiButton
{
Button = { Command = $"przcore.unload {name}", Color = "0.5 0.25 0.25 1" },
RectTransform = { AnchorMin = $"0.51 {bottom}", AnchorMax = $"0.67 {top}" },
Text = { Text = "✖ Unload", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, contentPanelName);
elements.Add(new CuiButton
{
Button = { Command = $"przcore.openconfig {name}", Color = "0.25 0.25 0.5 1" },
RectTransform = { AnchorMin = $"0.68 {bottom}", AnchorMax = $"0.98 {top}" },
Text = { Text = "⚙ Edit Configuration", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, contentPanelName);
}
CuiHelper.AddUi(player, elements);
}
private void DestroyUi(IPlayer player)
{
var basePlayer = player.Object as BasePlayer;
if (basePlayer == null) return;
CuiHelper.DestroyUi(basePlayer, UiPrefix + basePlayer.userID);
}
private void DestroyAllUI(IPlayer player)
{
var basePlayer = player.Object as BasePlayer;
if (basePlayer == null) return;
CuiHelper.DestroyUi(basePlayer, UiPrefix + basePlayer.userID);
CuiHelper.DestroyUi(basePlayer, UiConfigPrefix + basePlayer.userID);
CuiHelper.DestroyUi(basePlayer, UiPermPrefix + basePlayer.userID);
}
#endregion
#region Config Editor UI
private void ShowConfigUI(IPlayer iplayer, string pluginName)
{
var player = iplayer.Object as BasePlayer;
if (player == null) return;
DestroyConfigUI(iplayer);
string filePath = $"{Interface.Oxide.ConfigDirectory}/{pluginName}.json";
string displayJson = "{}";
if (System.IO.File.Exists(filePath))
{
try
{
string raw = System.IO.File.ReadAllText(filePath);
try
{
var parsed = JsonConvert.DeserializeObject(raw);
if (parsed is string innerJson)
{
try
{
var innerObj = JsonConvert.DeserializeObject(innerJson);
displayJson = JsonConvert.SerializeObject(innerObj, Formatting.Indented);
}
catch
{
displayJson = innerJson;
}
}
else
{
displayJson = JsonConvert.SerializeObject(parsed, Formatting.Indented);
}
}
catch
{
displayJson = raw;
}
displayJson = displayJson.Replace("\r\n", "\n").Replace("\r", "\n");
}
catch (Exception ex)
{
iplayer.Reply($"Error reading config: {ex.Message}");
displayJson = "Error loading config file";
}
}
else
{
var plugin = plugins.GetAll().FirstOrDefault(p => p.Name.Equals(pluginName, StringComparison.OrdinalIgnoreCase));
if (plugin != null && plugin.Config != null)
{
try
{
displayJson = JsonConvert.SerializeObject(plugin.Config, Formatting.Indented);
}
catch { }
}
else
{
displayJson = "No config file found";
}
}
_configEditBuffer[$"{iplayer.Id}_{pluginName}"] = displayJson;
string panelName = UiConfigPrefix + player.userID;
var elements = new CuiElementContainer();
elements.Add(new CuiPanel
{
Image = { Color = "0.05 0.05 0.05 1" },
RectTransform = { AnchorMin = "0.2 0.15", AnchorMax = "0.8 0.85" },
CursorEnabled = true
}, "Overlay", panelName);
elements.Add(new CuiLabel
{
Text = { Text = $"PRZCore - Config Editor ({pluginName})", FontSize = 20, Align = TextAnchor.MiddleCenter },
RectTransform = { AnchorMin = "0.02 0.93", AnchorMax = "0.98 0.98" }
}, panelName);
elements.Add(new CuiButton
{
Button = { Command = "przcore.closeconfig", Color = "0.8 0.2 0.2 1" },
RectTransform = { AnchorMin = "0.88 0.94", AnchorMax = "0.98 0.98" },
Text = { Text = "✖ Close", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, panelName);
elements.Add(new CuiButton
{
Button = { Command = $"przcore.saveconfig {pluginName}", Color = "0.2 0.6 0.2 1" },
RectTransform = { AnchorMin = "0.02 0.86", AnchorMax = "0.18 0.91" },
Text = { Text = "💾 Save Config", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, panelName);
elements.Add(new CuiButton
{
Button = { Command = $"przcore.resetconfig {pluginName}", Color = "0.6 0.3 0.2 1" },
RectTransform = { AnchorMin = "0.19 0.86", AnchorMax = "0.37 0.91" },
Text = { Text = "🔄 Reset to Default", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, panelName);
elements.Add(new CuiPanel
{
Image = { Color = "0.03 0.03 0.03 1" },
RectTransform = { AnchorMin = "0.02 0.08", AnchorMax = "0.98 0.84" }
}, panelName, panelName + "_content");
elements.Add(new CuiElement
{
Parent = panelName + "_content",
Components =
{
new CuiInputFieldComponent
{
Align = TextAnchor.UpperLeft,
FontSize = 11,
Command = $"przcore.updateconfig {pluginName}",
Text = displayJson,
LineType = UnityEngine.UI.InputField.LineType.MultiLineNewline,
Font = "robotocondensed-regular.ttf",
CharsLimit = 8000
},
new CuiRectTransformComponent
{
AnchorMin = "0.01 0.01",
AnchorMax = "0.99 0.99"
}
}
});
CuiHelper.AddUi(player, elements);
}
private void SaveConfig(IPlayer player, string pluginName, string json)
{
object parsedObj;
try
{
parsedObj = JsonConvert.DeserializeObject(json);
if (parsedObj == null)
{
player.Reply("Invalid JSON format.");
return;
}
}
catch (Exception ex)
{
player.Reply($"Invalid JSON: {ex.Message}");
return;
}
try
{
string formattedJson = JsonConvert.SerializeObject(parsedObj, Formatting.Indented);
formattedJson = formattedJson.Replace("\r\n", "\n").Replace("\r", "\n");
string filePath = $"{Interface.Oxide.ConfigDirectory}/{pluginName}.json";
System.IO.File.WriteAllText(filePath, formattedJson);
_configEditBuffer.Remove($"{player.Id}_{pluginName}");
player.Reply($"Config for {pluginName} saved successfully! Reloading plugin in 1 second...");
timer.Once(1f, () =>
{
try
{
Interface.Oxide.ReloadPlugin(pluginName);
}
catch (Exception ex)
{
player.Reply($"Error reloading {pluginName}: {ex.Message}");
}
timer.Once(0.1f, () =>
{
var basePlayer = player.Object as BasePlayer;
if (basePlayer != null)
{
var iplayer = covalence.Players.FindPlayerById(player.Id);
if (iplayer != null)
ShowConfigUI(iplayer, pluginName);
}
});
});
}
catch (Exception ex)
{
player.Reply($"Error saving config: {ex.Message}");
}
}
private void DestroyConfigUI(IPlayer player)
{
var basePlayer = player.Object as BasePlayer;
if (basePlayer == null) return;
CuiHelper.DestroyUi(basePlayer, UiConfigPrefix + basePlayer.userID);
}
#endregion
#region Permissions Manager UI
private void ShowPermissionsUI(IPlayer iplayer)
{
var player = iplayer.Object as BasePlayer;
if (player == null) return;
DestroyPermissionsUI(iplayer);
string panelName = UiPermPrefix + player.userID;
var elements = new CuiElementContainer();
// Main background panel
elements.Add(new CuiPanel
{
Image = { Color = "0.05 0.05 0.05 1" },
RectTransform = { AnchorMin = "0.2 0.15", AnchorMax = "0.8 0.85" },
CursorEnabled = true
}, "Overlay", panelName);
// Title
elements.Add(new CuiLabel
{
Text = { Text = "PRZCore - Permission Manager", FontSize = 20, Align = TextAnchor.MiddleCenter },
RectTransform = { AnchorMin = "0.02 0.93", AnchorMax = "0.98 0.98" }
}, panelName);
// Close button
elements.Add(new CuiButton
{
Button = { Command = "przcore.closeperm", Color = "0.8 0.2 0.2 1" },
RectTransform = { AnchorMin = "0.88 0.94", AnchorMax = "0.98 0.98" },
Text = { Text = "✖ Close", FontSize = 14, Align = TextAnchor.MiddleCenter }
}, panelName);
CuiHelper.AddUi(player, elements);
// Show the content panel separately
UpdatePermissionsUIContent(iplayer);
}
private void UpdatePermissionsUIContent(IPlayer iplayer)
{
var player = iplayer.Object as BasePlayer;
if (player == null) return;
var onlinePlayers = players.Connected.OrderBy(p => p.Name).ToList();
string panelName = UiPermPrefix + player.userID;
string contentPanelName = panelName + "_content";
// Destroy only the content panel
CuiHelper.DestroyUi(player, contentPanelName);
var elements = new CuiElementContainer();
// Content container panel (lighter gray)
elements.Add(new CuiPanel
{
Image = { Color = "0.08 0.08 0.08 1" },
RectTransform = { AnchorMin = "0.02 0.08", AnchorMax = "0.98 0.84" }
}, panelName, contentPanelName);
// Column headers
elements.Add(new CuiLabel
{
Text = { Text = "Player Name", FontSize = 14, Align = TextAnchor.MiddleLeft, Color = "0.8 0.8 0.8 1" },
RectTransform = { AnchorMin = "0.03 0.94", AnchorMax = "0.33 0.99" }
}, contentPanelName);
elements.Add(new CuiLabel
{
Text = { Text = "Authorization", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0.8 0.8 0.8 1" },
RectTransform = { AnchorMin = "0.33 0.94", AnchorMax = "0.46 0.99" }
}, contentPanelName);
elements.Add(new CuiLabel
{
Text = { Text = "PRZ Permissions", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0.8 0.8 0.8 1" },
RectTransform = { AnchorMin = "0.46 0.94", AnchorMax = "0.61 0.99" }
}, contentPanelName);
elements.Add(new CuiLabel
{
Text = { Text = "Actions", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0.8 0.8 0.8 1" },
RectTransform = { AnchorMin = "0.61 0.94", AnchorMax = "0.97 0.99" }
}, contentPanelName);
int itemsPerPage = 12;
int totalPages = (int)Math.Ceiling((double)onlinePlayers.Count / itemsPerPage);
string pageKey = $"{iplayer.Id}_perm";
int currentPage = _pagePositions.ContainsKey(pageKey) ? _pagePositions[pageKey] : 0;
// Ensure page is within bounds
if (currentPage >= totalPages && totalPages > 0)
currentPage = totalPages - 1;
if (currentPage < 0)
currentPage = 0;
_pagePositions[pageKey] = currentPage;
// Pagination controls and player count
if (totalPages > 1)
{
// Previous page button
if (currentPage > 0)
{
elements.Add(new CuiButton
{
Button = { Command = $"przcore.changepageperm {currentPage - 1}", Color = "0.3 0.3 0.3 1" },
RectTransform = { AnchorMin = "0.30 0.01", AnchorMax = "0.37 0.05" },
Text = { Text = "◄ Previous", FontSize = 12, Align = TextAnchor.MiddleCenter }
}, contentPanelName);
}
// Page indicator
elements.Add(new CuiLabel
{
Text = { Text = $"Page {currentPage + 1} of {totalPages}", FontSize = 12, Align = TextAnchor.MiddleCenter, Color = "0.8 0.8 0.8 1" },
RectTransform = { AnchorMin = "0.38 0.01", AnchorMax = "0.52 0.05" }
}, contentPanelName);
// Next page button
if (currentPage < totalPages - 1)
{
elements.Add(new CuiButton
{
Button = { Command = $"przcore.changepageperm {currentPage + 1}", Color = "0.3 0.3 0.3 1" },
RectTransform = { AnchorMin = "0.53 0.01", AnchorMax = "0.60 0.05" },
Text = { Text = "Next ►", FontSize = 12, Align = TextAnchor.MiddleCenter }
}, contentPanelName);
}
}
// Player count label
elements.Add(new CuiLabel
{
Text = { Text = $"Online Players: {onlinePlayers.Count}", FontSize = 11, Align = TextAnchor.MiddleCenter, Color = "0.6 0.6 0.6 1" },
RectTransform = { AnchorMin = "0.65 0.01", AnchorMax = "0.95 0.05" }
}, contentPanelName);
// Calculate item range for current page
int startIndex = currentPage * itemsPerPage;
int endIndex = Math.Min(startIndex + itemsPerPage, onlinePlayers.Count);
float startY = 0.91f;
float rowHeight = 0.07f;
for (int i = startIndex; i < endIndex; i++)
{
var targetPlayer = onlinePlayers[i];
int displayIndex = i - startIndex;
float top = startY - displayIndex * rowHeight;
float bottom = top - rowHeight + 0.005f;
if (bottom < 0.08f) break;
var baseTargetPlayer = targetPlayer.Object as BasePlayer;
int authLevel = GetPlayerAuthLevel(baseTargetPlayer);
bool isOwner = authLevel >= 3;
bool isAdmin = authLevel >= 2;
string authLevelText = isOwner ? "Owner (3)" : (isAdmin ? "Admin (2)" : "Player (0)");
string authLevelColor = isOwner ? "0.9 0.3 0.3 1" : (isAdmin ? "0.8 0.6 0.2 1" : "0.6 0.6 0.6 1");
bool hasPermission = permission.UserHasPermission(targetPlayer.Id, PermissionUse);
string permStatusText = hasPermission ? "✓ Granted" : "✗ None";
string permStatusColor = hasPermission ? "0.2 0.8 0.2 1" : "0.8 0.2 0.2 1";
string permButtonText = isOwner ? (hasPermission ? "Owner (Protected)" : "Grant Permissions") : (hasPermission ? "Revoke Permissions" : "Grant Permissions");
string permButtonColor = isOwner ? (hasPermission ? "0.3 0.3 0.3 1" : "0.3 0.6 0.3 1") : (hasPermission ? "0.6 0.3 0.3 1" : "0.3 0.6 0.3 1");
string permCommand = (isOwner && hasPermission) ? "" : $"przcore.toggleperm {targetPlayer.Id}";
string adminButtonText = isOwner ? "Owner (Protected)" : (isAdmin ? "Revoke Admin" : "Grant Admin");
string adminButtonColor = isOwner ? "0.3 0.3 0.3 1" : (isAdmin ? "0.7 0.4 0.2 1" : "0.4 0.5 0.7 1");
string adminCommand = isOwner ? "" : $"przcore.toggleadmin {targetPlayer.Id}";
string displayName = targetPlayer.Name.Length > 20 ? targetPlayer.Name.Substring(0, 17) + "..." : targetPlayer.Name;
elements.Add(new CuiLabel
{
Text = { Text = displayName, FontSize = 14, Align = TextAnchor.MiddleLeft },
RectTransform = { AnchorMin = $"0.03 {bottom}", AnchorMax = $"0.33 {top}" }
}, contentPanelName);
elements.Add(new CuiLabel
{
Text = { Text = authLevelText, FontSize = 14, Align = TextAnchor.MiddleCenter, Color = authLevelColor },
RectTransform = { AnchorMin = $"0.33 {bottom}", AnchorMax = $"0.46 {top}" }
}, contentPanelName);
elements.Add(new CuiLabel
{
Text = { Text = permStatusText, FontSize = 14, Align = TextAnchor.MiddleCenter, Color = permStatusColor },
RectTransform = { AnchorMin = $"0.46 {bottom}", AnchorMax = $"0.61 {top}" }
}, contentPanelName);
elements.Add(new CuiButton
{
Button = { Command = adminCommand, Color = adminButtonColor },
RectTransform = { AnchorMin = $"0.61 {bottom}", AnchorMax = $"0.79 {top}" },
Text = { Text = adminButtonText, FontSize = 14, Align = TextAnchor.MiddleCenter }
}, contentPanelName);
elements.Add(new CuiButton
{
Button = { Command = permCommand, Color = permButtonColor },
RectTransform = { AnchorMin = $"0.80 {bottom}", AnchorMax = $"0.98 {top}" },
Text = { Text = permButtonText, FontSize = 14, Align = TextAnchor.MiddleCenter }
}, contentPanelName);
}
if (onlinePlayers.Count == 0)
{
elements.Add(new CuiLabel
{
Text = { Text = "No online players found.", FontSize = 11, Align = TextAnchor.MiddleCenter, Color = "0.6 0.6 0.6 1" },
RectTransform = { AnchorMin = "0.3 0.4", AnchorMax = "0.7 0.6" }
}, contentPanelName);
}
CuiHelper.AddUi(player, elements);
}
private void DestroyPermissionsUI(IPlayer player)
{
var basePlayer = player.Object as BasePlayer;
if (basePlayer == null) return;
CuiHelper.DestroyUi(basePlayer, UiPermPrefix + basePlayer.userID);
}
#endregion
}
}Editor is loading...
Leave a Comment