Initial Deployment

This commit is contained in:
Patrick Ulrich 2025-01-29 10:40:56 -05:00
commit 66e385b6f5
3 changed files with 433 additions and 0 deletions

363
ClaimPlayerRewards.cs Normal file
View File

@ -0,0 +1,363 @@
using Oxide.Core.Plugins;
using Oxide.Core;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using System;
using System.Globalization;
namespace Oxide.Plugins
{
[Info("Claim Player Rewards", "rustysats", "0.1.0")]
[Description("Allows players to claim rewards based on a JSON configuration file and logs claims.")]
public class ClaimPlayerRewards : RustPlugin
{
// Configurable parameters
private ConfigData config;
// Path to your JSON configuration files within a subfolder
private const string DataFolderPath = "oxide/data/ClaimPlayerRewards/";
private const string ConfigFilePath = DataFolderPath + "ClaimPlayerRewards.json";
private const string ClaimedRewardsFilePath = DataFolderPath + "ClaimedRewards.json";
// Permission name for using the claim command
private const string PermissionClaim = "claimplayerrewards.use";
// Data managers
private RewardDataManager rewardDataManager;
private ClaimDataManager claimDataManager;
// Configurable data structure
private class ConfigData
{
public string RewardItem { get; set; } = "blood"; // Default reward item
public ulong RewardSkinID { get; set; } = 0; // Default skin ID (0 means no skin)
}
void Init()
{
// Register the permission
permission.RegisterPermission(PermissionClaim, this);
// Ensure the data directory exists
if (!Directory.Exists(DataFolderPath))
{
Directory.CreateDirectory(DataFolderPath);
}
// Load the configuration
LoadConfig();
// Initialize data managers
rewardDataManager = new RewardDataManager(ConfigFilePath, this);
claimDataManager = new ClaimDataManager(ClaimedRewardsFilePath, this);
// Load reward data from JSON file when the plugin initializes
rewardDataManager.LoadRewardData();
// Load claims data from JSON file when the plugin initializes
claimDataManager.LoadClaimedRewards();
}
// Load plugin configuration and ensure defaults are saved if config is empty or missing
protected override void LoadDefaultConfig()
{
PrintWarning("Generating new configuration file...");
config = new ConfigData();
SaveConfig();
}
private new void LoadConfig()
{
try
{
config = Config.ReadObject<ConfigData>();
if (config == null)
{
PrintWarning("Config file was empty, creating new defaults...");
LoadDefaultConfig();
}
}
catch (IOException e)
{
PrintWarning($"IO error loading config: {e.Message}, generating default config...");
LoadDefaultConfig();
}
catch (JsonException e)
{
PrintWarning($"JSON error loading config: {e.Message}, generating default config...");
LoadDefaultConfig();
}
catch (Exception e)
{
PrintWarning($"Unexpected error loading config: {e.Message}, generating default config...");
throw; // Rethrow the exception
}
}
private void SaveConfig()
{
Config.WriteObject(config, true); // Save with indentation for readability
PrintWarning("Configuration saved successfully.");
}
[ChatCommand("claim")]
private void ClaimCommand(BasePlayer player, string command, string[] args)
{
// Check if the player has permission
if (!permission.UserHasPermission(player.UserIDString, PermissionClaim))
{
SendReply(player, Lang("NoPermission", player.UserIDString));
return;
}
string playerSteamId = player.UserIDString;
if (rewardDataManager.HasReward(playerSteamId))
{
int amountToGive = rewardDataManager.GetRewardAmount(playerSteamId);
// Use the configured reward item and skin ID
GiveItem(player, config.RewardItem, amountToGive, config.RewardSkinID);
// Log the claim
claimDataManager.LogClaim(playerSteamId, amountToGive);
// Remove the player's entry from the rewardData after claiming
rewardDataManager.RemoveReward(playerSteamId);
SendReply(player, Lang("ClaimSuccess", player.UserIDString, amountToGive, config.RewardItem));
}
else
{
SendReply(player, Lang("NothingToClaim", player.UserIDString));
}
}
private void GiveItem(BasePlayer player, string itemShortName, int amount, ulong skinId)
{
// This function gives the specified item to the player with the defined skin ID
Item item = ItemManager.CreateByName(itemShortName, amount, skinId);
if (item != null)
{
player.GiveItem(item);
}
}
// Localization with Lang API
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["ClaimSuccess"] = "You have claimed {0} {1}.",
["NothingToClaim"] = "Nothing to claim.",
["NoPermission"] = "You do not have permission to use this command."
}, this);
}
private string Lang(string key, string userId = null, params object[] args)
{
return string.Format(CultureInfo.InvariantCulture, lang.GetMessage(key, this, userId), args);
}
// Nested class to handle reward data
private class RewardDataManager
{
private string filePath;
private Dictionary<string, int> rewardData;
private ClaimPlayerRewards plugin;
public RewardDataManager(string filePath, ClaimPlayerRewards plugin)
{
this.filePath = filePath;
this.plugin = plugin;
rewardData = new Dictionary<string, int>();
}
public void LoadRewardData()
{
if (File.Exists(filePath))
{
try
{
string json = File.ReadAllText(filePath);
rewardData = JsonConvert.DeserializeObject<Dictionary<string, int>>(json) ?? new Dictionary<string, int>();
plugin.Puts("Reward data loaded successfully.");
}
catch (IOException ex)
{
plugin.Puts($"IO error loading reward data: {ex.Message}");
rewardData = new Dictionary<string, int>();
}
catch (JsonException ex)
{
plugin.Puts($"JSON error loading reward data: {ex.Message}");
rewardData = new Dictionary<string, int>();
}
catch (Exception ex)
{
plugin.Puts($"Unexpected error loading reward data: {ex.Message}");
throw;
}
}
else
{
plugin.Puts("No reward data found, creating a new file.");
rewardData = new Dictionary<string, int>();
SaveRewardData();
}
}
public void SaveRewardData()
{
try
{
// Save the reward data back to the JSON file
string json = JsonConvert.SerializeObject(rewardData, Formatting.Indented);
File.WriteAllText(filePath, json);
plugin.Puts("Reward data saved successfully.");
}
catch (IOException ex)
{
plugin.Puts($"IO error saving reward data: {ex.Message}");
throw;
}
catch (JsonException ex)
{
plugin.Puts($"JSON error saving reward data: {ex.Message}");
throw;
}
catch (Exception ex)
{
plugin.Puts($"Unexpected error saving reward data: {ex.Message}");
throw;
}
}
public bool HasReward(string steamId)
{
return rewardData.ContainsKey(steamId);
}
public int GetRewardAmount(string steamId)
{
return rewardData.ContainsKey(steamId) ? rewardData[steamId] : 0;
}
public void RemoveReward(string steamId)
{
if (rewardData.Remove(steamId))
{
SaveRewardData();
}
}
}
// Nested class to handle claimed rewards data
private class ClaimDataManager
{
private string filePath;
private List<ClaimRecord> claims;
private ClaimPlayerRewards plugin;
public ClaimDataManager(string filePath, ClaimPlayerRewards plugin)
{
this.filePath = filePath;
this.plugin = plugin;
claims = new List<ClaimRecord>();
}
public void LoadClaimedRewards()
{
if (File.Exists(filePath))
{
try
{
string json = File.ReadAllText(filePath);
var claimContainer = JsonConvert.DeserializeObject<ClaimContainer>(json);
claims = claimContainer.claims ?? new List<ClaimRecord>();
plugin.Puts("Claimed rewards data loaded successfully.");
}
catch (IOException ex)
{
plugin.Puts($"IO error loading claimed rewards data: {ex.Message}");
claims = new List<ClaimRecord>();
}
catch (JsonException ex)
{
plugin.Puts($"JSON error loading claimed rewards data: {ex.Message}");
claims = new List<ClaimRecord>();
}
catch (Exception ex)
{
plugin.Puts($"Unexpected error loading claimed rewards data: {ex.Message}");
throw;
}
}
else
{
plugin.Puts("No claimed rewards data found, creating a new file.");
claims = new List<ClaimRecord>();
SaveClaimedRewards();
}
}
public void SaveClaimedRewards()
{
try
{
// Save the claims data back to the JSON file
var claimContainer = new ClaimContainer { claims = claims };
string json = JsonConvert.SerializeObject(claimContainer, Formatting.Indented);
File.WriteAllText(filePath, json);
plugin.Puts("Claimed rewards data saved successfully.");
}
catch (IOException ex)
{
plugin.Puts($"IO error saving claimed rewards data: {ex.Message}");
throw;
}
catch (JsonException ex)
{
plugin.Puts($"JSON error saving claimed rewards data: {ex.Message}");
throw;
}
catch (Exception ex)
{
plugin.Puts($"Unexpected error saving claimed rewards data: {ex.Message}");
throw;
}
}
public void LogClaim(string steamId, int amountClaimed)
{
// Create a new claim record
ClaimRecord newClaim = new ClaimRecord
{
steamid = steamId,
timestamp = DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture), // ISO 8601 format
amount_claimed = amountClaimed
};
// Add the new claim to the list
claims.Add(newClaim);
// Save the updated claims list to the JSON file
SaveClaimedRewards();
}
}
private class ClaimRecord
{
public string steamid { get; set; }
public string timestamp { get; set; }
public int amount_claimed { get; set; }
}
private class ClaimContainer
{
public List<ClaimRecord> claims { get; set; }
}
}
}

