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

FREE GroupWebSync : 1.3.1 1.3.1

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Database;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;

namespace Oxide.Plugins
{
    [Info("Group Web Sync", "Orangemart", "1.3.1")]
    [Description("Syncs Oxide groups, player rewards, Discord linkages, and scrap leaderboards to a central MySQL database")]
    public class GroupWebSync : CovalencePlugin
    {
        private Configuration _config;
        private readonly Oxide.Core.MySql.Libraries.MySql _mySql = Interface.Oxide.GetLibrary<Oxide.Core.MySql.Libraries.MySql>();
        private Oxide.Core.Database.Connection _dbConnection;

        [PluginReference]
        private Plugin ScrapLeaderboard;

        #region Configuration
        private class Configuration
        {
            [JsonProperty("Server Identifier (e.g., orange or mandarin)")]
            public string ServerName = "orange";

            [JsonProperty("MySQL Host IP")]
            public string Host = "127.0.0.1";

            [JsonProperty("MySQL Port")]
            public int Port = 3306;

            [JsonProperty("MySQL Database Name")]
            public string Database = "rust_server";

            [JsonProperty("MySQL Username")]
            public string Username = "username";

            [JsonProperty("MySQL Password")]
            public string Password = "password";
        }

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

        protected override void LoadDefaultConfig() => _config = new Configuration();
        protected override void SaveConfig() => Config.WriteObject(_config);
        #endregion

        #region Initialization & Database
        private void OnServerInitialized()
        {
            if (_mySql == null)
            {
                PrintError("MySQL library not found! Is the Oxide.Ext.MySql extension installed?");
                return;
            }

            try
            {
                _dbConnection = _mySql.OpenDb(_config.Host, _config.Port, _config.Database, _config.Username, _config.Password, this);
                
                // Existing User Groups Table
                Sql groupSql = Sql.Builder.Append(@"CREATE TABLE IF NOT EXISTS user_groups (
                                                steam_id VARCHAR(50) NOT NULL,
                                                group_name VARCHAR(50) NOT NULL,
                                                PRIMARY KEY (steam_id, group_name)
                                              );");
                
                // New Player Rewards Table
                Sql rewardSql = Sql.Builder.Append(@"CREATE TABLE IF NOT EXISTS player_rewards (
                                                steam_id VARCHAR(50) NOT NULL,
                                                server_name VARCHAR(50) NOT NULL,
                                                total_amount BIGINT NOT NULL,
                                                PRIMARY KEY (steam_id, server_name)
                                              );");

                // New Player Discord Mappings Table
                Sql discordSql = Sql.Builder.Append(@"CREATE TABLE IF NOT EXISTS player_discord (
                                                steam_id VARCHAR(50) NOT NULL PRIMARY KEY,
                                                discord_id VARCHAR(50) NOT NULL
                                              );");

                // New Scrap Leaderboard Table
                Sql scrapSql = Sql.Builder.Append(@"CREATE TABLE IF NOT EXISTS player_scrap (
                                                steam_id VARCHAR(50) NOT NULL,
                                                server_name VARCHAR(50) NOT NULL,
                                                total_deposited INT NOT NULL,
                                                PRIMARY KEY (steam_id, server_name)
                                              );");
                
                _mySql.ExecuteNonQuery(groupSql, _dbConnection, delegate(int rows) { });
                _mySql.ExecuteNonQuery(rewardSql, _dbConnection, delegate(int rows) { });
                _mySql.ExecuteNonQuery(scrapSql, _dbConnection, delegate(int rows) { });
                _mySql.ExecuteNonQuery(discordSql, _dbConnection, delegate(int rows) 
                {
                    Puts("Successfully connected to MySQL and verified database structures.");
                    SyncDiscordLinks();
                    
                    // Sync scrap totals initially, then every 5 minutes (300 seconds)
                    timer.Once(10f, () => SyncScrapTotals());
                    timer.Every(300f, () => SyncScrapTotals());
                });
            }
            catch (Exception ex)
            {
                PrintError($"Failed to connect to MySQL: {ex.Message}");
            }
        }

        private void Unload()
        {
            if (_dbConnection != null)
            {
                _mySql.CloseDb(_dbConnection);
            }
        }

        private void OnServerSave()
        {
            SyncScrapTotals();
        }
        #endregion

        #region Group Sync Hooks & Commands
        [HookMethod("OnUserGroupAdded")]
        private void OnUserGroupAdded(string id, string groupName)
        {
            if (_dbConnection == null) return;
            Sql sql = Sql.Builder.Append("REPLACE INTO user_groups (steam_id, group_name) VALUES (@0, @1);", id, groupName);
            _mySql.Insert(sql, _dbConnection, delegate(int rows) { });
        }

        [HookMethod("OnUserGroupRemoved")]
        private void OnUserGroupRemoved(string id, string groupName)
        {
            if (_dbConnection == null) return;
            Sql sql = Sql.Builder.Append("DELETE FROM user_groups WHERE steam_id = @0 AND group_name = @1;", id, groupName);
            _mySql.Delete(sql, _dbConnection, delegate(int rows) { });
        }

        [Command("groupsync.force")]
        private void ForceGroupSyncCommand(IPlayer player, string command, string[] args)
        {
            if (!player.IsAdmin) return;

            int count = 0;
            string[] allGroups = permission.GetGroups();

            foreach (string group in allGroups)
            {
                string[] usersInGroup = permission.GetUsersInGroup(group);
                foreach (string userId in usersInGroup)
                {
                    Sql sql = Sql.Builder.Append("REPLACE INTO user_groups (steam_id, group_name) VALUES (@0, @1);", userId, group);
                    _mySql.Insert(sql, _dbConnection, delegate(int rows) { });
                    count++;
                }
            }

            player.Reply($"Queued {count} group assignments for asynchronous sync to MySQL.");
        }
        #endregion

