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

FREE BanSync : 0.1 0.1

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Oxide.Core;
using Oxide.Core.Plugins;
// Reference: Oxide.Core.MySql
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using UnityEngine;
using Connection = Oxide.Core.Database.Connection;

namespace Oxide.Plugins
{
    [Info("BanSync", "Jake_Rich", 0.1)]
    [Description("Syncs bans across servers")]
    class BanSync : RustPlugin
    {
        //Make sure table is setup   | steamid | name | reason |


        public class MySqlConstants
        {
            //public static string ADD_BAN_TO_DATABASE = "INSERT IGNORE INTO `{0}`.`{1}` (`steamid`, `name`, `reason`) VALUES {2}";
            public static string ADD_BAN_TO_DATABASE = "INSERT INTO `{0}`.`{1}` (`steamid`, `name`, `reason`) VALUES {2} ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `reason` = VALUES(`reason`)";
            public static string SELECT_ALL_BANS = "SELECT * FROM `{0}`.`{1}`";
            //public static string ADD_UNBAN = "INSERT IGNORE INTO `{0}`.`{1}` (`steamid`, `name`, `reason`) VALUES {2}";
            public static string REMOVE_BAN = "DELETE FROM `{0}`.`{1}` WHERE `steamid` = '{2}'";
        }

        public Timer _syncTimer { get; set; }
        public static BanSync _plugin { get; set; }
        public bool Initialized { get; set; }
        #region Hooks

        void OnServerInitialized()
        {
            Settings = new ConfigurationAccessor<BanConfig>("BanSync-Config");
            if (Settings.Instance.DatabaseServerIP == "")
            {
                Puts("Please enter the database's IP in oxide/data/BanSync-Config.data");
                return;
            }
            if (Settings.Instance.DatabaseUserName == "")
            {
                Puts("Please enter the database username in oxide/data/BanSync-Config.data");
                return;
            }
            if (Settings.Instance.DatabaseName == "")
            {
                Puts("Please enter the ban database's name in oxide/data/BanSync-Config.data");
                return;
            }
            if (Settings.Instance.TableName == "")
            {
                Puts("Please enter the ban table's name in oxide/data/BanSync-Config.data");
                return;
            }

            SyncBans();
            _syncTimer?.Destroy();
            _syncTimer = timer.Every(60f, SyncBans);
            Initialized = true;
        }

        void OnServerCommand(ConsoleSystem.Arg args)
        {
            if (!Initialized)
            {
                return;
            }
            if (!args.IsAdmin)
            {
                return;
            }
            if (args.cmd == null)
            {
                return;
            }
            switch(args.cmd.Name)
            {
                case "banid":
                    {
                        BanID(args);
                        break;
                    }
                case "unban":
                    {
                        Unban(args);
                        break;
                    }
            }
        }

        void Init()
        {
            _plugin = this;
        }

        void Unload()
        {
            _syncTimer?.Destroy();
        }

        #endregion

        public ConfigurationAccessor<BanConfig> Settings { get; set; }

        public List<PlayerBan> UnnamedBans { get; set; } = new List<PlayerBan>();
        public List<PlayerBan> BansToSend { get; set; } = new List<PlayerBan>();

        #region Configuration classes

        public class ConfigurationAccessor<Type> where Type : class
        {
            #region Typed Configuration Accessors

            private Type GetTypedConfigurationModel(string storageName)
            {
                return Interface.Oxide.DataFileSystem.ReadObject<Type>(storageName);
            }

            private void SaveTypedConfigurationModel(string storageName, Type storageModel)
            {
                Interface.Oxide.DataFileSystem.WriteObject(storageName, storageModel);
            }

            #endregion

            private string name { get; set; }
            public Type Instance { get; set; }

            public ConfigurationAccessor(string name)
            {
                this.name = name;
                Init();
                Reload();
            }

            public virtual void Init()
            {

            }

            public void Load()
            {
                Instance = GetTypedConfigurationModel(name);
            }

