Jump to content

[PAID] Make minor changes to the SQL Economics plugin


laodu

Recommended Posts

Hello,
Can someone make a couple of changes in one basic plugin? Please reply if you can, I can tip of course 

After installing the plugin and running it on the server, not a single row with the player was created in the database. And also, when entering the command, the deposit displays a message that 100 has been accrued, even if I enter deposit 1000
And also when viewing the balance of the player displays 100 credits

/***********************************************************************************************************************/
/*** DO NOT edit this file! Edit the files under `oxide/config` and/or `oxide/lang`, created once plugin has loaded. ***/
/*** Please note, support cannot be provided if the plugin has been modified. Please use a fresh copy if modified.   ***/
/***********************************************************************************************************************/

//#define DEBUG

using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using MySql.Data.MySqlClient;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;

namespace Oxide.Plugins
{
    [Info("Economics", "Wulf", "4.0.0")]
    [Description("Basic economics system and economy API")]
    public class Economics : CovalencePlugin
    {
        #region Configuration

        private Configuration _config;

        public class MySqlConfig
        {
            public string Server = "localhost";
            public string Username = "root";
            public string Password = "";
            public string Database = "economics";
        }

        public class Configuration
        {
            [JsonProperty("Balance limit for accounts (0.0 to disable)")]
            public double BalanceLimit = 0.0;

            [JsonProperty("Balance limit for accounts (0 to disable)")]
            private int BalanceLimitOld { set { BalanceLimit = Convert.ToDouble(value); } } // TODO: From version 3.9.1; remove eventually

            [JsonProperty("Negative balance limit for accounts (0.0 to disable)")]
            public double NegativeBalanceLimit;

            [JsonProperty("Negative balance limit for accounts (0 to disable)")]
            public int NegativeBalanceLimitOld { set { NegativeBalanceLimit = Convert.ToDouble(value); } } // TODO: From version 3.9.1; remove eventually

            [JsonProperty("Remove unused accounts")]
            public bool RemoveUnused = true;

            [JsonProperty("Log transactions to file")]
            public bool LogTransactions = false;

            [JsonProperty("Starting account balance (0.0 or higher)")]
            public double StartingBalance = 1000.0;

            [JsonProperty("Starting account balance (0 or higher)")]
            private int StartingBalanceOld { set { StartingBalance = Convert.ToDouble(value); } } // TODO: From version 3.9.1; remove eventually

            [JsonProperty("Wipe balances on new save file")]
            public bool WipeOnNewSave = false;

            [JsonProperty("Store data in SQLite instead of data files")]
            public bool UseSqLite = false;

            [JsonProperty("Store data in MySQL instead of data files")]
            public bool UseMySql = false;

            [JsonProperty("MySQL configuration, if using MySQL")]
            public MySqlConfig MySql = new MySqlConfig();

            public string ToJson() => JsonConvert.SerializeObject(this);

            public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
        }

        protected override void LoadDefaultConfig() => _config = new Configuration();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<Configuration>();
                if (_config == null)
                {
                    throw new JsonException();
                }

