Version 3.0.0
Rewrite of DepositBox to restructure the data storage. - Instead of writing each deposit to storage; plugin now updates each SteamID's total balance. Introduced Discord Webhooks on Deposit - Allows each deposit to be written to a Discord Webhook to store individual deposits (optional config) Removed /checkdeposits in favor of option ServerInfo support - Adds new config to support ServerInfo; creates new Leaderboard tab that tracks player deposits (optional config) Added /createclaim - Creates a json file to be used with Claim-Player-Rewards based on the config amount of rewards for the wipe
This commit is contained in:
parent
29ed11d6c2
commit
8fc360d688
381
DepositBox.cs
381
DepositBox.cs
@ -1,83 +1,128 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization; // For CultureInfo
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Oxide.Core;
|
using Oxide.Core;
|
||||||
using Oxide.Core.Libraries.Covalence;
|
using Oxide.Core.Libraries.Covalence;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Oxide.Plugins
|
namespace Oxide.Plugins
|
||||||
{
|
{
|
||||||
[Info("DepositBox", "rustysats", "0.2.0")]
|
[Info("DepositBox", "rustysats", "0.3.0")]
|
||||||
[Description("Drop box that registers drops for admin while removing items from the game.")]
|
[Description("Drop box that registers deposits for admin while removing items from the game. Now with Discord, claim functionality, and optional ServerInfo leaderboard updates (supports Oxide and Carbon).")]
|
||||||
internal class DepositBox : RustPlugin
|
internal class DepositBox : RustPlugin
|
||||||
{
|
{
|
||||||
private static DepositBox instance;
|
private static DepositBox instance;
|
||||||
// Configuration variables
|
|
||||||
private int DepositItemID;
|
private int DepositItemID;
|
||||||
private ulong DepositBoxSkinID;
|
private ulong DepositBoxSkinID;
|
||||||
// Permission constants
|
private string DiscordWebhookUrl;
|
||||||
|
private int ClaimRewardBudget;
|
||||||
|
private bool UseServerInfo;
|
||||||
|
private int ServerInfoUpdateFreq;
|
||||||
|
|
||||||
private const string permPlace = "depositbox.place";
|
private const string permPlace = "depositbox.place";
|
||||||
private const string permCheck = "depositbox.check";
|
private const string permCreateClaim = "depositbox.createclaim";
|
||||||
private const string permAdminCheck = "depositbox.admincheck";
|
|
||||||
private DepositLog depositLog;
|
private Dictionary<string, int> depositLog = new Dictionary<string, int>();
|
||||||
private Dictionary<Item, BasePlayer> depositTrack = new Dictionary<Item, BasePlayer>(); // Track deposits
|
|
||||||
|
private readonly Dictionary<Item, BasePlayer> depositTrack = new Dictionary<Item, BasePlayer>();
|
||||||
|
|
||||||
|
private Timer serverInfoTimer;
|
||||||
|
|
||||||
#region Oxide Hooks
|
#region Oxide Hooks
|
||||||
void Init()
|
|
||||||
|
private void Init()
|
||||||
{
|
{
|
||||||
instance = this;
|
instance = this;
|
||||||
LoadConfiguration();
|
LoadConfiguration();
|
||||||
LoadDepositLog();
|
LoadDepositLog();
|
||||||
permission.RegisterPermission(permPlace, this);
|
permission.RegisterPermission(permPlace, this);
|
||||||
permission.RegisterPermission(permCheck, this);
|
permission.RegisterPermission(permCreateClaim, this);
|
||||||
permission.RegisterPermission(permAdminCheck, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadDefaultConfig()
|
protected override void LoadDefaultConfig()
|
||||||
{
|
{
|
||||||
PrintWarning("Creating a new configuration file.");
|
PrintWarning("Creating a new configuration file.");
|
||||||
Config["DepositItemID"] = -1779183908; // Default Item ID for deposits (paper)
|
Config["ClaimRewardBudget"] = "100000";
|
||||||
Config["DepositBoxSkinID"] = 1641384897; // Default skin ID for the deposit box
|
Config["DepositBoxSkinID"] = 3406403145;
|
||||||
|
Config["DepositItemID"] = -1779183908;
|
||||||
|
Config["DiscordWebhookUrl"] = "";
|
||||||
|
Config["UseServerInfo"] = false;
|
||||||
|
Config["ServerInfoUpdateFreq"] = 30;
|
||||||
SaveConfig();
|
SaveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnServerInitialized(bool initial)
|
private void OnServerInitialized(bool initial)
|
||||||
{
|
{
|
||||||
foreach (var entity in BaseNetworkable.serverEntities)
|
ReinitializeDepositBoxes();
|
||||||
|
|
||||||
|
if (UseServerInfo)
|
||||||
{
|
{
|
||||||
if (entity is StorageContainer storageContainer)
|
serverInfoTimer = timer.Every(ServerInfoUpdateFreq * 60, UpdateServerInfoLeaderboard);
|
||||||
{
|
|
||||||
OnEntitySpawned(storageContainer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unload()
|
private void Unload()
|
||||||
{
|
{
|
||||||
|
if (serverInfoTimer != null)
|
||||||
|
{
|
||||||
|
serverInfoTimer.Destroy();
|
||||||
|
serverInfoTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var entity in BaseNetworkable.serverEntities)
|
foreach (var entity in BaseNetworkable.serverEntities)
|
||||||
{
|
{
|
||||||
if (entity is StorageContainer storageContainer && storageContainer.TryGetComponent(out DepositBoxRestriction restriction))
|
if (entity is StorageContainer container)
|
||||||
{
|
{
|
||||||
restriction.Destroy();
|
var restrictions = container.GetComponents<DepositBoxRestriction>();
|
||||||
|
foreach (var r in restrictions)
|
||||||
|
{
|
||||||
|
UnityEngine.Object.Destroy(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
depositTrack.Clear();
|
||||||
|
|
||||||
instance = null;
|
instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnEntitySpawned(StorageContainer container)
|
private void ReinitializeDepositBoxes()
|
||||||
{
|
{
|
||||||
if (container == null || container.skinID != DepositBoxSkinID) return; // Early return for non-matching containers
|
foreach (var entity in BaseNetworkable.serverEntities)
|
||||||
|
{
|
||||||
|
if (entity is StorageContainer container && container.skinID == DepositBoxSkinID)
|
||||||
|
{
|
||||||
|
var restrictions = container.GetComponents<DepositBoxRestriction>();
|
||||||
|
foreach (var restriction in restrictions)
|
||||||
|
{
|
||||||
|
UnityEngine.Object.Destroy(restriction);
|
||||||
|
}
|
||||||
|
var newRestriction = container.gameObject.AddComponent<DepositBoxRestriction>();
|
||||||
|
newRestriction.container = container.inventory;
|
||||||
|
newRestriction.InitDepositBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEntitySpawned(StorageContainer container)
|
||||||
|
{
|
||||||
|
if (container == null || container.skinID != DepositBoxSkinID) return;
|
||||||
|
|
||||||
if (!container.TryGetComponent(out DepositBoxRestriction mono))
|
if (!container.TryGetComponent(out DepositBoxRestriction mono))
|
||||||
{
|
{
|
||||||
mono = container.gameObject.AddComponent<DepositBoxRestriction>();
|
mono = container.gameObject.AddComponent<DepositBoxRestriction>();
|
||||||
mono.container = container.inventory; // Assign inventory upon component addition
|
mono.container = container.inventory;
|
||||||
mono.InitDepositBox();
|
mono.InitDepositBox();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Commands
|
#region Commands
|
||||||
|
|
||||||
[ChatCommand("depositbox")]
|
[ChatCommand("depositbox")]
|
||||||
private void GiveDepositBox(BasePlayer player, string command, string[] args)
|
private void GiveDepositBox(BasePlayer player, string command, string[] args)
|
||||||
{
|
{
|
||||||
@ -90,101 +135,74 @@ namespace Oxide.Plugins
|
|||||||
player.ChatMessage(lang.GetMessage("BoxGiven", this, player.UserIDString));
|
player.ChatMessage(lang.GetMessage("BoxGiven", this, player.UserIDString));
|
||||||
}
|
}
|
||||||
|
|
||||||
[ChatCommand("checkdeposits")]
|
[ChatCommand("createclaim")]
|
||||||
private void CheckDepositsCommand(BasePlayer player, string command, string[] args)
|
private void CreateClaimCommand(BasePlayer player, string command, string[] args)
|
||||||
{
|
{
|
||||||
if (!permission.UserHasPermission(player.UserIDString, permCheck))
|
if (!permission.UserHasPermission(player.UserIDString, permCreateClaim))
|
||||||
{
|
{
|
||||||
player.ChatMessage(lang.GetMessage("NoCheckPermission", this, player.UserIDString));
|
player.ChatMessage(lang.GetMessage("NoCreateClaimPermission", this, player.UserIDString));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (depositLog == null || depositLog.Count == 0)
|
||||||
if (depositLog == null || depositLog.Deposits.Count == 0)
|
|
||||||
{
|
{
|
||||||
player.ChatMessage(lang.GetMessage("NoDepositData", this, player.UserIDString));
|
player.ChatMessage(lang.GetMessage("NoDepositData", this, player.UserIDString));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int totalDeposits = depositLog.Values.Sum();
|
||||||
// Group the deposits by SteamID and calculate the total amount deposited for each player
|
if (totalDeposits == 0)
|
||||||
var depositSummary = depositLog.Deposits
|
|
||||||
.GroupBy(entry => entry.SteamId)
|
|
||||||
.Select(group => new
|
|
||||||
{
|
|
||||||
SteamId = group.Key,
|
|
||||||
TotalAmount = group.Sum(entry => entry.AmountDeposited)
|
|
||||||
})
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
// Calculate the total amount deposited by all players
|
|
||||||
int totalDeposited = depositSummary.Sum(summary => summary.TotalAmount);
|
|
||||||
|
|
||||||
// Find the current player's total deposits
|
|
||||||
var playerSummary = depositSummary.FirstOrDefault(summary => summary.SteamId == player.UserIDString);
|
|
||||||
|
|
||||||
if (playerSummary != null)
|
|
||||||
{
|
{
|
||||||
// Calculate the percentage of total deposits for the current player
|
player.ChatMessage(lang.GetMessage("ZeroDeposits", this, player.UserIDString));
|
||||||
double percentageOfTotal = ((double)playerSummary.TotalAmount / totalDeposited) * 100;
|
return;
|
||||||
player.ChatMessage(lang.GetMessage("PlayerDepositSummary", this, player.UserIDString)
|
|
||||||
.Replace("{amount}", playerSummary.TotalAmount.ToString(CultureInfo.InvariantCulture))
|
|
||||||
.Replace("{percentage}", percentageOfTotal.ToString("F2", CultureInfo.InvariantCulture)));
|
|
||||||
}
|
}
|
||||||
else
|
var claimData = new Dictionary<string, int>();
|
||||||
|
foreach (var entry in depositLog)
|
||||||
{
|
{
|
||||||
player.ChatMessage(lang.GetMessage("NoPlayerDeposits", this, player.UserIDString));
|
double percentage = (double)entry.Value / totalDeposits;
|
||||||
}
|
int reward = (int)Math.Floor(percentage * ClaimRewardBudget);
|
||||||
|
claimData[entry.Key] = reward;
|
||||||
// Admin view if player has both permissions
|
|
||||||
if (permission.UserHasPermission(player.UserIDString, permAdminCheck))
|
|
||||||
{
|
|
||||||
player.ChatMessage(lang.GetMessage("DepositTotals", this, player.UserIDString));
|
|
||||||
foreach (var summary in depositSummary)
|
|
||||||
{
|
|
||||||
double percentage = ((double)summary.TotalAmount / totalDeposited) * 100;
|
|
||||||
player.ChatMessage(lang.GetMessage("DepositEntrySummary", this, player.UserIDString)
|
|
||||||
.Replace("{steamid}", summary.SteamId)
|
|
||||||
.Replace("{amount}", summary.TotalAmount.ToString(CultureInfo.InvariantCulture))
|
|
||||||
.Replace("{percentage}", percentage.ToString("F2", CultureInfo.InvariantCulture)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Interface.Oxide.DataFileSystem.WriteObject("DepositBox_Claim", claimData);
|
||||||
|
player.ChatMessage(lang.GetMessage("ClaimFileUpdated", this, player.UserIDString));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region DepositBoxRestriction Class
|
#region DepositBoxRestriction Class
|
||||||
|
|
||||||
public class DepositBoxRestriction : FacepunchBehaviour
|
public class DepositBoxRestriction : FacepunchBehaviour
|
||||||
{
|
{
|
||||||
public ItemContainer container;
|
public ItemContainer container;
|
||||||
|
|
||||||
public void InitDepositBox()
|
public void InitDepositBox()
|
||||||
{
|
{
|
||||||
container.canAcceptItem += CanAcceptItem;
|
container.canAcceptItem += CanAcceptItem;
|
||||||
container.onItemAddedRemoved += OnItemAddedRemoved;
|
container.onItemAddedRemoved += OnItemAddedRemoved;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanAcceptItem(Item item, int targetPos)
|
private bool CanAcceptItem(Item item, int targetPos)
|
||||||
{
|
{
|
||||||
// Only allow the configured deposit item to be deposited
|
|
||||||
if (item == null || item.info == null || item.info.itemid != DepositBox.instance.DepositItemID)
|
if (item == null || item.info == null || item.info.itemid != DepositBox.instance.DepositItemID)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (item.GetOwnerPlayer() is BasePlayer player)
|
if (item.GetOwnerPlayer() is BasePlayer player)
|
||||||
{
|
{
|
||||||
DepositBox.instance.TrackDeposit(item, player); // Track the item with player reference
|
DepositBox.instance.TrackDeposit(item, player);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnItemAddedRemoved(Item item, bool added)
|
private void OnItemAddedRemoved(Item item, bool added)
|
||||||
{
|
{
|
||||||
// Early exit if item isn't added or isn't the correct deposit item
|
|
||||||
if (!added || item.info.itemid != DepositBox.instance.DepositItemID) return;
|
if (!added || item.info.itemid != DepositBox.instance.DepositItemID) return;
|
||||||
// Try to get the player who deposited the item
|
|
||||||
if (DepositBox.instance.depositTrack.TryGetValue(item, out BasePlayer player))
|
if (DepositBox.instance.depositTrack.TryGetValue(item, out BasePlayer player))
|
||||||
{
|
{
|
||||||
DepositBox.instance.LogDeposit(player, item.amount); // Log the deposit first
|
DepositBox.instance.LogDeposit(player, item.amount);
|
||||||
DepositBox.instance.depositTrack.Remove(item); // Remove from tracking
|
DepositBox.instance.depositTrack.Remove(item);
|
||||||
// Now remove the deposited item from the box, after logging is complete
|
|
||||||
item.Remove();
|
item.Remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
container.canAcceptItem -= CanAcceptItem;
|
container.canAcceptItem -= CanAcceptItem;
|
||||||
@ -192,82 +210,191 @@ namespace Oxide.Plugins
|
|||||||
Destroy(this);
|
Destroy(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Logging
|
#region Logging and Discord Integration
|
||||||
private class DepositLog
|
|
||||||
{
|
|
||||||
[JsonProperty("deposits")]
|
|
||||||
public List<DepositEntry> Deposits { get; set; } = new List<DepositEntry>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DepositEntry
|
private void LogDeposit(BasePlayer player, int depositAmount)
|
||||||
{
|
{
|
||||||
[JsonProperty("steamid")]
|
string steamId = player.UserIDString;
|
||||||
public string SteamId { get; set; }
|
if (!depositLog.ContainsKey(steamId))
|
||||||
[JsonProperty("timestamp")]
|
|
||||||
public string Timestamp { get; set; }
|
|
||||||
[JsonProperty("amount_deposited")]
|
|
||||||
public int AmountDeposited { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LogDeposit(BasePlayer player, int amount)
|
|
||||||
{
|
|
||||||
// Record this deposit
|
|
||||||
depositLog.Deposits.Add(new DepositEntry
|
|
||||||
{
|
{
|
||||||
SteamId = player.UserIDString,
|
depositLog[steamId] = 0;
|
||||||
Timestamp = DateTime.UtcNow.ToString("o"),
|
}
|
||||||
AmountDeposited = amount
|
depositLog[steamId] += depositAmount;
|
||||||
});
|
SaveDepositLog();
|
||||||
SaveDepositLog(); // Save the log after recording the deposit
|
int playerTotalDeposits = depositLog[steamId];
|
||||||
|
int totalDepositedByAllPlayers = depositLog.Values.Sum();
|
||||||
// Calculate the player's total deposits
|
double playerPercentageOfTotal = totalDepositedByAllPlayers > 0 ? (double)playerTotalDeposits / totalDepositedByAllPlayers * 100.0 : 0.0;
|
||||||
int playerTotalDeposits = depositLog.Deposits
|
player.ChatMessage(lang.GetMessage("DepositRecorded", this, steamId)
|
||||||
.Where(entry => entry.SteamId == player.UserIDString)
|
.Replace("{amount}", depositAmount.ToString(CultureInfo.InvariantCulture))
|
||||||
.Sum(entry => entry.AmountDeposited);
|
|
||||||
|
|
||||||
// Calculate the total deposits of all players
|
|
||||||
int totalDepositedByAllPlayers = depositLog.Deposits.Sum(entry => entry.AmountDeposited);
|
|
||||||
|
|
||||||
// Calculate the player's percentage of all deposits
|
|
||||||
double playerPercentageOfTotal = ((double)playerTotalDeposits / totalDepositedByAllPlayers) * 100;
|
|
||||||
|
|
||||||
// Send the updated deposit message to the player
|
|
||||||
player.ChatMessage(lang.GetMessage("DepositRecorded", this, player.UserIDString)
|
|
||||||
.Replace("{amount}", amount.ToString(CultureInfo.InvariantCulture))
|
|
||||||
.Replace("{total_amount}", playerTotalDeposits.ToString(CultureInfo.InvariantCulture))
|
.Replace("{total_amount}", playerTotalDeposits.ToString(CultureInfo.InvariantCulture))
|
||||||
.Replace("{percentage}", playerPercentageOfTotal.ToString("F2", CultureInfo.InvariantCulture)));
|
.Replace("{percentage}", playerPercentageOfTotal.ToString("F2", CultureInfo.InvariantCulture)));
|
||||||
|
SendDiscordNotification(player, depositAmount, playerTotalDeposits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TrackDeposit(Item item, BasePlayer player)
|
public void TrackDeposit(Item item, BasePlayer player)
|
||||||
{
|
{
|
||||||
if (item != null && player != null)
|
if (item != null && player != null)
|
||||||
{
|
{
|
||||||
depositTrack[item] = player; // Track the item with its owner
|
depositTrack[item] = player;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadDepositLog()
|
private void LoadDepositLog()
|
||||||
{
|
{
|
||||||
depositLog = Interface.Oxide.DataFileSystem.ReadObject<DepositLog>("DepositBoxLog") ?? new DepositLog();
|
depositLog = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, int>>("DepositBoxLog")
|
||||||
|
?? new Dictionary<string, int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveDepositLog()
|
private void SaveDepositLog()
|
||||||
{
|
{
|
||||||
Interface.Oxide.DataFileSystem.WriteObject("DepositBoxLog", depositLog);
|
Interface.Oxide.DataFileSystem.WriteObject("DepositBoxLog", depositLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SendDiscordNotification(BasePlayer player, int depositAmount, int newTotal)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(DiscordWebhookUrl))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string playerName = !string.IsNullOrEmpty(player.displayName) ? player.displayName : player.UserIDString;
|
||||||
|
string message = $"{playerName} ({player.UserIDString}) deposited {depositAmount} items. Their total is now {newTotal}.";
|
||||||
|
if (string.IsNullOrWhiteSpace(message))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var payload = new Dictionary<string, string> { ["content"] = message };
|
||||||
|
string postData = JsonConvert.SerializeObject(payload);
|
||||||
|
var headers = new Dictionary<string, string> { ["Content-Type"] = "application/json" };
|
||||||
|
webrequest.EnqueuePost(DiscordWebhookUrl, postData, (code, response) =>
|
||||||
|
{
|
||||||
|
if (code != 200 && code != 204)
|
||||||
|
{
|
||||||
|
PrintWarning($"Discord notification failed: {code} {response}");
|
||||||
|
}
|
||||||
|
}, this, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ServerInfo Leaderboard Update
|
||||||
|
|
||||||
|
private void UpdateServerInfoLeaderboard()
|
||||||
|
{
|
||||||
|
string serverInfoPath = GetServerInfoPath();
|
||||||
|
if (string.IsNullOrEmpty(serverInfoPath))
|
||||||
|
{
|
||||||
|
Puts("ServerInfo.json not found in oxide/config or carbon/configs, skipping update.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string fileContent = File.ReadAllText(serverInfoPath);
|
||||||
|
var serverInfo = JsonConvert.DeserializeObject<Dictionary<string, object>>(fileContent);
|
||||||
|
if (serverInfo == null || !serverInfo.ContainsKey("settings"))
|
||||||
|
{
|
||||||
|
Puts("ServerInfo.json format unexpected, skipping update.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var settings = serverInfo["settings"] as Newtonsoft.Json.Linq.JObject;
|
||||||
|
if (settings == null) return;
|
||||||
|
var tabs = settings["Tabs"] as Newtonsoft.Json.Linq.JArray;
|
||||||
|
if (tabs == null)
|
||||||
|
{
|
||||||
|
tabs = new Newtonsoft.Json.Linq.JArray();
|
||||||
|
settings["Tabs"] = tabs;
|
||||||
|
}
|
||||||
|
var leaderboardLines = new List<string> { $"Leaderboard is updated every {ServerInfoUpdateFreq} minutes.", "" };
|
||||||
|
var sorted = depositLog.OrderByDescending(x => x.Value).Take(100).ToList();
|
||||||
|
int rank = 1;
|
||||||
|
foreach (var kv in sorted)
|
||||||
|
{
|
||||||
|
string steamId = kv.Key;
|
||||||
|
int totalDeposited = kv.Value;
|
||||||
|
string name = covalence.Players.FindPlayerById(steamId)?.Name ?? steamId;
|
||||||
|
leaderboardLines.Add($"{rank}. {name} - {totalDeposited} items");
|
||||||
|
rank++;
|
||||||
|
}
|
||||||
|
int linesPerPage = 20;
|
||||||
|
var pages = new List<object>();
|
||||||
|
for (int i = 0; i < leaderboardLines.Count; i += linesPerPage)
|
||||||
|
{
|
||||||
|
var chunk = leaderboardLines.Skip(i).Take(linesPerPage).ToList();
|
||||||
|
pages.Add(new { TextLines = chunk, ImageSettings = new object[] { } });
|
||||||
|
}
|
||||||
|
var leaderboardTab = new
|
||||||
|
{
|
||||||
|
ButtonText = "Leaderboard",
|
||||||
|
HeaderText = "Top Depositors",
|
||||||
|
Pages = pages.ToArray(),
|
||||||
|
TabButtonAnchor = 4,
|
||||||
|
TabButtonFontSize = 16,
|
||||||
|
HeaderAnchor = 0,
|
||||||
|
HeaderFontSize = 32,
|
||||||
|
TextFontSize = 16,
|
||||||
|
TextAnchor = 3,
|
||||||
|
OxideGroup = ""
|
||||||
|
};
|
||||||
|
for (int i = tabs.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (tabs[i]["ButtonText"]?.ToString() == "Leaderboard")
|
||||||
|
{
|
||||||
|
tabs.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tabs.Add(Newtonsoft.Json.Linq.JObject.FromObject(leaderboardTab));
|
||||||
|
File.WriteAllText(serverInfoPath, JsonConvert.SerializeObject(serverInfo, Formatting.Indented));
|
||||||
|
Puts("ServerInfo.json updated with leaderboard data.");
|
||||||
|
string reloadCmd = GetServerInfoReloadCommand(serverInfoPath);
|
||||||
|
if (!string.IsNullOrEmpty(reloadCmd))
|
||||||
|
{
|
||||||
|
ConsoleSystem.Run(ConsoleSystem.Option.Server, reloadCmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
PrintWarning($"Error updating ServerInfo: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetServerInfoPath()
|
||||||
|
{
|
||||||
|
if (File.Exists("oxide/config/ServerInfo.json"))
|
||||||
|
return "oxide/config/ServerInfo.json";
|
||||||
|
if (File.Exists("carbon/configs/ServerInfo.json"))
|
||||||
|
return "carbon/configs/ServerInfo.json";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetServerInfoReloadCommand(string serverInfoPath)
|
||||||
|
{
|
||||||
|
if (serverInfoPath.Contains("oxide"))
|
||||||
|
return "oxide.reload ServerInfo";
|
||||||
|
if (serverInfoPath.Contains("carbon"))
|
||||||
|
return "carbon.reload ServerInfo";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Configuration
|
#region Configuration
|
||||||
|
|
||||||
private void LoadConfiguration()
|
private void LoadConfiguration()
|
||||||
{
|
{
|
||||||
DepositItemID = Convert.ToInt32(Config["DepositItemID"], CultureInfo.InvariantCulture); // Specified CultureInfo
|
DepositItemID = Convert.ToInt32(Config["DepositItemID"], CultureInfo.InvariantCulture);
|
||||||
DepositBoxSkinID = Convert.ToUInt64(Config["DepositBoxSkinID"], CultureInfo.InvariantCulture); // Specified CultureInfo
|
DepositBoxSkinID = Convert.ToUInt64(Config["DepositBoxSkinID"], CultureInfo.InvariantCulture);
|
||||||
|
DiscordWebhookUrl = Convert.ToString(Config["DiscordWebhookUrl"]);
|
||||||
|
ClaimRewardBudget = Convert.ToInt32(Config["ClaimRewardBudget"], CultureInfo.InvariantCulture);
|
||||||
|
UseServerInfo = Convert.ToBoolean(Config["UseServerInfo"]);
|
||||||
|
ServerInfoUpdateFreq = Convert.ToInt32(Config["ServerInfoUpdateFreq"], CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Localization
|
#region Localization
|
||||||
|
|
||||||
protected override void LoadDefaultMessages()
|
protected override void LoadDefaultMessages()
|
||||||
{
|
{
|
||||||
lang.RegisterMessages(new Dictionary<string, string>
|
lang.RegisterMessages(new Dictionary<string, string>
|
||||||
@ -275,15 +402,13 @@ namespace Oxide.Plugins
|
|||||||
["NoPermission"] = "You do not have permission to place this box.",
|
["NoPermission"] = "You do not have permission to place this box.",
|
||||||
["BoxGiven"] = "You have received a Deposit Box.",
|
["BoxGiven"] = "You have received a Deposit Box.",
|
||||||
["DepositRecorded"] = "Your deposit of {amount} has been recorded. You have deposited a total of {total_amount} items, which is {percentage}% of all deposits.",
|
["DepositRecorded"] = "Your deposit of {amount} has been recorded. You have deposited a total of {total_amount} items, which is {percentage}% of all deposits.",
|
||||||
["PlacedNoPerm"] = "You have placed a deposit box but lack permission to place it.",
|
["NoCreateClaimPermission"] = "You do not have permission to create a claim file.",
|
||||||
["NoCheckPermission"] = "You do not have permission to check deposits.",
|
["NoDepositData"] = "No deposit data found to create a claim.",
|
||||||
["NoDepositData"] = "No deposit data found.",
|
["ZeroDeposits"] = "Total deposits are zero, cannot create claim.",
|
||||||
["PlayerDepositSummary"] = "You have deposited a total of {amount} items, which is {percentage}% of all deposits.",
|
["ClaimFileUpdated"] = "Claim file has been created/updated."
|
||||||
["NoPlayerDeposits"] = "You have not made any deposits.",
|
|
||||||
["DepositTotals"] = "Deposit Totals:",
|
|
||||||
["DepositEntrySummary"] = "SteamID: {steamid}, Total Deposited: {amount}, {percentage}% of total."
|
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user