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

FREE NWGCore : 3.1.0 3.1.0

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Plugins;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("NWGCore", "NWG Team", "3.1.0")]
    [Description("Central Hub for NWG Plugin Suite. Provides performance services and shared infrastructure.")]
    public class NWGCore : RustPlugin
    {
#region Static Access
        public static NWGCore Instance { get; private set; }
        
        // Configuration Constants
        public const string AdminPermission = "nwgcore.admin";
        public const string PluginPrefix = "<color=#b7d092>[NWG]</color>";
        
        // Public API for other plugins to access services
        public T GetService<T>() where T : class => ServiceContainer.Get<T>();
#endregion

#region Service Container
        public class ServiceContainer
        {
            private static readonly Dictionary<Type, object> _services = new Dictionary<Type, object>();

            public static void Register<T>(T service) where T : class
            {
                if (_services.ContainsKey(typeof(T)))
                    _services[typeof(T)] = service;
                else
                    _services.Add(typeof(T), service);
            }

            public static T Get<T>() where T : class
            {
                if (_services.TryGetValue(typeof(T), out var service))
                    return service as T;
                return null;
            }

            public static void Clear() => _services.Clear();
            
            public static IEnumerable<object> GetAll() => _services.Values;
        }
#endregion

#region Interfaces
        public interface IService
        {
            void OnServerInitialized();
            void OnUnload();
        }
        
        public interface IEntityTracker
        {
            int GetCount<T>() where T : BaseEntity;
            List<T> GetEntities<T>() where T : BaseEntity;
        }
#endregion

#region Services Implementation

        /// <summary>
        /// High-Performance Entity Tracker. 
        /// Replaces laggy FindObjectsOfType with Event-Driven caching.
        /// </summary>
        public class EntityTrackerService : IService, IEntityTracker
        {
            // Cache specific types we care about (Bradleys, Helis, Planes, Drops)
            private readonly HashSet<BradleyAPC> _bradleys = new HashSet<BradleyAPC>();
            private readonly HashSet<PatrolHelicopter> _helis = new HashSet<PatrolHelicopter>();
            private readonly HashSet<CargoPlane> _planes = new HashSet<CargoPlane>();
            private readonly HashSet<SupplyDrop> _drops = new HashSet<SupplyDrop>();
            
            // Generic cache storage for unified access
            private readonly Dictionary<Type, object> _cacheMap = new Dictionary<Type, object>();

            public EntityTrackerService()
            {
                // Register caches
                _cacheMap[typeof(BradleyAPC)] = (object)_bradleys;
                _cacheMap[typeof(PatrolHelicopter)] = (object)_helis;
                _cacheMap[typeof(CargoPlane)] = (object)_planes;
                _cacheMap[typeof(SupplyDrop)] = (object)_drops;
            }

            public void OnServerInitialized()
            {
                // Initial Population (Only done once on reload)
                RepopulateCache<BradleyAPC>(_bradleys);
                RepopulateCache<PatrolHelicopter>(_helis);
                RepopulateCache<CargoPlane>(_planes);
                RepopulateCache<SupplyDrop>(_drops);
            }

            public void OnUnload()
            {
                _bradleys.Clear();
                _helis.Clear();
                _planes.Clear();
                _drops.Clear();
            }

            // --- Public API ---

            public int GetCount<T>() where T : BaseEntity
            {
                if (_cacheMap.TryGetValue(typeof(T), out var collection))
                {
                    if (collection is HashSet<T> set) return set.Count;
                }
                return 0;
            }

            public List<T> GetEntities<T>() where T : BaseEntity
            {
                if (_cacheMap.TryGetValue(typeof(T), out var collection))
                {
                    if (collection is HashSet<T> set)
                        return set.ToList();
                }
                return new List<T>();
            }

            // --- Internal Update Logic ---

            public void RegisterEntity(BaseEntity entity)
            {
                if (entity == null) return;
                
                if (entity is BradleyAPC apc) _bradleys.Add(apc);
                else if (entity is PatrolHelicopter heli) _helis.Add(heli);
                else if (entity is CargoPlane plane) _planes.Add(plane);
                else if (entity is SupplyDrop drop) _drops.Add(drop);
            }

            public void UnregisterEntity(BaseEntity entity)
            {
                if (entity == null) return;

                if (entity is BradleyAPC apc) _bradleys.Remove(apc);
                else if (entity is PatrolHelicopter heli) _helis.Remove(heli);
                else if (entity is CargoPlane plane) _planes.Remove(plane);
                else if (entity is SupplyDrop drop) _drops.Remove(drop);
            }

            private void RepopulateCache<T>(HashSet<T> cache) where T : BaseEntity
            {
                cache.Clear();
                foreach (var entity in UnityEngine.Object.FindObjectsOfType<T>())
                {
                    if (entity != null && !entity.IsDestroyed)
                        cache.Add(entity);
                }
            }
        }

#endregion

#region Plugin Lifecycle

        private void Init()
        {
            Instance = this;
            ServiceContainer.Clear();
            
            // Register Services
            ServiceContainer.Register<IEntityTracker>(new EntityTrackerService());
            
            permission.RegisterPermission(AdminPermission, this);
            Puts("[NWG Core] Services Registered.");
        }

        private void OnServerInitialized()
        {
            // Initialize all registered services
            foreach (var service in ServiceContainer.GetAll().OfType<IService>())
            {
                try
                {
                    service.OnServerInitialized();
                }
                catch (Exception ex)
                {
                    PrintError($"Failed to initialize service {service.GetType().Name}: {ex}");
                }
            }

            // Ensure admin group has root permission
            if (!permission.GroupExists("admin")) permission.CreateGroup("admin", "Default Admin Group", 0);
            if (!permission.GroupHasPermission("admin", AdminPermission))
            {
                permission.GrantGroupPermission("admin", AdminPermission, this);
                Puts($"[NWG Core] Granted '{AdminPermission}' to 'admin' group.");
            }
            
            Puts($"[NWG Core] Ready. Tracker monitoring {GetEntityStatusString()}");
        }

        private void Unload()
        {
            foreach (var service in ServiceContainer.GetAll().OfType<IService>())
            {
                service.OnUnload();
            }
            ServiceContainer.Clear();
            Instance = null;
        }

#endregion

#region Hooks (Event Wiring)

        // Sync native Rust admins to Oxide Groups/Permissions
        private void OnPlayerConnected(BasePlayer player)
        {
            if (player == null) return;

            if (player.IsAdmin || player.IsDeveloper)
            {
                // Ensure native admin flag
                if (!player.HasPlayerFlag(BasePlayer.PlayerFlags.IsAdmin))
                {
                    player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, true);
                    player.SendNetworkUpdate();
                }

                // Ensure Oxide 'admin' group membership
                if (!permission.UserHasGroup(player.UserIDString, "admin"))
                {
                    permission.AddUserGroup(player.UserIDString, "admin");
                }

                // Ensure core NWG admin permission
                if (!permission.UserHasPermission(player.UserIDString, AdminPermission))
                {
                    permission.GrantUserPermission(player.UserIDString, AdminPermission, this);
                }
            }
        
            // Entity Tracking (BasePlayer is a BaseEntity)
            var tracker = ServiceContainer.Get<EntityTrackerService>();
            tracker?.RegisterEntity(player);
        }

        private void OnEntitySpawned(BaseNetworkable entity)
        {
             if (entity is BaseEntity baseEntity)
             {
                 var tracker = ServiceContainer.Get<EntityTrackerService>(); // Use concrete type for speed
                 tracker?.RegisterEntity(baseEntity);
             }
        }

        private void OnEntityKilled(BaseNetworkable entity)
        {
            if (entity is BaseEntity baseEntity)
            {
                var tracker = ServiceContainer.Get<EntityTrackerService>();
                tracker?.UnregisterEntity(baseEntity);
            }
        }