                if (!_config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys))
                {
                    LogWarning("Configuration appears to be outdated; updating and saving");
                    SaveConfig();
                }
            }
            catch
            {
                LogWarning($"Configuration file {Name}.json is invalid; using defaults");
                LoadDefaultConfig();
            }
        }

        protected override void SaveConfig()
        {
            LogWarning($"Configuration changes saved to {Interface.Oxide.ConfigDirectory}{Path.DirectorySeparatorChar}{Name}.json");
            Config.WriteObject(_config, true);
        }

        #endregion Configuration

        #region Stored Data

        private DynamicConfigFile _oldStoredData;
        private KeyValuePair<double, double> _balanceLimits;
        private MySqlConnection _mysqlConnection;
        private SQLiteConnection _sqlConnection;
        private StoredData _storedData;
        private bool _changed;
        private string _connectionStr;

        private class StoredData
        {
            public readonly Dictionary<string, double> Balances = new Dictionary<string, double>();
        }

        private void SaveData()
        {
            if (_changed)
            {
                Log("Saving balances for players...");
                Interface.Oxide.DataFileSystem.WriteObject(Name, _storedData); // TODO: Try/catch potential IOException
                _changed = false;
            }
        }

        private void OnServerSave() => SaveData();

        private void Unload() => SaveData();

        #endregion Stored Data

        #region Localization

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["CommandBalance"] = "balance",
                ["CommandDeposit"] = "deposit",
                ["CommandSetBalance"] = "SetBalance",
                ["CommandTransfer"] = "transfer",
                ["CommandWithdraw"] = "withdraw",
                ["CommandWipe"] = "ecowipe",
                ["DataSaved"] = "Economics data saved!",
                ["DataWiped"] = "Economics data wiped!",
                ["DepositedToAll"] = "Deposited {0:C} total ({1:C} each) to {2} player(s)",
                ["LogDeposit"] = "{0:C} deposited to {1}",
                ["LogSetBalance"] = "{0:C} set as balance for {1}",
                ["LogTransfer"] = "{0:C} transferred to {1} from {2}",
                ["LogWithdrawl"] = "{0:C} withdrawn from {1}",
                ["NegativeBalance"] = "Balance can not be negative!",
                ["NotAllowed"] = "You are not allowed to use the '{0}' command",
                ["NoPlayersFound"] = "No players found with name or ID '{0}'",
                ["PlayerBalance"] = "Balance for {0}: {1:C}",
                ["PlayerLacksMoney"] = "'{0}' does not have enough money!",
                ["PlayersFound"] = "Multiple players were found, please specify: {0}",
                ["ReceivedFrom"] = "You have received {0} from {1}",
                ["SetBalanceForAll"] = "Balance set to {0:C} for {1} player(s)",
                ["TransactionFailed"] = "Transaction failed! Make sure amount is above 0",
                ["TransferredTo"] = "{0} transferred to {1}",
                ["TransferredToAll"] = "Transferred {0:C} total ({1:C} each) to {2} player(s)",
                ["TransferToSelf"] = "You can not transfer money yourself!",
                ["UsageBalance"] = "{0} - check your balance",
                ["UsageBalanceOthers"] = "{0} <player name or id> - check balance of a player",
                ["UsageDeposit"] = "{0} <player name or id> <amount> - deposit amount to player",
                ["UsageSetBalance"] = "Usage: {0} <player name or id> <amount> - set balance for player",
                ["UsageTransfer"] = "Usage: {0} <player name or id> <amount> - transfer money to player",
                ["UsageWithdraw"] = "Usage: {0} <player name or id> <amount> - withdraw money from player",
                ["UsageWipe"] = "Usage: {0} - wipe all economics data",
                ["YouLackMoney"] = "You do not have enough money!",
                ["YouLostMoney"] = "You lost: {0:C}",
                ["YouReceivedMoney"] = "You received: {0:C}",
                ["YourBalance"] = "Your balance is: {0:C}",
                ["WithdrawnForAll"] = "Withdrew {0:C} total ({1:C} each) from {2} player(s)",
                ["ZeroAmount"] = "Amount cannot be zero"
            }, this);
        }

        #endregion Localization

        #region Initialization

        private const string PermissionBalance = "economics.balance";
        private const string PermissionDeposit = "economics.deposit";
        private const string PermissionDepositAll = "economics.depositall";
        private const string PermissionSetBalance = "economics.setbalance";
        private const string PermissionSetBalanceAll = "economics.setbalanceall";
        private const string PermissionTransfer = "economics.transfer";
        private const string PermissionTransferAll = "economics.transferall";
        private const string PermissionWithdraw = "economics.withdraw";
        private const string PermissionWithdrawAll = "economics.withdrawall";
        private const string PermissionWipe = "economics.wipe";

        private void Init()
        {
            // Register universal chat/console commands
            AddLocalizedCommand(nameof(CommandBalance));
            AddLocalizedCommand(nameof(CommandDeposit));
            AddLocalizedCommand(nameof(CommandSetBalance));
            AddLocalizedCommand(nameof(CommandTransfer));
            AddLocalizedCommand(nameof(CommandWithdraw));
            AddLocalizedCommand(nameof(CommandWipe));

            // Register permissions for commands
            permission.RegisterPermission(PermissionBalance, this);
            permission.RegisterPermission(PermissionDeposit, this);
            permission.RegisterPermission(PermissionDepositAll, this);
            permission.RegisterPermission(PermissionSetBalance, this);
            permission.RegisterPermission(PermissionSetBalanceAll, this);
            permission.RegisterPermission(PermissionTransfer, this);
            permission.RegisterPermission(PermissionTransferAll, this);
            permission.RegisterPermission(PermissionWithdraw, this);
            permission.RegisterPermission(PermissionWithdrawAll, this);
            permission.RegisterPermission(PermissionWipe, this);

            if (_config.UseSqLite && _config.UseMySql)
            {
                LogWarning("Both SQLite and MySQL databases are enabled; defaulting to SQLite for data storage");
            }

            if (_config.UseMySql || _config.UseSqLite)
            {
                Unsubscribe(nameof(OnServerSave));
                Unsubscribe(nameof(Unload));
            }

            bool emptyDatabase = true;
            if (_config.UseSqLite)
            {
                _connectionStr = $"Data Source={Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}{Name}.db;";
                _sqlConnection = new SQLiteConnection(_connectionStr);
                _sqlConnection.Open();
                emptyDatabase = CheckDatabase();
            }
            else if (_config.UseMySql)
            {
                _connectionStr = $"server={_config.MySql.Server};uid={_config.MySql.Username};pwd={_config.MySql.Password};database={_config.MySql.Database};";
                _mysqlConnection = new MySqlConnection(_connectionStr);
                _mysqlConnection.Open();
                emptyDatabase = CheckDatabase();
            }

            if ((!_config.UseMySql && !_config.UseSqLite))
            {
                // Load existing data and migrate old data format
                _oldStoredData = Interface.Oxide.DataFileSystem.GetFile(Name);
                try
                {
                    Dictionary<ulong, double> temp = _oldStoredData.ReadObject<Dictionary<ulong, double>>();
                    try
                    {
                        _storedData = new StoredData();
                        foreach (KeyValuePair<ulong, double> old in temp)
                        {
                            if (!_storedData.Balances.ContainsKey(old.Key.ToString()))
                            {
                                _storedData.Balances.Add(old.Key.ToString(), old.Value);
                            }
                        }
                        _changed = true;
                    }
                    catch
                    {
                        // Ignore
                    }
                }
                catch
                {
                    _storedData = _oldStoredData.ReadObject<StoredData>();
                    _changed = true;
                }

                List<string> playerData = new List<string>(_storedData.Balances.Keys);

                // Check for and set any balances over maximum allowed
                if (_config.BalanceLimit > 0)
                {
                    foreach (string playerId in playerData)
                    {
                        if (_storedData.Balances[playerId] > _config.BalanceLimit)
                        {
                            _storedData.Balances[playerId] = _config.BalanceLimit;
                            _changed = true;
                        }
                    }
                }

                // Check for and remove any inactive player balance data
                if (_config.RemoveUnused)
                {
                    foreach (string playerId in playerData)
                    {
                        if (_storedData.Balances[playerId].Equals(_config.StartingBalance))
                        {
                            _storedData.Balances.Remove(playerId);
                            _changed = true;
                        }
                    }
                }
            }

            if (_config.UseSqLite)
            {
                if (emptyDatabase)
                {
                    // Migrate/import the data file, if present
                    foreach (KeyValuePair<string, double> playerData in _storedData.Balances)
                    {
                        using (SQLiteConnection connection = new SQLiteConnection(_connectionStr))
                        {
                            connection.Open();
                            string query = $"INSERT INTO balances VALUES ('{playerData.Key}', {playerData.Value})";
                            using (SQLiteCommand sqlCommand = new SQLiteCommand(query, connection))
                            {
                                sqlCommand.ExecuteNonQuery();
                            }
                        }
                    }
                }
                else if (_config.RemoveUnused)
                {
                    Log("Reading data from SQLite database...");

                    // Read the storedData from SQLite
                    _storedData = new StoredData();
                    using (SQLiteConnection connection = new SQLiteConnection(_connectionStr))
                    {
                        connection.Open();
                        using (SQLiteCommand sqlCommand = new SQLiteCommand("SELECT DISTINCT playerid, value FROM balances", connection))
                        using (SQLiteDataReader reader = sqlCommand.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                string playerId = reader.GetString(0);
                                double balance = reader.GetDouble(1);
                                _storedData.Balances.Add(playerId, balance);
                            }
                        }
                    }

                    // Check for and remove any inactive player balance data
                    foreach (string playerId in new List<string>(_storedData.Balances.Keys))
                    {
                        if (_storedData.Balances[playerId].Equals(_config.StartingBalance))
                        {
                            using (SQLiteConnection connection = new SQLiteConnection(_connectionStr))
                            {
                                connection.Open();
                                using (SQLiteCommand sqlCommand = new SQLiteCommand($"DELETE FROM balances WHERE playerid='{playerId}'", connection))
                                {
                                    sqlCommand.ExecuteNonQuery();
                                }
                            }
                        }
                    }
                    _storedData = new StoredData();
                }
            }
            else if (_config.UseMySql)
            {
                if (emptyDatabase)
                {
                    // Migrate/import the data file, if present
                    foreach (KeyValuePair<string, double> playerData in _storedData.Balances)
                    {
                        using (MySqlConnection connection = new MySqlConnection(_connectionStr))
                        {
                            connection.Open();
                            string query = $"INSERT INTO balances VALUES ('{playerData.Key}', {playerData.Value})";
                            using (MySqlCommand sqlCommand = new MySqlCommand(query, connection))
                            {
                                sqlCommand.ExecuteNonQuery();
                            }
                        }
                    }
                }
                else if (_config.RemoveUnused)
                {
                    Log("Reading data from MySQL database...");

                    _storedData = new StoredData();
                    using (MySqlConnection connection = new MySqlConnection(_connectionStr))
                    {
                        connection.Open();
                        using (MySqlCommand sqlCommand = new MySqlCommand("SELECT DISTINCT playerid, value FROM balances", connection))
                        using (MySqlDataReader reader = sqlCommand.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                string playerId = reader.GetString(0);
                                double balance = reader.GetDouble(1);
                                _storedData.Balances.Add(playerId, balance);
                            }
                        }
                    }

                    // Check for and remove any inactive player balance data
                    foreach (string playerId in new List<string>(_storedData.Balances.Keys))
                    {
                        if (_storedData.Balances[playerId].Equals(_config.StartingBalance))
                        {
                            using (MySqlConnection connection = new MySqlConnection(_connectionStr))
                            {
                                connection.Open();
                                using (MySqlCommand sqlCommand = new MySqlCommand($"DELETE FROM balances WHERE playerid='{playerId}'", connection))
                                {
                                    sqlCommand.ExecuteNonQuery();
                                }
                            }
                        }
                    }
                    _storedData = new StoredData();
                }
            }

            _balanceLimits = new KeyValuePair<double, double>(_config.NegativeBalanceLimit, _config.BalanceLimit);
        }

        private bool CheckDatabase()
        {
            // Return true if database is empty or non-existent
            bool found = false;

            if (_config.UseSqLite)
            {
                using (SQLiteConnection connection = new SQLiteConnection(_connectionStr))
                {
                    connection.Open();
                    using (SQLiteCommand command = new SQLiteCommand("SELECT name FROM sqlite_master WHERE type='table' AND name='balances'", connection))
                    using (SQLiteDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            found = true;
                        }
                    }
                }

                if (!found)
                {
                    SQLiteCommand command = new SQLiteCommand("DROP TABLE IF EXISTS balances", _sqlConnection);
                    command.ExecuteNonQuery();
                    command = new SQLiteCommand("CREATE TABLE balances (playerid varchar(32) PRIMARY KEY, value DOUBLE DEFAULT 0)", _sqlConnection);
                    command.ExecuteNonQuery();
                    return true;
                }
            }
            else if (_config.UseMySql)
            {
                using (MySqlConnection connection = new MySqlConnection(_connectionStr))
                {
                    connection.Open();
                    using (MySqlCommand command = new MySqlCommand($"SELECT * FROM information_schema.tables WHERE table_schema='{_config.MySql.Database}' AND table_name='balances' LIMIT 1;", connection))
                    using (MySqlDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            found = true;
                        }
                    }
                }

                if (!found)
                {
                    MySqlCommand command = new MySqlCommand("DROP TABLE IF EXISTS balances", _mysqlConnection);
                    command.ExecuteNonQuery();
                    command = new MySqlCommand("CREATE TABLE balances (playerid varchar(32) PRIMARY KEY, value DOUBLE DEFAULT 0)", _mysqlConnection);
                    command.ExecuteNonQuery();
                    return true;
                }
            }

            return !found;
        }

        private void OnNewSave()
        {
            if (_config.WipeOnNewSave)
            {
                if (_config.UseSqLite)
                {
                    SQLiteCommand command = new SQLiteCommand("DROP TABLE IF EXISTS balances", _sqlConnection);
                    command.ExecuteNonQuery();
                    command = new SQLiteCommand("CREATE TABLE balances (playerid varchar(32) PRIMARY KEY, value DOUBLE DEFAULT 0)", _sqlConnection);
                    command.ExecuteNonQuery();
                }
                else if (_config.UseMySql)
                {
                    SQLiteCommand command = new SQLiteCommand("DROP TABLE IF EXISTS balances", _sqlConnection);
                    command.ExecuteNonQuery();
                    command = new SQLiteCommand("CREATE TABLE balances (playerid varchar(32) PRIMARY KEY, value DOUBLE DEFAULT 0)", _sqlConnection);
                    command.ExecuteNonQuery();
                }
                else
                {
                    _storedData.Balances.Clear();
                    _changed = true;
                }

                Interface.Call("OnEconomicsDataWiped");
            }
        }

        #endregion Initialization

        #region API Methods

        private double Balance(string playerId)
        {
            if (string.IsNullOrEmpty(playerId))
            {
                LogWarning("Balance method called without a valid player ID");
                return 0.0;
            }

            double balance = _config.StartingBalance;

            if (_config.UseSqLite)
            {
                using (SQLiteConnection connection = new SQLiteConnection(_connectionStr))
                {
                    connection.Open();
                    using (SQLiteCommand sqlCommand = new SQLiteCommand($"SELECT value FROM balances WHERE playerid='{playerId}'", connection))
                    using (SQLiteDataReader reader = sqlCommand.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            balance = reader.GetDouble(0);
                        }
                    }
                }
            }
            else if (_config.UseMySql)
            {
                using (MySqlConnection connection = new MySqlConnection(_connectionStr))
                {
                    connection.Open();
                    using (MySqlCommand sqlCommand = new MySqlCommand($"SELECT value FROM balances WHERE playerid='{playerId}'", connection))
                    using (MySqlDataReader reader = sqlCommand.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            balance = reader.GetDouble(0);
                        }
                    }
                }
            }
            else
            {
                _storedData.Balances.TryGetValue(playerId, out balance);
            }

            // TODO: Handle potential database read failure; check if balance changed or not
            return balance;
        }

        private double Balance(ulong playerId) => Balance(playerId.ToString());

        private KeyValuePair<double, double> BalanceLimits() => _balanceLimits;

        private bool Deposit(string playerId, double amount)
        {
            if (string.IsNullOrEmpty(playerId))
            {
                LogWarning("Deposit method called without a valid player ID");
                return false;
            }

            if (amount > 0 && SetBalance(playerId, amount + Balance(playerId)))
            {
                Interface.Call("OnEconomicsDeposit", playerId, amount);

                if (_config.LogTransactions)
                {
                    LogToFile("transactions", $"[{DateTime.Now}] {GetLang("LogDeposit", null, amount, playerId)}", this);
                }

                return true;
            }

            return false;
        }

        private bool Deposit(ulong playerId, double amount) => Deposit(playerId.ToString(), amount);

        private bool SetBalance(string playerId, double amount)
        {
            if (string.IsNullOrEmpty(playerId))
            {
                LogWarning("SetBalance method called without a valid player ID");
                return false;
            }

            amount = Math.Round(amount, 2);

            if (amount < 0 && _config.NegativeBalanceLimit == 0)
            {
                return false;
            }

            if (_config.BalanceLimit > 0 && amount > _config.BalanceLimit)
            {
                amount = _config.BalanceLimit;
            }
            else if (_config.NegativeBalanceLimit < 0 && amount < _config.NegativeBalanceLimit)
            {
                amount = _config.NegativeBalanceLimit;
            }

            double oldAmount = Balance(playerId);

            if (oldAmount > _config.StartingBalance)
            {
                if (_config.UseSqLite)
                {
                    using (SQLiteConnection connection = new SQLiteConnection(_connectionStr))
                    {
                        connection.Open();
                        //string query = $"UPDATE balances SET value={amount} WHERE playerid='{playerId}'";
                        //string query = $"INSERT INTO balances VALUES ('{playerId}', {amount})";
                        //string query = $"INSERT INTO balances (playerid, value) VALUES ('{playerId}', {amount})"
                        //    + "ON CONFLICT (playerid) DO UPDATE SET value=excluded.value";
                        string query = $"REPLACE INTO balances (playerid, value) VALUES('{playerId}', {amount})";
                        using (SQLiteCommand sqlCommand = new SQLiteCommand(query, connection))
                        {
                            sqlCommand.ExecuteNonQuery();
                        }
                    }
                }
                else if (_config.UseMySql)
                {
                    using (MySqlConnection connection = new MySqlConnection(_connectionStr))
                    {
                        connection.Open();
                        //string query = $"UPDATE balances SET value={amount} WHERE playerid='{playerId}'";
                        //string query = $"INSERT INTO balances VALUES ('{playerId}', {amount})";
                        //string query = $"INSERT INFO balances VALUES ('{playerId}', {amount})"
                        //    + $"ON DUPLICATE KEY UPDATE playerid='{playerId}', value={amount}";
                        string query = $"REPLACE INTO balances (playerid, value) VALUES('{playerId}', {amount})";
                        using (MySqlCommand sqlCommand = new MySqlCommand(query, connection))
                        {
                            sqlCommand.ExecuteNonQuery();
                        }
                    }
                }
                else
                {
                    if (_storedData.Balances.ContainsKey(playerId))
                    {
                        _storedData.Balances[playerId] = amount;
                    }
                    else
                    {
                        _storedData.Balances.Add(playerId, amount);
                    }
                    _changed = true;
                }

                Interface.Call("OnEconomicsBalanceUpdated", playerId, amount, oldAmount);
                Interface.CallDeprecatedHook("OnBalanceChanged", "OnEconomicsBalanceUpdated", new DateTime(2023, 1, 1), playerId, amount);

                if (_config.LogTransactions)
                {
                    LogToFile("transactions", $"[{DateTime.Now}] {GetLang("LogSetBalance", null, amount, playerId)}", this);
                }
            }

            return true;
        }

        private bool SetBalance(ulong playerId, double amount) => SetBalance(playerId.ToString(), amount);

        private bool Transfer(string playerId, string targetId, double amount)
        {
            if (string.IsNullOrEmpty(playerId))
            {
                LogWarning("Transfer method called without a valid player ID");
                return false;
            }

            if (Withdraw(playerId, amount) && Deposit(targetId, amount))
            {
                Interface.Call("OnEconomicsTransfer", playerId, targetId, amount);

                if (_config.LogTransactions)
                {
                    LogToFile("transactions", $"[{DateTime.Now}] {GetLang("LogTransfer", null, amount, targetId, playerId)}", this);
                }

                return true;
            }

            return false;
        }

        private bool Transfer(ulong playerId, ulong targetId, double amount)
        {
            return Transfer(playerId.ToString(), targetId.ToString(), amount);
        }

        private bool Withdraw(string playerId, double amount)
        {
            if (string.IsNullOrEmpty(playerId))
            {
                LogWarning("Withdraw method called without a valid player ID");
                return false;
            }

            double balance = Balance(playerId);
            if (amount >= 0 || balance <= _config.NegativeBalanceLimit && _config.NegativeBalanceLimit < 0)
            {
                if (balance >= amount && SetBalance(playerId, balance - amount) || _config.NegativeBalanceLimit <= balance - amount && SetBalance(playerId, balance - amount))
                {
                    Interface.Call("OnEconomicsWithdrawl", playerId, amount);

                    if (_config.LogTransactions)
                    {
                        LogToFile("transactions", $"[{DateTime.Now}] {GetLang("LogWithdrawl", null, amount, playerId)}", this);
                    }

                    return true;
                }
            }

            return false;
        }

        private bool Withdraw(ulong playerId, double amount) => Withdraw(playerId.ToString(), amount);

        #endregion API Methods

        #region Commands

        #region Balance Command

        private void CommandBalance(IPlayer player, string command, string[] args)
        {
            if (args != null && args.Length > 0)
            {
                if (!player.HasPermission(PermissionBalance))
                {
                    Message(player, "NotAllowed", command);
                    return;
                }

                IPlayer target = FindPlayer(args[0], player);
                if (target == null)
                {
                    Message(player, "UsageBalance", command);
                    return;
                }

                Message(player, "PlayerBalance", target.Name, Balance(target.Id));
                return;
            }

            if (player.IsServer)
            {
                Message(player, "UsageBalanceOthers", command);
            }
            else
            {
                Message(player, "YourBalance", Balance(player.Id));
            }
        }

        #endregion Balance Command

        #region Deposit Command

        private void CommandDeposit(IPlayer player, string command, string[] args)
        {
            if (!player.HasPermission(PermissionDeposit))
            {
                Message(player, "NotAllowed", command);
                return;
            }

            if (args == null || args.Length <= 1)
            {
                Message(player, "UsageDeposit", command);
                return;
            }

            double amount;
            double.TryParse(args[1], out amount);

            if (amount <= 0)
            {
                Message(player, "ZeroAmount");
                return;
            }

            if (args[0] == "*")
            {
                if (!player.HasPermission(PermissionDepositAll))
                {
                    Message(player, "NotAllowed", command);
                    return;
                }

                int receivers = 0;

                if (_config.UseSqLite)
                {
                    using (SQLiteConnection connection = new SQLiteConnection(_connectionStr))
                    {
                        connection.Open();
                        // TODO: INSERT OR UPDATE
                        string query = $"UPDATE balances SET value=value+{amount}";
                        using (SQLiteCommand sqlCommand = new SQLiteCommand(query, connection))
                        {
                            sqlCommand.ExecuteNonQuery();
                        }

                        using (SQLiteCommand sqlCommand = new SQLiteCommand("SELECT COUNT(*) FROM balances", connection))
                        using (SQLiteDataReader reader = sqlCommand.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                receivers = reader.GetInt32(0);
                            }
                        }
                    }
                }
                else if (_config.UseMySql)
                {
                    using (MySqlConnection connection = new MySqlConnection(_connectionStr))
                    {
                        connection.Open();
                        // TODO: INSERT OR UPDATE
                        string query = $"UPDATE balances SET value=value+{amount}";
                        using (MySqlCommand sqlCommand = new MySqlCommand(query, connection))
                        {
                            sqlCommand.ExecuteNonQuery();
                        }

                        using (MySqlCommand sqlCommand = new MySqlCommand("SELECT COUNT(*) FROM balances", connection))
                        using (MySqlDataReader reader = sqlCommand.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                receivers = reader.GetInt32(0);
                            }
                        }
                    }
                }
                else
                {
                    foreach (string targetId in _storedData.Balances.Keys.ToList())
                    {
                        if (Deposit(targetId, amount))
                        {
                            receivers++;
                        }
                    }
                }

                Message(player, "DepositedToAll", amount * receivers, amount, receivers);
            }
            else
            {
                IPlayer target = FindPlayer(args[0], player);
                if (target == null)
                {
                    return;
                }

                if (Deposit(target.Id, amount))
                {
                    Message(player, "PlayerBalance", target.Name, Balance(target.Id));
                }
                else
                {
                    Message(player, "TransactionFailed", target.Name);
                }
            }
        }

        #endregion Deposit Command

        #region Set Balance Command

        private void CommandSetBalance(IPlayer player, string command, string[] args)
        {
            if (!player.HasPermission(PermissionSetBalance))
            {
                Message(player, "NotAllowed", command);
                return;
            }

            if (args == null || args.Length <= 1)
            {
                Message(player, "UsageSetBalance", command);
                return;
            }

            double amount;
            double.TryParse(args[1], out amount);

            if (amount < 0)
            {
                Message(player, "NegativeBalance");
                return;
            }

            if (args[0] == "*")
            {
                if (!player.HasPermission(PermissionSetBalanceAll))
                {
                    Message(player, "NotAllowed", command);
                    return;
                }

                int receivers = 0;

                if (_config.UseSqLite)
                {
                    using (SQLiteConnection connection = new SQLiteConnection(_connectionStr))
                    {
                        connection.Open();
                        // TODO: INSERT OR UPDATE
                        string query = $"UPDATE balances SET value={amount}";
                        using (SQLiteCommand sqlCommand = new SQLiteCommand(query, connection))
                        {
                            sqlCommand.ExecuteNonQuery();
                        }

                        using (SQLiteCommand sqlCommand = new SQLiteCommand("SELECT COUNT(*) FROM balances", connection))
                        using (SQLiteDataReader reader = sqlCommand.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                receivers = reader.GetInt32(0);
                            }
                        }
                    }
                }
                else if (_config.UseMySql)
                {
                    using (MySqlConnection connection = new MySqlConnection(_connectionStr))
                    {
                        connection.Open();
                        // TODO: INSERT OR UPDATE
                        string query = $"UPDATE balances SET value={amount}";
                        using (MySqlCommand sqlCommand = new MySqlCommand(query, connection))
                        {
                            sqlCommand.ExecuteNonQuery();
                        }

                        using (MySqlCommand sqlCommand = new MySqlCommand("SELECT COUNT(*) FROM balances", connection))
                        using (MySqlDataReader reader = sqlCommand.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                receivers = reader.GetInt32(0);
                            }
                        }
                    }
                }
                else
                {
                    foreach (string targetId in _storedData.Balances.Keys.ToList())
                    {
                        if (SetBalance(targetId, amount))
                        {
                            receivers++;
                        }
                    }
                }

                Message(player, "SetBalanceForAll", amount, receivers);
            }
            else
            {
                IPlayer target = FindPlayer(args[0], player);
                if (target == null)
                {
                    return;
                }

                if (SetBalance(target.Id, amount))
                {
                    Message(player, "PlayerBalance", target.Name, Balance(target.Id));
                }
                else
                {
                    Message(player, "TransactionFailed", target.Name);
                }
            }
        }

        #endregion Set Balance Command

        #region Transfer Command

        private void CommandTransfer(IPlayer player, string command, string[] args)
        {
            if (!player.HasPermission(PermissionTransfer))
            {
                Message(player, "NotAllowed", command);
                return;
            }

            if (args == null || args.Length <= 1)
            {
                Message(player, "UsageTransfer", command);
                return;
            }

            double amount;
            double.TryParse(args[1], out amount);

            if (amount <= 0)
            {
                Message(player, "ZeroAmount");
                return;
            }

            if (args[0] == "*")
            {
                if (!player.HasPermission(PermissionTransferAll))
                {
                    Message(player, "NotAllowed", command);
                    return;
                }

                if (!Withdraw(player.Id, amount))
                {
                    Message(player, "YouLackMoney");
                    return;
                }

                int receivers = players.Connected.Count();
                double splitAmount = amount /= receivers;

                foreach (IPlayer target in players.Connected)
                {
                    if (Deposit(target.Id, splitAmount))
                    {
                        if (target.IsConnected)
                        {
                            Message(target, "ReceivedFrom", splitAmount, player.Name);
                        }
                    }
                }
                Message(player, "TransferedToAll", amount, splitAmount, receivers);
            }
            else
            {
                IPlayer target = FindPlayer(args[0], player);
                if (target == null)
                {
                    return;
                }

                if (target.Equals(player))
                {
                    Message(player, "TransferToSelf");
                    return;
                }

                if (!Withdraw(player.Id, amount))
                {
                    Message(player, "YouLackMoney");
                    return;
                }

                if (Deposit(target.Id, amount))
                {
                    Message(player, "TransferredTo", amount, target.Name);
                    Message(target, "ReceivedFrom", amount, player.Name);
                }
                else
                {
                    Message(player, "TransactionFailed", target.Name);
                }
            }
        }

        #endregion Transfer Command

        #region Withdraw Command

        private void CommandWithdraw(IPlayer player, string command, string[] args)
        {
            if (!player.HasPermission(PermissionWithdraw))
            {
                Message(player, "NotAllowed", command);
                return;
            }

            if (args == null || args.Length <= 1)
            {
                Message(player, "UsageWithdraw", command);
                return;
            }

            double amount;
            double.TryParse(args[1], out amount);

            if (amount <= 0)
            {
                Message(player, "ZeroAmount");
                return;
            }

            if (args[0] == "*")
            {
                if (!player.HasPermission(PermissionWithdrawAll))
                {
                    Message(player, "NotAllowed", command);
                    return;
                }

                int receivers = 0;

                if (_config.UseSqLite)
                {
                    using (SQLiteConnection connection = new SQLiteConnection(_connectionStr))
                    {
                        connection.Open();
                        // TODO: INSERT OR UPDATE
                        string query = $"UPDATE balances SET value=value-{amount}";
                        using (SQLiteCommand sqlCommand = new SQLiteCommand(query, connection))
                        {
                            sqlCommand.ExecuteNonQuery();
                        }

                        using (SQLiteCommand sqlCommand = new SQLiteCommand("SELECT COUNT(*) FROM balances", connection))
                        using (SQLiteDataReader reader = sqlCommand.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                receivers = reader.GetInt32(0);
                            }
                        }
                    }
                }
                else if (_config.UseMySql)
                {
                    using (MySqlConnection connection = new MySqlConnection(_connectionStr))
                    {
                        connection.Open();
                        // TODO: INSERT OR UPDATE
                        string query = $"UPDATE balances SET value=value-{amount}";
                        using (MySqlCommand sqlCommand = new MySqlCommand(query, connection))
                        {
                            sqlCommand.ExecuteNonQuery();
                        }

                        using (MySqlCommand sqlCommand = new MySqlCommand("SELECT COUNT(*) FROM balances", connection))
                        using (MySqlDataReader reader = sqlCommand.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                receivers = reader.GetInt32(0);
                            }
                        }
                    }
                }
                else
                {
                    foreach (string targetId in _storedData.Balances.Keys.ToList())
                    {
                        if (Withdraw(targetId, amount))
                        {
                            receivers++;
                        }
                    }
                }

                Message(player, "WithdrawnForAll", amount * receivers, amount, receivers);
            }
            else
            {
                IPlayer target = FindPlayer(args[0], player);
                if (target == null)
                {
                    return;
                }

                if (Withdraw(target.Id, amount))
                {
                    Message(player, "PlayerBalance", target.Name, Balance(target.Id));
                }
                else
                {
                    Message(player, "YouLackMoney", target.Name);
                }
            }
        }

        #endregion Withdraw Command

        #region Wipe Command

        private void CommandWipe(IPlayer player, string command, string[] args)
        {
            if (!player.HasPermission(PermissionWipe))
            {
                Message(player, "NotAllowed", command);
                return;
            }

            if (_config.UseSqLite)
            {
                using (SQLiteConnection connection = new SQLiteConnection(_connectionStr))
                {
                    connection.Open();
                    using (SQLiteCommand sqlCommand = new SQLiteCommand("DELETE FROM balances", connection))
                    {
                        sqlCommand.ExecuteNonQuery();
                    }
                }
            }
            else if (_config.UseMySql)
            {
                using (MySqlConnection connection = new MySqlConnection(_connectionStr))
                {
                    connection.Open();
                    using (MySqlCommand sqlCommand = new MySqlCommand("DELETE FROM balances", connection))
                    {
                        sqlCommand.ExecuteNonQuery();
                    }
                }
            }
            else
            {
                _storedData = new StoredData();
                _changed = true;
                SaveData();
            }

            Message(player, "DataWiped");
            Interface.Call("OnEconomicsDataWiped", player);
        }

        #endregion Wipe Command

        #endregion Commands

        #region Helpers

        private void AddLocalizedCommand(string command)
        {
            foreach (string language in lang.GetLanguages(this))
            {
                foreach (KeyValuePair<string, string> message in lang.GetMessages(language, this))
                {
                    if (message.Key.Equals(command) && !string.IsNullOrEmpty(message.Value))
                    {
                        AddCovalenceCommand(message.Value, command);
                    }
                }
            }
        }

        private IPlayer FindPlayer(string playerNameOrId, IPlayer player)
        {
            IPlayer[] foundPlayers = players.FindPlayers(playerNameOrId).ToArray();
            if (foundPlayers.Length > 1)
            {
                Message(player, "PlayersFound", string.Join(", ", foundPlayers.Select(p => p.Name).Take(10).ToArray()).Truncate(60));
                return null;
            }

            IPlayer target = foundPlayers.Length == 1 ? foundPlayers[0] : null;
            if (target == null)
            {
                Message(player, "NoPlayersFound", playerNameOrId);
                return null;
            }

            return target;
        }

        private string GetLang(string langKey, string playerId = null, params object[] args)
        {
            return string.Format(lang.GetMessage(langKey, this, playerId), args);
        }

        private void Message(IPlayer player, string textOrLang, params object[] args)
        {
            if (player.IsConnected)
            {
                string message = GetLang(textOrLang, player.Id, args);
                player.Reply(message != textOrLang ? message : textOrLang);
            }
        }

        #endregion Helpers
    }
}