            public void Save()
            {
                SaveTypedConfigurationModel(name, Instance);
            }

            public void Reload()
            {
                Load(); //Need to load and save to init list
                Save();
                Load();
            }
        }

        #endregion

        #region SteamAPI

        public class SteamAlias_Ajax
        {
            public string newname { get; set; }
            public string timechanged { get; set; }
            public DateTime lastChange { get { return DateTime.Parse(timechanged); } }
        }

        public const string SteamAPI_PastUsernameFormat = "http://steamcommunity.com/profiles/{0}/ajaxaliases";

        #endregion

        public class BanConfig
        {
            public string DatabaseServerIP = ""; //Database IP address
            public int DatabaseServerPort = 3306; //Usually defaults to 3306
            public string DatabaseUserName = ""; //Username of SQL user
            public string DatabasePassword = ""; //Password of SQL user
            public string DatabaseName = ""; //Database Name
            public string TableName = "";
            public string UnbanTableName = "";

            public bool PushedAllLocalBansToDatabase = false;

            public Dictionary<ulong,PlayerBan> databaseBans { get; set; } = new Dictionary<ulong, PlayerBan>();
        }

        public class PlayerBan
        {
            public ulong SteamID { get; set; } = 0;
            public string Username { get; set; } = "";
            public string Reason { get; set; } = "";

            public PlayerBan(ulong steamid, string reason, string username = "")
            {
                SteamID = steamid;
                Reason = reason;
                if (username == "")
                {
                    GetUsername();
                }
            }

            public PlayerBan(ServerUsers.User user)
            {
                SteamID = user.steamid;
                Username = user.username;
                Reason = user.notes;
            }

            public PlayerBan()
            {

            }

            public void GetUsername()
            {
                
                _plugin.webrequest.EnqueueGet(string.Format(SteamAPI_PastUsernameFormat, SteamID), (code, response) =>
                {
                    if (code == 200)
                    {
                        List<SteamAlias_Ajax> lastNames;
                        try
                        {
                            lastNames = JsonConvert.DeserializeObject<List<SteamAlias_Ajax>>(response);
                        }
                        catch
                        {
                            //_plugin.Puts("Failed to parse JSON GetUsername()");
                            Username = "Invalid_SteamID";
                            return;
                        }
                        if (lastNames.Count == 0)
                        {
                            //_plugin.Puts($"GetUsername() returned no usernames for {SteamID}!");
                            Username = "No_Aliases";
                            return;
                        }
                        Username = lastNames.First().newname;
                        var user = ServerUsers.Get(SteamID);
                        if (user != null)
                        {
                            user.username = Username;
                        }
                    }
                    else
                    {
                        _plugin.Puts($"GetUsername() error code: {code}");
                    }
                }, _plugin, null, 60);
            }
        }

        private void SyncBans()
        {
            if (!Settings.Instance.PushedAllLocalBansToDatabase)
            {
                Puts($"Please use \"pushbans\" to sync the database with this server.");
                return;
            }

            PullBansFromServer();
        }