21
LICENSE.txt Normal file
View 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.

49
README.md Normal file
View File

@ -0,0 +1,49 @@
## Overview
The **Claim Player Rewards** plugin allows players to claim rewards based on a pre-configured JSON file. Each reward claim is logged to prevent players from claiming multiple times.
This plugin is ideal for servers that want to distribute rewards to players based on specific achievements, events, or other criteria managed through a JSON configuration file.
### Features
- Allows players to claim pre-configured rewards.
- Stores reward configurations in a JSON file.
- Logs every successful reward claim to track claims and prevent duplicates.
- No external dependencies required.
## Installation
1. Download the plugin and place it in the `oxide/plugins/` directory.
2. Create the JSON configuration file `ClaimPlayerRewards.json` in the `oxide/data/ClaimPlayerRewards/` directory.
3. Configure the SteamIDs and reward amounts.
4. Restart your server or reload the plugin.
## Configuration
The plugin will automatically generate a configuration folder and file on first run. The configuration is stored at:
`oxide/data/ClaimPlayerRewards/ClaimPlayerRewards.json`
### Example Configuration:
```json
{
"76561198000000000": 10,
"76561198000000001": 5
}
```
In this example, the SteamID `76561198000000000` is entitled to 10 reward items, and the SteamID `76561198000000001` is entitled to 5 reward items.
### Claims Logging:
All claims are logged in a separate JSON file located at:
`oxide/data/ClaimPlayerRewards/ClaimedRewards.json`
Each log entry contains:
- **SteamID**: The player's SteamID.
- **Timestamp**: When the claim was made.
- **Amount Claimed**: The number of items claimed.
## Permissions
| Permission | Purpose |
|---------------------------|-------------------------------------------------------|
| `claimplayerrewards.use` | Required to allow players to claim their rewards. |
Make sure to assign the `claimplayerrewards.use` permission to players or groups you want to grant access to claim rewards.