#endregion

#region Helpers

        private string GetEntityStatusString()
        {
            var tracker = ServiceContainer.Get<IEntityTracker>();
            if (tracker == null) return "Tracker Error";

            return $"Bradleys: {tracker.GetCount<BradleyAPC>()}, " +
                   $"Helis: {tracker.GetCount<PatrolHelicopter>()}, " +
                   $"Planes: {tracker.GetCount<CargoPlane>()}, " +
                   $"Drops: {tracker.GetCount<SupplyDrop>()}";
        }

#endregion

#region Lang & Config Helpers
        
        [HookMethod("FormatMessage")]
        public string API_FormatMessage(string message)
        {
            return $"{PluginPrefix} {message}";
        }

        [HookMethod("SendColoredMessage")]
        public void API_SendColoredMessage(BasePlayer player, string message)
        {
            player?.ChatMessage(API_FormatMessage(message));
        }

        // Shared Config pattern interface
        public interface INWGConfig
        {
            void SetDefaults();
        }

#endregion
        
#region UI Theme
        public static class Theme
        {
            public const string Primary = "0.718 0.816 0.573 1";   // Sage Green #b7d092
            public const string Secondary = "0.851 0.325 0.31 1"; // Red/Rust #d9534f
            public const string Accent = "1 0.647 0 1";           // Orange #FFA500
            public const string Panel = "0.15 0.15 0.15 0.98";    // Dark Background
            public const string Text = "0.867 0.867 0.867 1";     // Soft White #DDDDDD
            
            public static Dictionary<string, string> GetThemeDict()
            {
                return new Dictionary<string, string>
                {
                    ["Primary"] = Primary,
                    ["Secondary"] = Secondary,
                    ["Accent"] = Accent,
                    ["Panel"] = Panel,
                    ["Text"] = Text
                };
            }
        }
