C#:
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using System.Collections.Generic;
namespace Oxide.Plugins
{
[Info("LeaderboardUI", "TuNombre", "1.0.0")]
public class LeaderboardUI : RustPlugin
{
// Si instalas ImageLibrary, se usará para obtener/cachéar imágenes locales
[PluginReference] private Plugin ImageLibrary;
private string PanelPrefix => "LeaderboardMainPanel_";
private class LbEntry
{
public string name;
public ulong id;
public int score;
public LbEntry(string n, ulong i, int s) { name = n; id = i; score = s; }
}
private List<LbEntry> GetInitialLeaderboard()
{
var list = new List<LbEntry>();
// jugadores conectados
foreach (var p in BasePlayer.activePlayerList)
{
list.Add(new LbEntry(p.displayName, p.userID, 0));
}
// sleepers / desconectados (si no están ya en la lista)
foreach (var s in BasePlayer.sleepingPlayerList)
{
bool exists = false;
foreach (var e in list)
{
if (e.id == s.userID) { exists = true; break; }
}
if (!exists) list.Add(new LbEntry(s.displayName, s.userID, 0));
}
return list;
}
[ChatCommand("showleaderboard")]
private void CmdShowLeaderboard(BasePlayer player, string cmd, string[] args)
{
ShowLeaderboardUI(player);
}
// Console command para cerrar (invocado por botones)
[ConsoleCommand("cerrar_ui")]
private void CCmdCerrarUi(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player == null) return;
if (arg.Args == null || arg.Args.Length < 1) return;
string panel = arg.GetString(0);
CuiHelper.DestroyUi(player, panel);
}
// Console command para reclamar (invocado por botones)
[ConsoleCommand("claim_reward")]
private void CCmdClaimReward(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player == null) return;
if (arg.Args == null || arg.Args.Length < 2) return;
string panel = arg.GetString(0);
int index = 0;
int.TryParse(arg.Args[1], out index);
player.ChatMessage($"Reclamaste la recompensa del panel #{index}");
// ejemplo: podrías dar items aquí o marcar el subpanel como reclamado
// CuiHelper.DestroyUi(player, panel + $"_sub_{index}"); // opcional
}
private void ShowLeaderboardUI(BasePlayer player)
{
string panelName = PanelPrefix + player.userID;
CuiHelper.DestroyUi(player, panelName);
var container = new CuiElementContainer();
// Panel principal
container.Add(new CuiPanel
{
Image = { Color = "0.08 0.08 0.08 0.95" },
RectTransform = { AnchorMin = "0.12 0.12", AnchorMax = "0.88 0.88" },
CursorEnabled = true
}, "Overlay", panelName);
// Título / Leaderboard (lado izquierdo)
container.Add(new CuiLabel
{
Text = { Text = "Leaderboard (Dummy)", FontSize = 20, Align = TextAnchor.UpperLeft, Color = "1 1 1 1" },
RectTransform = { AnchorMin = "0.04 0.60", AnchorMax = "0.48 0.86" }
}, panelName);
// Botón X (cierra con ConsoleCommand "cerrar_ui <panelName>")
container.Add(new CuiButton
{
Button = { Color = "0.8 0.1 0.1 1", Command = $"cerrar_ui {panelName}" },
RectTransform = { AnchorMin = "0.92 0.92", AnchorMax = "0.98 0.98" },
Text = { Text = "X", FontSize = 16, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" }
}, panelName);
// Obtener leaderboard inicial
var board = GetInitialLeaderboard();
// Mostrar lista (izquierda): mostramos hasta N filas (ejemplo 12)
int maxRows = Mathf.Min(board.Count, 12);
float startY = 0.56f;
float rowH = 0.04f;
for (int i = 0; i < maxRows; i++)
{
float yMin = startY - (i * rowH);
float yMax = yMin + rowH;
container.Add(new CuiLabel
{
Text = { Text = $"{i + 1}. {board[i].name} - {board[i].score}", FontSize = 14, Align = TextAnchor.MiddleLeft, Color = "1 1 1 1" },
RectTransform = { AnchorMin = $"0.04 {yMin}", AnchorMax = $"0.48 {yMax}" }
}, panelName);
}
// Lista de subpaneles a la derecha (rewards) - ejemplo con 3 filas
int rows = 3;
float top = 0.86f;
float height = 0.26f;
float spacing = 0.02f;
for (int i = 0; i < rows; i++)
{
string subPanel = panelName + $"_sub_{i}";
float yMax = top - i * (height + spacing);
float yMin = yMax - height;
// Subpanel
container.Add(new CuiPanel
{
Image = { Color = "0.14 0.14 0.14 0.95" },
RectTransform = { AnchorMin = $"0.52 {yMin}", AnchorMax = $"0.98 {yMax}" }
}, panelName, subPanel);
// Iconos: intenta usar ImageLibrary, si no, URL fallback
string scrapUrl = null;
string hqmUrl = null;
if (ImageLibrary != null)
{
scrapUrl = (string)ImageLibrary.Call("GetImage", "scrap");
hqmUrl = (string)ImageLibrary.Call("GetImage", "metal.refined");
Puts($"ImageLibrary scrap ID: {scrapUrl}");
Puts($"ImageLibrary hqm ID: {hqmUrl}");
}
if (string.IsNullOrEmpty(scrapUrl)) scrapUrl = "https://rustlabs.com/img/items180/scrap.png";
if (string.IsNullOrEmpty(hqmUrl)) hqmUrl = "https://rustlabs.com/img/items180/metal.refined.png";
// Scrap icon
container.Add(new CuiElement
{
Name = CuiHelper.GetGuid(),
Parent = subPanel,
Components =
{
new CuiRawImageComponent
{
Png = scrapUrl,
Sprite = "assets/content/textures/generic/fulltransparent.tga",
Color = "1 1 1 1"
},
new CuiRectTransformComponent
{
AnchorMin = "0.03 0.55",
AnchorMax = "0.22 0.92"
}
}
});
// HQM icon
container.Add(new CuiElement
{
Name = CuiHelper.GetGuid(),
Parent = subPanel,
Components =
{
new CuiRawImageComponent
{
Png = hqmUrl,
Sprite = "assets/content/textures/generic/fulltransparent.tga",
Color = "1 1 1 1"
},
new CuiRectTransformComponent
{
AnchorMin = "0.26 0.55",
AnchorMax = "0.45 0.92"
}
}
});
// Botón Reclamar (ConsoleCommand)
container.Add(new CuiButton
{
Button = { Color = "0.18 0.6 0.18 1", Command = $"claim_reward {panelName} {i}" },
RectTransform = { AnchorMin = "0.58 0.08", AnchorMax = "0.92 0.42" },
Text = { Text = "Reclamar", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" }
}, subPanel);
}
CuiHelper.AddUi(player, container);
}
}
}