        #region Reward Sync Logic
        // Data classes to match ClaimedRewards.json structure
        private class RewardData
        {
            [JsonProperty("claims")]
            public List<ClaimEntry> Claims = new List<ClaimEntry>();
        }

        private class ClaimEntry
        {
            [JsonProperty("steamid")]
            public string SteamId { get; set; }
            
            [JsonProperty("amount_claimed")]
            public long AmountClaimed { get; set; }
        }

        [Command("rewardsync.force")]
        private void ForceRewardSyncCommand(IPlayer player, string command, string[] args)
        {
            if (!player.IsAdmin) return;
            if (_dbConnection == null) return;

            // Read the JSON file from /oxide/data/ClaimPlayerRewards/ClaimedRewards.json
            var data = Interface.Oxide.DataFileSystem.ReadObject<RewardData>("ClaimPlayerRewards/ClaimedRewards");

            if (data == null || data.Claims == null || data.Claims.Count == 0)
            {
                player.Reply("No rewards found in ClaimedRewards.json to sync.");
                return;
            }

            // Aggregate multiple claims per SteamID into a single total
            Dictionary<string, long> aggregatedRewards = new Dictionary<string, long>();
            foreach (var claim in data.Claims)
            {
                if (string.IsNullOrEmpty(claim.SteamId)) continue;

                if (aggregatedRewards.ContainsKey(claim.SteamId))
                {
                    aggregatedRewards[claim.SteamId] += claim.AmountClaimed;
                }
                else
                {
                    aggregatedRewards[claim.SteamId] = claim.AmountClaimed;
                }
            }

            int count = 0;
            foreach (var kvp in aggregatedRewards)
            {
                // Push the aggregated total to MySQL along with the specific server name
                Sql sql = Sql.Builder.Append("REPLACE INTO player_rewards (steam_id, server_name, total_amount) VALUES (@0, @1, @2);", kvp.Key, _config.ServerName, kvp.Value);
                _mySql.Insert(sql, _dbConnection, delegate(int rows) { });
                count++;
            }

            player.Reply($"Aggregated and queued {count} player reward totals for asynchronous sync to MySQL.");
        }
        #endregion

        #region Discord Sync Logic
        private class DiscordAuthData
        {
            [JsonProperty("Players")]
            public Dictionary<string, string> Players = new Dictionary<string, string>();
        }

        private void SyncDiscordLinks()
        {
            if (_dbConnection == null) return;

            try
            {
                // Read the JSON file from /oxide/data/DiscordAuth.json
                var data = Interface.Oxide.DataFileSystem.ReadObject<DiscordAuthData>("DiscordAuth");
                if (data == null || data.Players == null || data.Players.Count == 0)
                {
                    Puts("No Discord authentication links found in DiscordAuth.json to sync.");
                    return;
                }

                int count = 0;
                foreach (var kvp in data.Players)
                {
                    if (string.IsNullOrEmpty(kvp.Key) || string.IsNullOrEmpty(kvp.Value)) continue;

                    Sql sql = Sql.Builder.Append("REPLACE INTO player_discord (steam_id, discord_id) VALUES (@0, @1);", kvp.Key, kvp.Value);
                    _mySql.Insert(sql, _dbConnection, delegate(int rows) { });
                    count++;
                }

                Puts($"Successfully synced {count} Discord linkages from DiscordAuth.json to MySQL.");
            }
            catch (Exception ex)
            {
                PrintError($"Failed to sync Discord links: {ex.Message}");
            }
        }

        [Command("discordsync.force")]
        private void ForceDiscordSyncCommand(IPlayer player, string command, string[] args)
        {
            if (!player.IsAdmin) return;
            if (_dbConnection == null)
            {
                player.Reply("Database connection is offline.");
                return;
            }

            SyncDiscordLinks();
            player.Reply("Triggered manual sync of Discord linkages from DiscordAuth.json to MySQL.");
        }
        #endregion

        #region Scrap Sync Logic
        private void SyncScrapTotals()
        {
            if (_dbConnection == null) return;
            if (ScrapLeaderboard == null || !ScrapLeaderboard.IsLoaded)
            {
                Puts("ScrapLeaderboard plugin is not loaded.Skipping scrap sync.");
                return;
            }

            var cache = ScrapLeaderboard.Call("GetPlayerTotalsCache") as Dictionary<string, int>;
            if (cache == null || cache.Count == 0)
            {
                Puts("No scrap deposits found in ScrapLeaderboard to sync.");
                return;
            }

            int count = 0;
            foreach (var kvp in cache)
            {
                if (string.IsNullOrEmpty(kvp.Key)) continue;

                Sql sql = Sql.Builder.Append("REPLACE INTO player_scrap (steam_id, server_name, total_deposited) VALUES (@0, @1, @2);", kvp.Key, _config.ServerName, kvp.Value);
                _mySql.Insert(sql, _dbConnection, delegate(int rows) { });
                count++;
            }

            Puts($"Successfully synced {count} scrap deposit totals to MySQL.");
        }

        [Command("scrapsync.force")]
        private void ForceScrapSyncCommand(IPlayer player, string command, string[] args)
        {
            if (!player.IsAdmin) return;
            if (_dbConnection == null)
            {
                player.Reply("Database connection is offline.");
                return;
            }

            SyncScrapTotals();
            player.Reply("Triggered manual sync of scrap leaderboards to MySQL.");
        }
        #endregion
    }
}

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