Иконка ресурса

FREE ScraponomicsLite : 1.1.3 1.1.3

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using Oxide.Core.Libraries.Covalence;
using Newtonsoft.Json;
//1.0.1 Adds Scrap Leaderboard on interval that lists top 5 balances.//1.0.2 Added Config options for announcement interval adjustment and number of players to announce.//1.1.0 Added SFX on ui press.Removed negative balance possibility, with an announcement (cont.below)
//1.1.0 cont.That the player cant afford the fee.Added color and Scraponomics tag.& centered ui, added coloring.//1.1.1 Changed SFX from register fx to scrap slot machine fx.Changed some coloring.//1.1.2 Added checks for 0 Balances to be skipped on announcement.//1.1.3 Added Discord Logging for top balances on announce.namespace Oxide.Plugins
{
    [Info("Scraponomics Lite", "haggbart, Wrecks", "1.1.3")]
    [Description("Adds ATM UI with simple, intuitive functionality to vending machines and bandit vendors")]
    internal class ScraponomicsLite : RustPlugin {
#region localization
        private const string LOC_PAID_BROKERAGE = "PaidBrokerage";
        private const string LOC_DEPOSIT = "Deposit";
        private const string LOC_WITHDRAW = "Withdraw";
        private const string LOC_TOTAL = "Total";
        private const string LOC_BALANCE = "Balance";
        private const string LOC_ATM = "SCRAP ATM";
        private const string LOC_REWARD_INTEREST = "RewardInterest";
        private const string LOC_INSUFFICIENT_FUNDS = "InsufficientFunds";
        private string announce = "assets/prefabs/misc/casino/slotmachine/effects/payout.prefab";
        private string increment = "assets/prefabs/tools/detonator/effects/unpress.prefab";
        private string deposit = "assets/prefabs/deployable/dropbox/effects/submit_items.prefab";
        private string withdraw = "assets/prefabs/deployable/vendingmachine/effects/vending-machine-purchase-human.prefab";
        private string insufficientfunds = "assets/prefabs/locks/keypad/effects/lock.code.denied.prefab";
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                [LOC_PAID_BROKERAGE]
                = "<color=#FF5733>[Scraponomics]</color> You paid the Brokerage fee of {0} Scrap.", [LOC_DEPOSIT] = "Deposit", [LOC_WITHDRAW] = "Withdraw", [LOC_BALANCE] = "Balance : <color=#FF5733>{0}</color> Scrap", [LOC_TOTAL] = "Total", [LOC_ATM] = "SCRAP ATM", [LOC_REWARD_INTEREST] = "<color=#FF5733>[Scraponomics]</color> You've earned {0} Scrap in interest.", [LOC_INSUFFICIENT_FUNDS] = "<color=#FF5733>[Scraponomics]</color> Insufficient funds to cover Fees and Withdraw amount."
            }
            , this);
        }
#endregion localization
#region data
        private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, playerData);
        private void ReadData() => playerData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, PlayerData>>(Name);
        private static Dictionary<ulong, PlayerData> playerData;
        private static readonly Dictionary<ulong, PlayerPreference> playerPrefs = new Dictionary<ulong, PlayerPreference>();
        private class PlayerData {
            public int scrap {
                get;
                set;
            }
            public DateTime lastInterest = DateTime.UtcNow;
        }
        private class PlayerPreference {
            public int amount {
                get;
                set;
            }
        }
#endregion data
#region config
        private PluginConfig config;
        private class PluginConfig {
            public float feesFraction;
            public int startingBalance;
            public bool allowPlayerVendingMachines;
            public bool resetOnMapWipe;
            public float interestRate;
            public int leaderboardAnnounceIntervalSeconds;
            public int leaderboardAnnouncePlayerCount;
            public string discordwebhookURL;
        }
        protected override void LoadDefaultConfig() {
            config = GetDefaultConfig();
            if (Config.Get("feesFraction") == null) Config.Set("feesFraction", config.feesFraction);
            if (Config.Get("startingBalance") == null) Config.Set("startingBalance", config.startingBalance);
            if (Config.Get("allowPlayerVendingMachines") == null) Config.Set("allowPlayerVendingMachines", config.allowPlayerVendingMachines);
            if (Config.Get("resetOnMapWipe") == null) Config.Set("resetOnMapWipe", config.resetOnMapWipe);
            if (Config.Get("interestRate") == null) Config.Set("interestRate", config.interestRate);
            if (Config.Get("leaderboardAnnounceIntervalSeconds") == null) Config.Set("leaderboardAnnounceIntervalSeconds", config.leaderboardAnnounceIntervalSeconds);
            if (Config.Get("leaderboardAnnouncePlayerCount") == null) Config.Set("leaderboardAnnouncePlayerCount", config.leaderboardAnnouncePlayerCount);
            if (Config.Get("discordwebhookURL") == null) Config.Set("discordwebhookURL", config.discordwebhookURL);
            SaveConfig();
        }
        private static PluginConfig GetDefaultConfig() {
            return new PluginConfig {
                feesFraction = 0.05f, startingBalance = 50, allowPlayerVendingMachines = false, resetOnMapWipe = true, interestRate = 0.10f, leaderboardAnnounceIntervalSeconds = 720, leaderboardAnnouncePlayerCount = 5
            }
            ;
        }
