C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using System.Linq;
using System;
namespace Oxide.Plugins
{
[Info("Scoreboards", "LaserHydra", "1.0.2")]
[Description("Provides a simple scoreboard API system")]
class Scoreboards : RustPlugin
{
static Scoreboards Instance;
static ScoreboardData Data;
#region Config Variables
static string AnchorMin;
static string AnchorMax;
static string BackgroundColor;
static string HeaderColor;
static string TitleColor;
static string ContentColor;
#endregion
#region Classes
public class ScoreboardData
{
public string ActiveScoreboard = string.Empty;
public List<Scoreboard> All = new List<Scoreboard>();
}
public class Scoreboard
{
public static Scoreboard Find(string Title) => Data.All.Find((s) => s.Title == Title);
public string Title;
public string Description;
internal bool Active => Data.ActiveScoreboard == Title;
internal KeyValuePair<string, string>[] Entries = new KeyValuePair<string, string>[0];
public override int GetHashCode() => Title.GetHashCode();
public void Remove() => Data.All.Remove(this);
public void SetActive() => SetActiveScoreboard(this);
public void SetEntries(KeyValuePair<string, string>[] Entries)
{
this.Entries = Entries;
Instance.ScoreboardUpdated(this);
}
public static void SetActiveScoreboard(Scoreboard scoreboard)
{
Data.ActiveScoreboard = scoreboard.Title;
Instance.ActiveScoreboardChanged(scoreboard);
}
public static Scoreboard GetActiveScoreboard() => Data.All.Find((s) => s.Active);
public static void AddScoreboard(Scoreboard scoreboard)
{
if (!Data.All.Contains(scoreboard))
{
Data.All.Add(scoreboard);
Instance.WriteData(Data);
}
}
}
#endregion
#region API
void UpdateScoreboard(string ScoreboardTitle, KeyValuePair<string, string>[] Entries)
{
var scoreboard = Scoreboard.Find(ScoreboardTitle);
if (scoreboard == null)
return;
scoreboard.SetEntries(Entries);
}
void CreateScoreboard(string ScoreboardTitle, string ScoreboardDescription, KeyValuePair<string, string>[] Entries)
{
if (Scoreboard.Find(ScoreboardTitle) != null)
return;
Scoreboard.AddScoreboard(new Scoreboard { Title = ScoreboardTitle, Description = ScoreboardDescription, Entries = Entries.Take(10).ToArray() });
}
void RemoveScoreboard(string ScoreboardTitle)
{
var scoreboard = Scoreboard.Find(ScoreboardTitle);
if (scoreboard == null)
return;
scoreboard.Remove();
}
#endregion
#region Scoreboards
void ScoreboardUpdated(Scoreboard scoreboard)
{
WriteData(Data);
if (scoreboard.Active)
UpdateScoreboardUI();
}
void ActiveScoreboardChanged(Scoreboard scoreboard)
{
UpdateScoreboardUI();
WriteData(Data);
}
void UpdateScoreboardUI()
{
foreach (var player in BasePlayer.activePlayerList)
DrawScoreboardUI(player);
}
void DrawScoreboardUI(BasePlayer player)
{
CuiHelper.DestroyUi(player, "Scoreboard");
var cui = GetCUI();
if (cui != null)
CuiHelper.AddUi(player, cui);
}
static CuiElementContainer GetCUI()
{
var activeScoreboard = Scoreboard.GetActiveScoreboard();
if (activeScoreboard == null)
return null;
CuiElementContainer elements = new CuiElementContainer();
elements.Add(new CuiPanel
{
Image =
{
Color = BackgroundColor
},
RectTransform =
{
AnchorMin = AnchorMin,
AnchorMax = AnchorMax
}
}, "Under", "Scoreboard");
elements.Add(new CuiElement
{
Name = "Header",
Parent = "Scoreboard",
Components =
{
new CuiTextComponent
{
Text = "Scoreboard",
Align = TextAnchor.LowerCenter,
FontSize = 28,
Color = HeaderColor
},
new CuiRectTransformComponent
{
AnchorMin = "0.06372549 0.8822171",
AnchorMax = "0.9411765 0.9676675"
}
}
});
elements.Add(new CuiElement
{
Name = "Title",
Parent = "Scoreboard",
Components =
{
new CuiTextComponent
{
Text = activeScoreboard.Title,
Align = TextAnchor.UpperCenter,
FontSize = 18,
Color = TitleColor
},
new CuiRectTransformComponent
{
AnchorMin = "0.06372549 0.8337182",
AnchorMax = "0.9411765 0.8960739"
}
}
});
elements.Add(new CuiElement
{
Name = "Contents",
Parent = "Scoreboard",
Components =
{
new CuiTextComponent
{
Text = string.Join("\n", activeScoreboard.Entries.Select((kvp) => $"{kvp.Key}: {kvp.Value}").ToArray()),
Align = TextAnchor.UpperCenter,
FontSize = 18,
Color = ContentColor
},
new CuiRectTransformComponent
{
AnchorMin = "0.06372549 0.0277136",
AnchorMax = "0.9411765 0.8337182"
}
}
});
return elements;
}
#endregion
#region Commands
[ChatCommand("scoreboard")]
void cmdScoreboard(BasePlayer player, string cmd, string[] args)
{
if (!permission.UserHasPermission(player.UserIDString, "scoreboards.admin"))
{
SendReply(player, LangMsg("No Permission", player.userID));
return;
}
if (args.Length == 0)
{
SendReply(player, "/scoreboard <select|disable|list>");
return;
}
switch (args[0].ToLower())
{
case "select":
if (args.Length != 2)
{
SendReply(player, "Syntax: /scoreboard select <scoreboard>");
return;
}
var scoreboard = Scoreboard.Find(args[1]);
if (scoreboard == null)
{
SendReply(player, LangMsg("Scoreboard Does Not Exist", player.userID, args[1]));
return;
}
scoreboard.SetActive();
SendReply(player, LangMsg("Scoreboard Selected", player.userID, scoreboard.Title));
break;
case "disable":
Scoreboard.SetActiveScoreboard(new Scoreboard { Title = string.Empty });
SendReply(player, LangMsg("Scoreboard Disabled", player.userID));
break;
case "list":
SendReply(player, $"Scoreboards:{Environment.NewLine}{string.Join(Environment.NewLine, Data.All.Select((s) => $"{s.Title} - {s.Description}").ToArray())}");
break;
default:
SendReply(player, "/scoreboard <select|disable|list>");
break;
}
}
#endregion
#region Hooks
void Init()
{
Instance = this;
permission.RegisterPermission("scoreboards.admin", this);
ReadData(out Data);
LoadConfig();
}
void OnServerInitialized()
{
CreateScoreboard("Bullets Fired", "Shows the amount of fired bullets", new KeyValuePair<string, string>[0]);
UpdateScoreboardUI();
}
void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
CuiHelper.DestroyUi(player, "Scoreboard");
}
void OnPlayerSleepEnded(BasePlayer player)
{
DrawScoreboardUI(player);
}
#endregion
#region Loading
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
{ "No Permission", "You do not have permission to do that." }
}, this);
}
protected override void LoadConfig()
{
base.LoadConfig();
AnchorMin = UpdateConfig<string>("Anchor Min", "0.83 0.21");
AnchorMax = UpdateConfig<string>("Anchor Max", "0.98 0.91");
BackgroundColor = UpdateConfig<string>("Background Color", "0.3 0.3 0.3 0.7");
HeaderColor = UpdateConfig<string>("Header Color", "0.66 1 0 1");
TitleColor = UpdateConfig<string>("Title Color", "0 0 0 1");
ContentColor = UpdateConfig<string>("Content Color", "0 0 0 1");
SaveConfig();
}
protected override void LoadDefaultConfig() => PrintWarning("Generating new configuration file...");
#endregion
#region Helpers
string LangMsg(string key, object id = null, params string[] replacements) => string.Format(lang.GetMessage(key, this, id == null ? null : id.ToString()), replacements);
DataValue ReadData<DataValue>(out DataValue data, string filename = null) => data = Core.Interface.Oxide.DataFileSystem.ReadObject<DataValue>(filename == null ? GetType().Name : $"{GetType().Name}/{filename}");
void WriteData<DataValue>(DataValue data, string filename = null) => Core.Interface.Oxide.DataFileSystem.WriteObject(filename == null ? GetType().Name : $"{GetType().Name}/{filename}", data);
ConfigValue UpdateConfig<ConfigValue>(params object[] fullPath)
{
List<string> pathL = fullPath.Select((v) => (string)v).ToList();
pathL.RemoveAt(pathL.Count - 1);
string[] path = pathL.ToArray();
if (Config.Get(path) == null)
{
PrintWarning("Generating config value: {0}", string.Join("/", path));
Config.Set(fullPath);
}
return (ConfigValue)Convert.ChangeType(Config.Get(path), typeof(ConfigValue));
}
#endregion
}
}