Initial Deployment
This commit is contained in:
commit
29ed11d6c2
289
DepositBox.cs
Normal file
289
DepositBox.cs
Normal file
@ -0,0 +1,289 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization; // For CultureInfo
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Oxide.Core;
|
||||
using Oxide.Core.Libraries.Covalence;
|
||||
|
||||
namespace Oxide.Plugins
|
||||
{
|
||||
[Info("DepositBox", "rustysats", "0.2.0")]
|
||||
[Description("Drop box that registers drops for admin while removing items from the game.")]
|
||||
internal class DepositBox : RustPlugin
|
||||
{
|
||||
private static DepositBox instance;
|
||||
// Configuration variables
|
||||
private int DepositItemID;
|
||||
private ulong DepositBoxSkinID;
|
||||
// Permission constants
|
||||
private const string permPlace = "depositbox.place";
|
||||
private const string permCheck = "depositbox.check";
|
||||
private const string permAdminCheck = "depositbox.admincheck";
|
||||
private DepositLog depositLog;
|
||||
private Dictionary<Item, BasePlayer> depositTrack = new Dictionary<Item, BasePlayer>(); // Track deposits
|
||||
|
||||
#region Oxide Hooks
|
||||
void Init()
|
||||
{
|
||||
instance = this;
|
||||
LoadConfiguration();
|
||||
LoadDepositLog();
|
||||
permission.RegisterPermission(permPlace, this);
|
||||
permission.RegisterPermission(permCheck, this);
|
||||
permission.RegisterPermission(permAdminCheck, this);
|
||||
}
|
||||
|
||||
protected override void LoadDefaultConfig()
|
||||
{
|
||||
PrintWarning("Creating a new configuration file.");
|
||||
Config["DepositItemID"] = -1779183908; // Default Item ID for deposits (paper)
|
||||
Config["DepositBoxSkinID"] = 1641384897; // Default skin ID for the deposit box
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
void OnServerInitialized(bool initial)
|
||||
{
|
||||
foreach (var entity in BaseNetworkable.serverEntities)
|
||||
{
|
||||
if (entity is StorageContainer storageContainer)
|
||||
{
|
||||
OnEntitySpawned(storageContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Unload()
|
||||
{
|
||||
foreach (var entity in BaseNetworkable.serverEntities)
|
||||
{
|
||||
if (entity is StorageContainer storageContainer && storageContainer.TryGetComponent(out DepositBoxRestriction restriction))
|
||||
{
|
||||
restriction.Destroy();
|
||||
}
|
||||
}
|
||||
instance = null;
|
||||
}
|
||||
|
||||
void OnEntitySpawned(StorageContainer container)
|
||||
{
|
||||
if (container == null || container.skinID != DepositBoxSkinID) return; // Early return for non-matching containers
|
||||
if (!container.TryGetComponent(out DepositBoxRestriction mono))
|
||||
{
|
||||
mono = container.gameObject.AddComponent<DepositBoxRestriction>();
|
||||
mono.container = container.inventory; // Assign inventory upon component addition
|
||||
mono.InitDepositBox();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Commands
|
||||
[ChatCommand("depositbox")]
|
||||
private void GiveDepositBox(BasePlayer player, string command, string[] args)
|
||||
{
|
||||
if (!permission.UserHasPermission(player.UserIDString, permPlace))
|
||||
{
|
||||
player.ChatMessage(lang.GetMessage("NoPermission", this, player.UserIDString));
|
||||
return;
|
||||
}
|
||||
player.inventory.containerMain.GiveItem(ItemManager.CreateByItemID(833533164, 1, DepositBoxSkinID));
|
||||
player.ChatMessage(lang.GetMessage("BoxGiven", this, player.UserIDString));
|
||||
}
|
||||
|
||||
[ChatCommand("checkdeposits")]
|
||||
private void CheckDepositsCommand(BasePlayer player, string command, string[] args)
|
||||
{
|
||||
if (!permission.UserHasPermission(player.UserIDString, permCheck))
|
||||
{
|
||||
player.ChatMessage(lang.GetMessage("NoCheckPermission", this, player.UserIDString));
|
||||
return;
|
||||
}
|
||||
|
||||
if (depositLog == null || depositLog.Deposits.Count == 0)
|
||||
{
|
||||
player.ChatMessage(lang.GetMessage("NoDepositData", this, player.UserIDString));
|
||||
return;
|
||||
}
|
||||
|
||||
// Group the deposits by SteamID and calculate the total amount deposited for each player
|
||||
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
|
||||
double percentageOfTotal = ((double)playerSummary.TotalAmount / totalDeposited) * 100;
|
||||
player.ChatMessage(lang.GetMessage("PlayerDepositSummary", this, player.UserIDString)
|
||||
.Replace("{amount}", playerSummary.TotalAmount.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{percentage}", percentageOfTotal.ToString("F2", CultureInfo.InvariantCulture)));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.ChatMessage(lang.GetMessage("NoPlayerDeposits", this, player.UserIDString));
|
||||
}
|
||||
|
||||
// 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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DepositBoxRestriction Class
|
||||
public class DepositBoxRestriction : FacepunchBehaviour
|
||||
{
|
||||
public ItemContainer container;
|
||||
public void InitDepositBox()
|
||||
{
|
||||
container.canAcceptItem += CanAcceptItem;
|
||||
container.onItemAddedRemoved += OnItemAddedRemoved;
|
||||
}
|
||||
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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (item.GetOwnerPlayer() is BasePlayer player)
|
||||
{
|
||||
DepositBox.instance.TrackDeposit(item, player); // Track the item with player reference
|
||||
}
|
||||
return true;
|
||||
}
|
||||
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;
|
||||
// Try to get the player who deposited the item
|
||||
if (DepositBox.instance.depositTrack.TryGetValue(item, out BasePlayer player))
|
||||
{
|
||||
DepositBox.instance.LogDeposit(player, item.amount); // Log the deposit first
|
||||
DepositBox.instance.depositTrack.Remove(item); // Remove from tracking
|
||||
// Now remove the deposited item from the box, after logging is complete
|
||||
item.Remove();
|
||||
}
|
||||
}
|
||||
public void Destroy()
|
||||
{
|
||||
container.canAcceptItem -= CanAcceptItem;
|
||||
container.onItemAddedRemoved -= OnItemAddedRemoved;
|
||||
Destroy(this);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Logging
|
||||
private class DepositLog
|
||||
{
|
||||
[JsonProperty("deposits")]
|
||||
public List<DepositEntry> Deposits { get; set; } = new List<DepositEntry>();
|
||||
}
|
||||
|
||||
private class DepositEntry
|
||||
{
|
||||
[JsonProperty("steamid")]
|
||||
public string SteamId { get; set; }
|
||||
[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,
|
||||
Timestamp = DateTime.UtcNow.ToString("o"),
|
||||
AmountDeposited = amount
|
||||
});
|
||||
SaveDepositLog(); // Save the log after recording the deposit
|
||||
|
||||
// Calculate the player's total deposits
|
||||
int playerTotalDeposits = depositLog.Deposits
|
||||
.Where(entry => entry.SteamId == player.UserIDString)
|
||||
.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("{percentage}", playerPercentageOfTotal.ToString("F2", CultureInfo.InvariantCulture)));
|
||||
}
|
||||
|
||||
public void TrackDeposit(Item item, BasePlayer player)
|
||||
{
|
||||
if (item != null && player != null)
|
||||
{
|
||||
depositTrack[item] = player; // Track the item with its owner
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadDepositLog()
|
||||
{
|
||||
depositLog = Interface.Oxide.DataFileSystem.ReadObject<DepositLog>("DepositBoxLog") ?? new DepositLog();
|
||||
}
|
||||
|
||||
private void SaveDepositLog()
|
||||
{
|
||||
Interface.Oxide.DataFileSystem.WriteObject("DepositBoxLog", depositLog);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Configuration
|
||||
private void LoadConfiguration()
|
||||
{
|
||||
DepositItemID = Convert.ToInt32(Config["DepositItemID"], CultureInfo.InvariantCulture); // Specified CultureInfo
|
||||
DepositBoxSkinID = Convert.ToUInt64(Config["DepositBoxSkinID"], CultureInfo.InvariantCulture); // Specified CultureInfo
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Localization
|
||||
protected override void LoadDefaultMessages()
|
||||
{
|
||||
lang.RegisterMessages(new Dictionary<string, string>
|
||||
{
|
||||
["NoPermission"] = "You do not have permission to place this 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.",
|
||||
["PlacedNoPerm"] = "You have placed a deposit box but lack permission to place it.",
|
||||
["NoCheckPermission"] = "You do not have permission to check deposits.",
|
||||
["NoDepositData"] = "No deposit data found.",
|
||||
["PlayerDepositSummary"] = "You have deposited a total of {amount} items, which is {percentage}% of all deposits.",
|
||||
["NoPlayerDeposits"] = "You have not made any deposits.",
|
||||
["DepositTotals"] = "Deposit Totals:",
|
||||
["DepositEntrySummary"] = "SteamID: {steamid}, Total Deposited: {amount}, {percentage}% of total."
|
||||
}, this);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Patrick Ulrich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
88
README.md
Normal file
88
README.md
Normal file
@ -0,0 +1,88 @@
|
||||
## Overview
|
||||
|
||||
The **DepositBox** plugin allows players to deposit specific items (e.g., paper) into a dropbox, logging the deposits and removing the items from the game. This can be used to create events or competitions, such as a system where players compete to turn in the most items (similar to the Twitch Rust event where players compete for dog tags).
|
||||
|
||||
### Features
|
||||
- Only designated items can be deposited.
|
||||
- Logs all deposits for tracking.
|
||||
- Configurable deposit box skin and item type.
|
||||
- Prevents non-whitelisted items from being deposited.
|
||||
- Can be used to run events or competitions where players turn in items for rewards.
|
||||
|
||||
Once installed players with permission will be able to create a deposit box using /depositbox as a chat command. They can then place this box down allowing players to make deposits into it. All deposits are logged to the data folder.
|
||||
|
||||
## Installation
|
||||
|
||||
1. Upload the `DepositBox.cs` file to your Rust server under the `/oxide/plugins/` directory.
|
||||
2. Restart or reload the server for the plugin to initialize:
|
||||
```bash
|
||||
oxide.reload DepositBox
|
||||
```
|
||||
3. Ensure you grant users permission to use the deposit box:
|
||||
```bash
|
||||
oxide.grant user <username> depositbox.place
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Upon the first run, a default configuration file will be generated at `/oxide/config/DepositBox.json`. The configuration contains the following settings:
|
||||
|
||||
```json
|
||||
{
|
||||
"DepositItemID": -1779183908, // The item ID for your deposit unit (default: -1779183908)
|
||||
"DepositBoxSkinID": 1641384897 // The skin ID for the deposit box
|
||||
}
|
||||
```
|
||||
|
||||
You can edit these values directly in the configuration file if needed.
|
||||
|
||||
- **DepositItemID**: The Rust item ID of the item that can be deposited (default: paper with ID `-1779183908`).
|
||||
- **DepositBoxSkinID**: The Rust skin ID applied to the deposit box (default: `1641384897`).
|
||||
|
||||
### Customizing the Configuration:
|
||||
|
||||
1. Navigate to `/oxide/config/DepositBox.json`.
|
||||
2. Modify the values as needed.
|
||||
3. Save the file and reload the plugin:
|
||||
```bash
|
||||
oxide.reload DepositBox
|
||||
```
|
||||
|
||||
### Important Note on Skin IDs:
|
||||
- The DepositBoxSkinID is used to differentiate between regular storage containers and deposit boxes. Admins should ensure that they select a skin ID that is not actively available in the skin box to avoid confusion or accidental misuse by players. Using a skin that is easily accessible to players could result in unintended behavior where non-deposit boxes are treated as deposit boxes.
|
||||
|
||||
## Permissions
|
||||
|
||||
- `depositbox.place`: Grants a player permission to place a deposit box.
|
||||
|
||||
To assign this permission, use the following command:
|
||||
```bash
|
||||
oxide.grant user <username> depositbox.place
|
||||
```
|
||||
|
||||
## Functionality
|
||||
|
||||
### Hooks
|
||||
|
||||
- **Init()**: Initializes the plugin, loads the configuration, and registers permissions.
|
||||
- **OnServerInitialized()**: Scans the server for `StorageContainer` entities and applies the plugin's functionality to deposit boxes.
|
||||
- **Unload()**: Cleans up and removes deposit box restrictions when the plugin is unloaded.
|
||||
- **OnEntitySpawned()**: When a `StorageContainer` is spawned, the plugin checks if it’s a deposit box and ensures it follows the required rules.
|
||||
|
||||
### Item Handling
|
||||
|
||||
- The plugin restricts item deposits to a hardcoded whitelist (currently, only paper can be deposited).
|
||||
- If an item is not on the whitelist, it will remain in the player's inventory, and only paper will be removed and logged.
|
||||
- **Logging**: Every time a player deposits paper into the box, the action is logged for administrative tracking.
|
||||
|
||||
### Custom Logging
|
||||
|
||||
- All paper deposits are logged in the `oxide/data/DepositBoxLog.json` file, structured as follows:
|
||||
```json
|
||||
{
|
||||
"SteamID": "player_steam_id",
|
||||
"amount_deposited": "amount_deposited",
|
||||
"Timestamp": "2024-09-22T12:00:00"
|
||||
}
|
||||
```
|
||||
This allows server administrators to keep track of deposits and monitor player activity.
|
Loading…
x
Reference in New Issue
Block a user