#endregion config
#region init
        private void Init() {
            config = Config.ReadObject<PluginConfig>();
            AddCovalenceCommand("scrapannounce", "CmdScrapAnnounce");
            if (!config.resetOnMapWipe) {
                Unsubscribe(nameof(OnNewSave));
            }
            SaveConfig();
            ReadData();
        }
        private void InitPlayerData(BasePlayer player) {
            var playerbalances = new PlayerData {
                scrap = config.startingBalance
            }
            ;
            playerData.Add(player.userID, playerbalances);
        }
        private static void InitPlayerPerference(BasePlayer player) {
            var playerPreference = new PlayerPreference {
                amount = 100
            }
            ;
            playerPrefs.Add(player.userID, playerPreference);
        }
        private void Unload() {
            foreach (BasePlayer player in BasePlayer.activePlayerList) {
                DestroyGuiAll(player);
            }
            SaveData();
        }
#endregion init
#region methods
        private void DoInterest(BasePlayer player) {
            PlayerData data = playerData[player.userID];
            if (data.scrap < 1) return;
            TimeSpan timeSinceLastInterest = DateTime.UtcNow - data.lastInterest;
            if (timeSinceLastInterest.Days == 0) {
                return;
            }
            int interest = (int)(data.scrap * Math.Pow(config.interestRate + 1.0f, timeSinceLastInterest.TotalSeconds / 86400.0)) - data.scrap;
            if (interest < 1) return;
            data.scrap += interest;
            data.lastInterest = DateTime.UtcNow;
            SendReply(player, lang.GetMessage(LOC_REWARD_INTEREST, this, player.UserIDString), interest);
        }
#endregion methods
#region hooks
        private void OnServerSave() {
            SaveData();
        }
        private void OnNewSave(string filename) {
            playerData = new Dictionary<ulong, PlayerData>();
            SaveData();
        }
        private void OnVendingShopOpened(VendingMachine machine, BasePlayer player) {
            if (!(machine is NPCVendingMachine) && !config.allowPlayerVendingMachines) return;
            if (!playerData.ContainsKey(player.userID)) {
                InitPlayerData(player);
            }
            DoInterest(player);
            NextTick(() => CreateUi(player));
        }
        private void OnLootEntityEnd(BasePlayer player, VendingMachine machine) {
            DestroyGuiAll(player);
        }
        private static void DestroyGuiAll(BasePlayer player) {
            CuiHelper.DestroyUi(player, CUI_BANK_NAME);
        }