#endregion

#region API Accessors (For External Plugins using Call())
        
        [HookMethod("GetTheme")]
        public Dictionary<string, string> API_GetTheme()
        {
            return Theme.GetThemeDict();
        }
        
        // Example: int count = (int)NWGCore.Call("GetEntityCount", "BradleyAPC");
        [HookMethod("GetEntityCount")]
        public int API_GetEntityCount(string typeName)
        {
            var tracker = ServiceContainer.Get<IEntityTracker>();
            if (tracker == null) return 0;
            
            switch (typeName.ToLower())
            {
                case "bradleyapc": return tracker.GetCount<BradleyAPC>();
                case "patrolhelicopter": return tracker.GetCount<PatrolHelicopter>();
                case "cargoplane": return tracker.GetCount<CargoPlane>();
                case "supplydrop": return tracker.GetCount<SupplyDrop>();
                default: return 0;
            }
        }

        [HookMethod("GetEntities")]
        public List<BaseEntity> API_GetEntities(string typeName)
        {
            var tracker = ServiceContainer.Get<IEntityTracker>();
            if (tracker == null) return new List<BaseEntity>();
            
            switch (typeName.ToLower())
            {
                case "bradleyapc": return tracker.GetEntities<BradleyAPC>().Cast<BaseEntity>().ToList();
                case "patrolhelicopter": return tracker.GetEntities<PatrolHelicopter>().Cast<BaseEntity>().ToList();
                case "cargoplane": return tracker.GetEntities<CargoPlane>().Cast<BaseEntity>().ToList();
                case "supplydrop": return tracker.GetEntities<SupplyDrop>().Cast<BaseEntity>().ToList();
                default: return new List<BaseEntity>();
            }
        }

        [HookMethod("GetGrid")]
        public string API_GetGrid(Vector3 pos)
        {
            return GetGrid(pos);
        }
        
        [HookMethod("GetGridRef")]
        public string API_GetGridRef(Vector3 pos)
        {
             return GetGrid(pos);
        }

        public string GetGrid(Vector3 pos)
        {
            float worldSize = ConVar.Server.worldsize;
            float offset = worldSize / 2f;
            const float cellSize = 150f;
            int maxCell = (int)(worldSize / cellSize) - 1;
            int x = Mathf.Clamp(Mathf.FloorToInt((pos.x + offset) / cellSize), 0, maxCell);
            int z = Mathf.Clamp(Mathf.FloorToInt((pos.z + offset) / cellSize), 0, maxCell);
            
            string col = "";
            int cx = x;
            do
            {
                col = (char)('A' + cx % 26) + col;
                cx = cx / 26 - 1;
            } while (cx >= 0);
            
            return $"{col}{z}";
        }
        
#endregion
    }
}

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