using Newtonsoft.Json; using Oxide.Core; using Oxide.Core.Libraries.Covalence; using Oxide.Core.Plugins; using Oxide.Game.Rust.Cui; using System.Globalization; using UnityEngine; using Newtonsoft.Json.Linq; using Oxide.Core.Configuration; using Oxide.Core.Libraries; using Oxide.Plugins; using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; namespace Oxide.Plugins { [Info("PlaytimeCommands", "Ifte", "1.0.1")] [Description("Execute commands on playtime")] public class PlaytimeCommands : RustPlugin { [PluginReference] Plugin PlaytimeTracker, PlayTimeRewards; private Configuration config; private Timer RepeatTimer; private Dictionary> playerRewards = new Dictionary>(); private const string AdminPerm = "PlaytimeCommands.admin"; protected override void LoadConfig() { base.LoadConfig(); config = Config.ReadObject(); } protected override void LoadDefaultConfig() { config = new Configuration(); } protected override void SaveConfig() { Config.WriteObject(config, true); } private List Cmds = new List(); private class Configuration { [JsonProperty("Select Playtime plugin(0 - PlaytimeTracker, 1 - PlayTimeRewards)")] public int playTimePlugin = 0; [JsonProperty("Check how often it checks for playtime and execute commands?(In Seconds)")] public int interval = 1800; [JsonProperty("Execute command upon playtime Minutes completation", ObjectCreationHandling = ObjectCreationHandling.Replace)] public Dictionary> Rewards { get; set; } = new Dictionary> { { 20, new List { "oxide.usergroup add {UserID} chads", "chat user add {UserID} chads" } }, { 30, new List { "sr add {Name} 1000", "sr take {UserID} 100", "oxide.usergroup add {UserID} veteran" } } }; [JsonProperty("Reset data on new wipe")] public bool resetonwipe = false; [JsonProperty("Discord Webhook Settings")] public DiscordSetting webhook = new DiscordSetting(); } private class DiscordSetting { [JsonProperty("Enable discord notify")] public bool enableDiscord = false; [JsonProperty("Webhook URL")] public string webHookURL = string.Empty; [JsonProperty("Message")] public List DiscordMessages = new List { "PlaytimeCommands", "Excuted commands for {PLAYERNAME} - {PLAYERID}", "Executed Playtime ID {PLAYTIME}" }; } private void OnServerInitialized() { permission.RegisterPermission(AdminPerm, this); if (config.playTimePlugin == 0 && PlaytimeTracker == null) { Puts($"This requires PlaytimeTracker plugin to work.(Link: https://umod.org/plugins/playtime-tracker)"); return; } if (config.playTimePlugin == 1 && PlayTimeRewards == null) { Puts($"This requires PlayTimeRewards plugin to work.(Link: https://umod.org/plugins/play-time-rewards)"); return; } LoadData(); if (config.interval > 0 && HasPlaytimePlugin()) { RepeatTimer = timer.Every(config.interval, () => { StartTimer(); }); } } private void Unload() { RepeatTimer.Destroy(); SaveData(); } private void OnNewSave(string filename) { if (config.resetonwipe) { playerRewards.Clear(); SaveData(); Puts("PlayerRewards data cleared."); } } private void StartTimer() { if (config == null || config.Rewards.Count == 0) return; foreach (var player in BasePlayer.activePlayerList) { double playtimeHours = GetPlayTime(player); // Get playtime in hours foreach (var reward in config.Rewards) { int thresholdHours = reward.Key; // Threshold List commands = reward.Value; // Commands for this threshold // Check if player's playtime meets or exceeds the threshold if (playtimeHours >= thresholdHours && !HasReceivedReward(player.UserIDString, thresholdHours)) { // Execute commands for this reward foreach (var command in commands) { // Execute command here ExecuteCommand(command, player); } AddRewardRecord(player.UserIDString, thresholdHours); SendDHook(player, thresholdHours); } } } } private void ExecuteCommand(string command, BasePlayer player) { IPlayer p = player.IPlayer; // Execute the command here // Check for {UserID}, {Name} Server.Command(command.Replace("{UserID}", player.UserIDString).Replace("{Name}", p.Name)); } private double GetPlayTime(BasePlayer player) { double playTime = 0; if (config.playTimePlugin == 0 && PlaytimeTracker != null) { //PlaytimeTracker.Call method returns playtime in seconds playTime = Convert.ToDouble(PlaytimeTracker.Call("GetPlayTime", player.UserIDString)) / 60; // Convert seconds to minutes } else if (config.playTimePlugin == 1 && PlayTimeRewards != null) { playTime = Convert.ToDouble(PlayTimeRewards.Call("FetchPlayTime", player.UserIDString)) / 60; } else { Puts("There is no Playtime tracking the playtime for players."); } return playTime; } private void LoadData() { playerRewards = Interface.Oxide.DataFileSystem.ReadObject>>($"{Name}/PlayerRewards"); } private void SaveData() { Interface.Oxide.DataFileSystem.WriteObject($"{Name}/PlayerRewards", playerRewards); } private bool HasReceivedReward(string userId, int hour) { if (!playerRewards.ContainsKey(userId)) return false; return playerRewards[userId].Contains(hour); } private void AddRewardRecord(string userId, int hour) { if (!playerRewards.ContainsKey(userId)) playerRewards[userId] = new List(); playerRewards[userId].Add(hour); SaveData(); } [ChatCommand("prc")] private void CMDAdmin(BasePlayer player, string cmd, string[] args) { if (player == null || !permission.UserHasPermission(player.UserIDString, AdminPerm) || !player.IsAdmin) { player?.ChatMessage("No Permission or invalid player."); return; } string command = args[0]; switch (command) { case "reset": playerRewards.Clear(); SaveData(); Puts("You have cleared all PlayerRewards data."); player.ChatMessage("You have cleared all PlayerRewards data."); return; } } [ConsoleCommand("prc")] private void CMDAdminConsole(ConsoleSystem.Arg args) { BasePlayer player = args.Player(); string command = args.Args[0]; switch (command) { case "reset": playerRewards.Clear(); SaveData(); Puts("You have cleared all PlayerRewards data."); return; } } private bool HasPlaytimePlugin() { if (config.playTimePlugin == 0 && PlaytimeTracker != null) return true; else if (config.playTimePlugin == 1 && PlayTimeRewards != null) return true; return false; } private void SendDHook(BasePlayer player, int Playtime) { if (!config.webhook.enableDiscord || config.webhook.webHookURL == string.Empty) return; string message = string.Join("\n", config.webhook.DiscordMessages); message = message.Replace("{PLAYERNAME}", player.displayName).Replace("{PLAYERID}", player.UserIDString).Replace("{PLAYTIME}", Playtime.ToString()); SendDiscordMessage(config.webhook.webHookURL, "", new List { }); } #region Discord Intregration private void SendDiscordMessage(string webhook, string title, List embeds, bool inline = false) { Embed embed = new Embed(); foreach (var item in embeds) { embed.AddField(title, item, inline, 3066993); } webrequest.Enqueue(webhook, new DiscordMessage(string.Empty, embed).ToJson(), (code, response) => { }, this, RequestMethod.POST, new Dictionary { { "Content-Type", "application/json" } }); } private class DiscordMessage { public DiscordMessage(string content, params Embed[] embeds) { Content = content; Embeds = embeds.ToList(); } [JsonProperty("content")] public string Content { get; set; } [JsonProperty("embeds")] public List Embeds { get; set; } public string ToJson() { return JsonConvert.SerializeObject(this); } } private class Embed { public int color { get; set; } [JsonProperty("fields")] public List Fields { get; set; } = new List(); public Embed AddField(string name, string value, bool inline, int colors) { Fields.Add(new Field(name, Regex.Replace(value, "<.*?>", string.Empty), inline)); color = colors; return this; } } private class Field { public Field(string name, string value, bool inline) { Name = name; Value = value; Inline = inline; } [JsonProperty("name")] public string Name { get; set; } [JsonProperty("value")] public string Value { get; set; } [JsonProperty("inline")] public bool Inline { get; set; } } #endregion } }