#endregion hooks
#region bank CUI
        private const int CUI_MAIN_FONTSIZE = 10;
        private const string CUI_MAIN_FONT_COLOR = "0.7 0.7 0.7 1.0";
        private const string CUI_GREEN_BUTTON_COLOR = "0.415 0.5 0.258 0.4";
        private const string CUI_GREEN_BUTTON_FONT_COLOR = "0.607 0.705 0.431";
        private const string CUI_GRAY_BUTTON_COLOR = "0.75 0.75 0.75 0.3";
        private const string CUI_BUTTON_FONT_COLOR = "0.77 0.68 0.68 1";
        private const string CUI_BANK_NAME = "BankUI";
        private const string CUI_BANK_HEADER_NAME = "header";
        private const string CUI_BANK_CONTENT_NAME = "content";
        private const string ANCHOR_MIN = "0.5 0.0";
        private const string ANCHOR_MAX = "0.67 0.0";
        private const string OFFSET_MIN = "193 16";
        private const string OFFSET_MAX = "200 97";
        private void CreateUi(BasePlayer player) {
            if (!player.inventory.loot.IsLooting()) return;
            if (!playerPrefs.ContainsKey(player.userID)) {
                InitPlayerPerference(player);
            }
            int amount = playerPrefs[player.userID].amount;
            double nextDecrement = amount / 1.5;
            double nextIncrement = amount * 1.5;
            CuiHelper.DestroyUi(player, CUI_BANK_NAME);
            var bankCui = new CuiElementContainer {
                {
                    new CuiPanel  // main panel
                    {
                        Image = new CuiImageComponent {
                            Color = "0 0 0 0"
                        }
                        , RectTransform = {
                            AnchorMin = ANCHOR_MIN, AnchorMax = ANCHOR_MAX, OffsetMin = OFFSET_MIN, OffsetMax = OFFSET_MAX
                        }
                    }
                    , "Hud.Menu", CUI_BANK_NAME
                }
                , {
                    new CuiPanel  // header
                    {
                        Image = new CuiImageComponent {
                            Color = "0.75 0.75 0.75 0.35"
                        }
                        , RectTransform = {
                            AnchorMin = "0 0.775", AnchorMax = "1 1"
                        }
                    }
                    , CUI_BANK_NAME, CUI_BANK_HEADER_NAME
                }
                , {
                    new CuiLabel  // header label
                    {
                        RectTransform = {
                            AnchorMin = "0.051 0", AnchorMax = "1 0.95"
                        }
                        , Text = {
                            Text = lang.GetMessage(LOC_ATM, this, player.UserIDString), Align = TextAnchor.MiddleCenter, Color = "1.000 0.341 0.200", FontSize = 13
                        }
                    }
                    , CUI_BANK_HEADER_NAME
                }
                , {
                    new CuiPanel  // content panel
                    {
                        Image = new CuiImageComponent {
                            Color = "0.65 0.65 0.65 0.25"
                        }
                        , RectTransform = {
                            AnchorMin = "0 0", AnchorMax = "1 0.74"
                        }
                    }
                    , CUI_BANK_NAME, CUI_BANK_CONTENT_NAME
                }
                , {
                    new CuiLabel  // balance label
                    {
                        RectTransform = {
                            AnchorMin = "0.02 0.7", AnchorMax = "0.98 1"
                        }
                        , Text = {
                            Text = string.Format(lang.GetMessage(LOC_BALANCE, this, player.UserIDString), playerData[player.userID].scrap), Align = TextAnchor.MiddleCenter, Color = CUI_MAIN_FONT_COLOR, FontSize = CUI_MAIN_FONTSIZE
                        }
                    }
                    , CUI_BANK_CONTENT_NAME
                }
                , {
                    new CuiButton  // deposit button
                    {
                        RectTransform = {
                            AnchorMin = "0.28 0.4", AnchorMax = "0.48 0.7"
                        }
                        , Button = {
                            Command = "sc.deposit " + amount, Color = CUI_GREEN_BUTTON_COLOR
                        }
                        , Text = {
                            Align = TextAnchor.MiddleCenter, Text = lang.GetMessage(LOC_DEPOSIT, this, player.UserIDString), Color = CUI_GREEN_BUTTON_FONT_COLOR, FontSize = 11
                        }
                    }
                    , CUI_BANK_CONTENT_NAME
                }
                , {
                    new CuiButton  // withdraw button
                    {
                        RectTransform = {
                            AnchorMin = "0.49 0.4", AnchorMax = "0.73 0.7"
                        }
                        , Button = {
                            Command = "sc.withdraw " + amount, Color = CUI_GRAY_BUTTON_COLOR
                        }
                        , Text = {
                            Align = TextAnchor.MiddleCenter, Text = lang.GetMessage(LOC_WITHDRAW, this, player.UserIDString), Color = CUI_MAIN_FONT_COLOR, FontSize = 11
                        }
                    }
                    , CUI_BANK_CONTENT_NAME
                }
                , {
                    new CuiButton  // decrement button
                    {
                        RectTransform = {
                            AnchorMin = "0.35 0.05", AnchorMax = "0.40 0.35"
                        }
                        , Button = {
                            Command = "sc.setamount " + nextDecrement, Color = CUI_GRAY_BUTTON_COLOR
                        }
                        , Text = {
                            Align = TextAnchor.MiddleCenter, Text = "<", Color = CUI_BUTTON_FONT_COLOR, FontSize = CUI_MAIN_FONTSIZE
                        }
                    }
                    , CUI_BANK_CONTENT_NAME
                }
                , {
                    new CuiLabel  // amount label
                    {
                        RectTransform = {
                            AnchorMin = "0.42 0.05", AnchorMax = "0.53 0.35"
                        }
                        , Text = {
                            Align = TextAnchor.MiddleCenter, Text = amount.ToString(), Color = CUI_MAIN_FONT_COLOR, FontSize = CUI_MAIN_FONTSIZE
                        }
                    }
                    , CUI_BANK_CONTENT_NAME
                }
                , {
                    new CuiButton  // increment button
                    {
                        RectTransform = {
                            AnchorMin = "0.57 0.05", AnchorMax = "0.62 0.35"
                        }
                        , Button = {
                            Command = "sc.setamount " + nextIncrement, Color = CUI_GRAY_BUTTON_COLOR
                        }
                        , Text = {
                            Align = TextAnchor.MiddleCenter, Text = ">", Color = CUI_BUTTON_FONT_COLOR, FontSize = CUI_MAIN_FONTSIZE
                        }
                    }
                    , CUI_BANK_CONTENT_NAME
                }
                , {
                    new CuiLabel  // amount text label
                    {
                        RectTransform = {
                            AnchorMin = "0.65 0.05", AnchorMax = "0.75 0.35"
                        }
                        , Text = {
                            Align = TextAnchor.MiddleLeft, Text = lang.GetMessage(LOC_TOTAL, this, player.UserIDString), Color = CUI_MAIN_FONT_COLOR, FontSize = CUI_MAIN_FONTSIZE
                        }
                    }
                    , CUI_BANK_CONTENT_NAME
                }
            }
            ;
            CuiHelper.AddUi(player, bankCui);
        }
        [ConsoleCommand("sc.setamount")]
        private void CmdSetAmount(ConsoleSystem.Arg arg) {
            var player = arg.Connection.player as BasePlayer;
            if (player == null || arg.Args.Length != 1 || !(player.inventory.loot.entitySource is VendingMachine)) return;
            double amount;
            if (!double.TryParse(arg.Args[0], out amount)) return;
            amount = Math.Round(amount / 10) * 10;
            if (amount < 10) amount = 10;
            else if (amount > 1000) amount = 1000;
            if (arg.Args.Length != 1) return;
            if (!playerPrefs.ContainsKey(player.userID)) {
                InitPlayerPerference(player);
            }
            playerPrefs[player.userID].amount = (short)amount;
            CreateUi(player);
            // sfx on ui interaction
            TriggerIncrementEffect(player);
        }
        private void TriggerIncrementEffect(BasePlayer player) {
            EffectNetwork.Send(new Effect(increment, player.transform.position, Vector3.zero), player.net.connection);
        }
        [ConsoleCommand("sc.deposit")]
        private void CmdDeposit(ConsoleSystem.Arg arg) {
            var player = arg.Connection.player as BasePlayer;
            if (player == null || arg.Args.Length != 1 || !(player.inventory.loot.entitySource is VendingMachine)) return;
            int amount;
            if (!int.TryParse(arg.Args[0], out amount)) return;
            if (player.inventory.GetAmount(-932201673) < amount) {
                amount = player.inventory.GetAmount(-932201673);
            }
            if (amount == 0) return;
            if (!playerData.ContainsKey(player.userID)) {
                InitPlayerData(player);
            }
            playerData[player.userID].scrap += amount;
            player.inventory.Take(null, -932201673, amount);
            CreateUi(player);
            // sfx on ui deposit interaction
            TriggerDepositEffect(player);
        }
        private void TriggerDepositEffect(BasePlayer player) {
            EffectNetwork.Send(new Effect(deposit, player.transform.position, Vector3.zero), player.net.connection);
        }
        [ConsoleCommand("sc.withdraw")]
        private void CmdWithdraw(ConsoleSystem.Arg arg) {
            var player = arg.Connection.player as BasePlayer;
            if (player == null || arg.Args.Length != 1 || !(player.inventory.loot.entitySource is VendingMachine)) return;
            int amount;
            if (!int.TryParse(arg.Args[0], out amount)) return;
            if (!playerData.ContainsKey(player.userID)) {
                InitPlayerData(player);
            }
            int balance = playerData[player.userID].scrap;
            int tax = (int)Math.Round(amount * config.feesFraction);
            if (balance < amount + tax) {
                SendReply(player, string.Format(lang.GetMessage(LOC_INSUFFICIENT_FUNDS, this, player.UserIDString)));
                TriggerInsufficientFundsEffect(player);
                return;
            }
            playerData[player.userID].scrap -= amount + tax;
            CreateUi(player);
            Item item = ItemManager.CreateByItemID(-932201673, amount);
            if (item == null) return;
            player.inventory.GiveItem(item);
            SendReply(player, string.Format(lang.GetMessage(LOC_PAID_BROKERAGE, this, player.UserIDString), tax));
            // sfx on ui withdraw interaction
            TriggerWithdrawEffect(player);
        }
        private void TriggerWithdrawEffect(BasePlayer player) {
            EffectNetwork.Send(new Effect(withdraw, player.transform.position, Vector3.zero), player.net.connection);
        }
        private void TriggerInsufficientFundsEffect(BasePlayer player) {
            EffectNetwork.Send(new Effect(insufficientfunds, player.transform.position, Vector3.zero), player.net.connection);
        }
        // Command to announce at will.[Command("scrapannounce")]
        private void CmdScrapAnnounce(IPlayer player, string cmd, string[] args) {
            if (player.IsAdmin) {
                AnnounceTopBalances();
            }
            else {
                player.Reply("You don't have permission to use this command.");
            }
        }