#region Extension Methods

namespace Oxide.Plugins.EconomicsExtensionMethods
{
    public static class ExtensionMethods
    {
        public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>
        {
            if (val.CompareTo(min) < 0)
            {
                return min;
            }

            if (val.CompareTo(max) > 0)
            {
                return max;
            }

            return val;
        }
    }
}

#endregion Extension Methods

 

Link to comment
Share on other sites

Hi, set this line to true:

from:
[JsonProperty("Store data in MySQL instead of data files")] public bool UseMySql = false;

to:
[JsonProperty("Store data in MySQL instead of data files")] public bool UseMySql = true;

Link to comment
Share on other sites

On 6/27/2023 at 7:16 AM, laodu said:

I have set it to true, but the player's economic data will not be added to the SQL database. And economics cannot be used either.

1. Make sure you have it set to true both in .cs file and .json
2. Make sure the database credentials are correct and it's creating tables. 
3. If you have an external database location than the VPS/VDS, check if the MySQL port 3306 is open for external connections.

Try to check the oxide logs and see if there's any error related to Economics.
As a last resort, we can investigate the issue for you and make the changes you want if needed.


Best regards,
Holoxy Solutions

Link to comment
Share on other sites

All settings, including the SQL database, are correct, and it is possible to connect to the SQL database and create basic tables. The real problem is that players cannot add or reduce new playback data, including economics, when using it

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
1.1m

Downloads

Total number of downloads.

5.7k

Customers

Total customers served.

83.5k

Files Sold

Total number of files sold.

1.6m

Payments Processed

Total payments processed.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.