        private void PushBansToServer()
        {
            var bans = new List<PlayerBan>(BansToSend);
            bans.AddRange(UnnamedBans.Where(x => UsernameValid(x)));
            UnnamedBans.RemoveAll(x => UsernameValid(x));
            bans.AddRange(ServerUsers.GetAll(ServerUsers.UserGroup.Banned).Where(x => !Settings.Instance.databaseBans.ContainsKey(x.steamid)).Select(x => new PlayerBan(x)));
            if (bans.Count() <= 0)
            {
                Puts("All bans have been synced with the database.");
                return;
            }
            var query = string.Format(MySqlConstants.ADD_BAN_TO_DATABASE, Settings.Instance.DatabaseName, Settings.Instance.TableName,
                string.Join(",", bans.Select(x => $"('{x.SteamID}','{x.Username}','{x.Reason.Replace(";", "").Replace("'", "")}')").ToArray())
            );
            Puts(query);
            try
            {
                PerformDatabaseQuery(query, (responseRows) =>
                {
                    Settings.Instance.PushedAllLocalBansToDatabase = true;
                    Puts($"Bans pushed to the database");
                });
            }
            catch
            {
                Puts("PushBansToServer() SQL Query failed!");
                Puts(query);
                timer.In(10f, ()=>
                {
                    PushBansToServer();
                });
            }
            Puts($"Started to send {bans.Count()} bans to database!");
        }

        private void UpdateDatabaseUsernames()
        {
            var usersToSend = UnnamedBans.Where(x => UsernameValid(x));
            UnnamedBans.RemoveAll(x => UsernameValid(x));
            if (usersToSend.Count() <= 0)
            {
                Puts("UpdateDatabaseUsernames() no users ready to update!");
                return;
            }
            var query = string.Format(MySqlConstants.ADD_BAN_TO_DATABASE, Settings.Instance.DatabaseName, Settings.Instance.TableName,
                string.Join(",", usersToSend.Select(x => $"('{x.SteamID}','{x.Username}','{x.Reason.Replace(";", "").Replace("'", "")}')").ToArray())
            );
            try
            {
                PerformDatabaseQuery(query, (responseRows) =>
                {

                });
            }
            catch
            {
                Puts("PushBansToServer() SQL Query failed!");
                Puts(query);
                timer.In(10f, UpdateDatabaseUsernames);
            }
            Puts($"Updated {usersToSend.Count()} usernames in the database!");
        }

        private void PullBansFromServer()
        {
            var query = string.Format(MySqlConstants.SELECT_ALL_BANS, Settings.Instance.DatabaseName, Settings.Instance.TableName);

            PerformDatabaseQuery(query, (responseRows) =>
            {
                if (responseRows == null)
                {
                    return;
                }

                HashSet<ulong> localBans = new HashSet<ulong>(ServerUsers.GetAll(ServerUsers.UserGroup.Banned).Select(x => x.steamid));

                Settings.Instance.databaseBans.Clear();

                if (responseRows.Any())
                {
                    //Add all database bans to local file
                    foreach (var row in responseRows)
                    {
                        var playerID = row["steamid"].ToString();

                        if (string.IsNullOrEmpty(playerID))
                        {
                            continue;
                        }

                        ulong steamID;
                        if (!ulong.TryParse(playerID, out steamID))
                        {
                            return;
                        }

                        var username = row["name"].ToString();
                        var reason = row["reason"].ToString();

                        Settings.Instance.databaseBans.Add(steamID, new PlayerBan(steamID, reason));

                        if (!UsernameValid(steamID, username))
                        {
                            UnnamedBans.Add(new PlayerBan(steamID, reason));
                        }

                        if (localBans.Remove(steamID)) //No need to reban people
                        {
                            continue;
                        }

                        ServerUsers.Set(steamID, ServerUsers.UserGroup.Banned, playerID, reason);

                        BasePlayer player = BasePlayer.FindByID(steamID);

                        if (player != null)
                        {
                            player.Kick("Bans share across servers :)");
                        }
                    }

                    //Dont want to delete local ban list accidently
                    foreach (var player in localBans) //Unban users who aren't found on the database
                    {
                        ServerUsers.Remove(player);
                    }

                    if (UnnamedBans.Count > 0)
                    {
                        timer.In(10f, UpdateDatabaseUsernames);
                    }

                    Puts($"Updated ban list - {responseRows.Count} bans pulled from database");

                    Settings.Save();
                }
            });
        }

        private void Unban(ConsoleSystem.Arg args)
        {
            ulong steamID = args.GetUInt64(0, 0uL);
            if (steamID < 70000000000000000uL)
            {
                return;
            }
            var query = string.Format(MySqlConstants.REMOVE_BAN, Settings.Instance.DatabaseName, Settings.Instance.TableName, steamID);

            PerformDatabaseQuery(query, (responseRows) =>
            {

            });
        }

        private void BanID(ConsoleSystem.Arg args)
        {
            ulong steamID = args.GetUInt64(0, 0uL);
            string name = args.GetString(1, "unnamed");
            string reason = args.GetString(2, "no reason");

            if (steamID == 0)
            {
                return;
            }

            var user = ServerUsers.Get(steamID);
            if (user != null)
            {
                if (UsernameValid(steamID, name))
                {
                    name = user.username;
                }
            }
            user.group = ServerUsers.UserGroup.Banned;

            if (Settings.Instance.PushedAllLocalBansToDatabase)
            {
                PushBansToServer();
            }
        }

        private void Ban(ConsoleSystem.Arg args)
        {
            BasePlayer player = args.GetPlayer(0);
            if (player == null || player.net == null)
            {
                return;
            }

            string name = args.GetString(1, "unnamed");
            string reason = args.GetString(2, "no reason");

            var user = ServerUsers.Get(player.userID);
            if (user != null)
            {
                if (UsernameValid(player.userID, name))
                {
                    name = user.username;
                }
            }
            user.group = ServerUsers.UserGroup.Banned;

            if (Settings.Instance.PushedAllLocalBansToDatabase)
            {
                PushBansToServer();
            }
        }

        private bool UsernameValid(ulong steamID, string name)
        {
            return !(string.IsNullOrEmpty(name) || name.ToLower() == "unnamed" || name == steamID.ToString());
        }

        private bool UsernameValid(PlayerBan ban)
        {
            return UsernameValid(ban.SteamID, ban.Username);
        }

        private bool UsernameValid(ServerUsers.User user)
        {
            return UsernameValid(user.steamid, user.username);
        }

        [ConsoleCommand("pushbans")]
        void PushBansCmd(ConsoleSystem.Arg args)
        {
            if (!args.IsAdmin)
            {
                return;
            }
            PushBansToServer();
            Settings.Instance.PushedAllLocalBansToDatabase = true;
            _syncTimer?.Destroy();
            _syncTimer = timer.Every(60f, SyncBans);
            Initialized = true;
        }

        //MySQL stuff in C# by audi / i_love_code
        #region This stuff should not be edited.This is the guts.private readonly Core.MySql.Libraries.MySql _mySql = Interface.GetMod().GetLibrary<Core.MySql.Libraries.MySql>();

        private void PerformDatabaseQuery(string dbStatement, Action<List<Dictionary<string, object>>> callbackAction,
            Connection optionalConnection = null, params object[] sqlQueryArguments)
        {
            var sqlConnection = optionalConnection ?? GetSqlConnection();

            var query = _mySql.NewSql().Append(dbStatement, sqlQueryArguments);

            _mySql.Query(query, sqlConnection, callbackAction);

            CloseConnection(sqlConnection);
        }

        private void PerformDatabaseInsert(string dbStatement, Action<int> callbackAction,
            Connection optionalConnection = null, params object[] sqlQueryArguments)
        {
            var sqlConnection = optionalConnection ?? GetSqlConnection();

            var query = _mySql.NewSql().Append(dbStatement, sqlQueryArguments);

            _mySql.Insert(query, sqlConnection, callbackAction);

            CloseConnection(sqlConnection);
        }

        private void PerformDatabaseUpdate(string dbStatement, Action<int> callbackAction,
            Connection optionalConnection = null, params object[] sqlQueryArguments)
        {
            var sqlConnection = optionalConnection ?? GetSqlConnection();

            var query = _mySql.NewSql().Append(dbStatement, sqlQueryArguments);

            _mySql.Update(query, sqlConnection, callbackAction);

            CloseConnection(sqlConnection);
        }

        private void CloseConnection(Connection sqlConnection)
        {
            _mySql.CloseDb(sqlConnection);
        }

        private Connection GetSqlConnection()
        {
            return _mySql.OpenDb(Settings.Instance.DatabaseServerIP, Settings.Instance.DatabaseServerPort,
                Settings.Instance.DatabaseName, Settings.Instance.DatabaseUserName, Settings.Instance.DatabasePassword,
                this);
        }

        #endregion
    }
}

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