#endregion bank CUI
#region Announce Top Balances
        private void OnServerInitialized() {
            timer.Every(config.leaderboardAnnounceIntervalSeconds, AnnounceTopBalances);
        }
        private void AnnounceTopBalances() {
            var topBalances = playerData.OrderByDescending(kv => kv.Value.scrap).Take(config.leaderboardAnnouncePlayerCount).ToList();
            if (topBalances.Count == 0 || topBalances.All(kv => kv.Value.scrap == 0)) {
                return;
            }
            string message = "<size=16><color=#FF5733>Scrap Leaderboard</color></size>\n";
            for (int i = 0; i < topBalances.Count; i++) {
                var kv = topBalances[i];
                var playerData = kv.Value;
                var playerID = kv.Key;
                var playerName = covalence.Players.FindPlayerById(playerID.ToString())?.Name ?? playerID.ToString();
                if (playerData.scrap > 0) {
                    message += $"<color=#ff3375>{i + 1}.</color> <color=#ffbd33>{playerName}</color> with <color=#ff5733>{playerData.scrap}</color> Scrap.\n";
                }
            }
            PrintToChat(message);
            foreach (var player in BasePlayer.activePlayerList) {
                EffectNetwork.Send(new Effect(announce, player.transform.position, Vector3.zero));
            }
            var topBalancesStringKeys = topBalances.Select(kv => new KeyValuePair<string, PlayerData>(kv.Key.ToString(), kv.Value)).ToList();
            SendDiscordTopBalances(topBalancesStringKeys);
        }
#endregion Announce Top Balances
#region Discord
        private void SendDiscordTopBalances(List<KeyValuePair<string, PlayerData>> topBalances) {
            string webhookUrl = Convert.ToString(config.discordwebhookURL);
            if (topBalances == null || topBalances.Count == 0 || string.IsNullOrEmpty(webhookUrl) || !webhookUrl.Contains("/api/webhooks")) {
                Puts("Failed to send Discord Message.Webhook URL or content is invalid.");
                return;
            }
            var discordMessage = new {
                embeds = new[] {
                    new {
                        title = "Scrap Leaderboard", color = 15158332, fields = topBalances.Select((kv, index) => new {
                            name = $"#{index + 1} {covalence.Players.FindPlayerById(kv.Key.ToString())?.Name ?? kv.Key.ToString()}", value = $"Balance: {kv.Value.scrap} Scrap", inline = false
                        }
                        ).ToArray()
                    }
                }
            }
            ;
            // Convert the message to JSON
            string content = JsonConvert.SerializeObject(discordMessage);
            if (string.IsNullOrEmpty(content)) {
                return;
            }
            // Send the message to Discord
            webrequest.Enqueue(webhookUrl, content, (code, response) => {
                if (code != 204) {
                    Puts($"Discord responded with code {code}.Response: {response}");
                }
            }
            , this, RequestMethod.POST, new Dictionary<string, string> {
                ["Content-Type"]
                = "application/json"
            }
            );
        }
        private const string DiscordJson = @"{
    ""embeds"":[{
        ""fields"": [
            {
                ""name"": ""${message.field.name}"",
                ""value"": ""${message}""
            }
        ]
    }]
}";
#endregion
#region API
        private object SetBalance(ulong userId, int balance) {
            if (!playerData.ContainsKey(userId) && !TryInitPlayer(userId)) return null;
            playerData[userId].scrap = balance;
            return true;
        }
        private object GetBalance(ulong userId) {
            if (!playerData.ContainsKey(userId) && !TryInitPlayer(userId)) return null;
            return playerData[userId].scrap;
        }
        private bool TryInitPlayer(ulong userId) {
            BasePlayer player = BasePlayer.FindByID(userId);
            if (player == null) return false;
            InitPlayerData(player);
            return true;
        }
#endregion API
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху