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

FREE AutoPurge : 1.5.0 1.5.0

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

namespace Oxide.Plugins
{
    [Info("AutoPurge", "", "1.5.0", ResourceId = 1566)]
    [Description("Remove entities if the owner becomes inactive.")]
    public class AutoPurge : RustPlugin
    {
		[PluginReference]
        Plugin Clans;
		
		[PluginReference]
		Plugin Friends;
		
		private bool Changed = false;
		StoredData playerConnections = new StoredData();
		static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
		static readonly double MaxUnixSeconds = (DateTime.MaxValue - UnixEpoch).TotalSeconds;
		private List<ulong> groupModerator = new List<ulong>();
		private List<ulong> groupOwner = new List<ulong>();
		private string logFile = "AutoPurgeLog.txt";
		private bool friendsEnabled = false;
		private bool clansEnabled = false;
		private int lastMinute;
		
		static List<object> defaultRealTimers()
		{
			var dp = new List<object>();
			dp.Add("06:00");
			dp.Add("18:00");
			return dp;
		}
		
		#region Config
		
		private int timerJob;
		private bool timerEnabled;
		private int inactiveAfter;
		private int removeRecordAfterDays;
		private bool removeRecordAfterPurge;
		private bool killSleepers;
		private bool showMessages;
		private bool testMode;
		private bool purgeOnStart;
		private bool logPurgeToFile;
		private bool showMessagesAdminOnly;
		private bool excludeGroupOwner;
		private bool excludeGroupModerator;
		private string excludePermission;
		private bool useFriendsApi;
		private bool useClansIO;
		private bool useRealTimer;
		private bool logRealTimerToConsole;
		List<object> realTimers = new List<object>();
		
		private object GetConfig(string menu, string datavalue, object defaultValue)
        {
            var data = Config[menu] as Dictionary<string, object>;
            if (data == null)
            {
                data = new Dictionary<string, object>();
                Config[menu] = data;
                Changed = true;
            }
            object value;
            if (!data.TryGetValue(datavalue, out value))
            {
                value = defaultValue;
                data[datavalue] = value;
                Changed = true;
            }
            return value;
        }
		
		void LoadVariables()
        {
			timerJob = Convert.ToInt32(GetConfig("Timing", "timerJob", 21600));
			timerEnabled = Convert.ToBoolean(GetConfig("Timing", "timerEnabled", true));
			inactiveAfter = Convert.ToInt32(GetConfig("Timing", "inactiveAfter", 172800));
			useRealTimer = Convert.ToBoolean(GetConfig("RealTimer", "enable RealTimer", false));
			logRealTimerToConsole = Convert.ToBoolean(GetConfig("RealTimer", "log to console", true));
			realTimers = (List<object>)GetConfig("RealTimer", "RealTime", defaultRealTimers());
			removeRecordAfterDays = Convert.ToInt32(GetConfig("Generic", "removeRecordAfterDays", 30));
			showMessages = Convert.ToBoolean(GetConfig("Messaging", "showMessages", true));
            testMode = Convert.ToBoolean(GetConfig("Generic", "testMode", false));
			purgeOnStart = Convert.ToBoolean(GetConfig("Generic", "purgeOnStart", false));
			logPurgeToFile = Convert.ToBoolean(GetConfig("Generic", "logPurgeToFile", true));
			killSleepers = Convert.ToBoolean(GetConfig("Generic", "killSleepers", false));
			useFriendsApi = Convert.ToBoolean(GetConfig("Generic", "useFriendsApi", false));
			useClansIO = Convert.ToBoolean(GetConfig("Generic", "useClansIO", true));
			showMessagesAdminOnly = Convert.ToBoolean(GetConfig("Messaging", "showMessagesAdminOnly", false));
			removeRecordAfterPurge = Convert.ToBoolean(GetConfig("Generic", "removeRecordAfterPurge", true));
			excludeGroupOwner = Convert.ToBoolean(GetConfig("Exclution", "excludeGroupOwner", true));
			excludeGroupModerator = Convert.ToBoolean(GetConfig("Exclution", "excludeGroupModerator", true));
			excludePermission = Convert.ToString(GetConfig("Exclution", "excludePermission", "autopurge.exclude"));
			
			if (!Changed) return;
            SaveConfig();
            Changed = false;
        }
		
        protected override void LoadDefaultConfig()
        {
            Config.Clear();
            LoadVariables();
        }
		
		#endregion Config
		
		#region StoredData
		
		class StoredData
        {
            public Dictionary<ulong, PlayerInfo> PlayerInfo = new Dictionary<ulong, PlayerInfo>();
            public StoredData(){}
        }
        
		class PlayerInfo
        {
			public string DisplayName;
            public int LastTime;
			public string LastDateTime;
            public PlayerInfo(){}
        }

		void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject(this.Title, playerConnections);
        }

		#endregion StoredData
		
		#region Connection
		
		private void UpdatePlayer(BasePlayer player)
        {
            if (player == null) return;
            PlayerInfo p = null;
            if (!playerConnections.PlayerInfo.TryGetValue(player.userID, out p))
            {
                var info = new PlayerInfo(); 
				info.DisplayName = player.displayName;
                info.LastTime = UnixTimeStampUTC();
				info.LastDateTime = DateTime.Now.ToString();
				playerConnections.PlayerInfo.Add(player.userID, info);
                return;
            }
            else
            {
                p.LastTime = UnixTimeStampUTC();
				p.LastDateTime = DateTime.Now.ToString();
				p.DisplayName = player.displayName;
            }
            return;
        }
		
		#endregion Connection

		private Int32 UnixTimeStampUTC()
        {
            Int32 unixTimeStamp;
            DateTime currentTime = DateTime.Now;
            DateTime zuluTime = currentTime.ToUniversalTime();
            DateTime unixEpoch = new DateTime(1970, 1, 1);
            unixTimeStamp = (Int32)(zuluTime.Subtract(unixEpoch)).TotalSeconds;
            return unixTimeStamp;
        }
        
		private static DateTime UnixTimeStampToDateTime(double unixTimeStamp)
        {
            return unixTimeStamp > MaxUnixSeconds
               ? UnixEpoch.AddMilliseconds(unixTimeStamp)
               : UnixEpoch.AddSeconds(unixTimeStamp);
        }

		private bool DataExistsFromID(ulong steamid)
        {
            if (playerConnections.PlayerInfo.ContainsKey(steamid)) { return true; }
            return false;
        }
        
		private bool DataExists(BasePlayer player)
        {
            if (player == null || !player.isConnected) return false;
            if (playerConnections.PlayerInfo.ContainsKey(player.userID)) { return true; }
            return false;
        }

		private bool CheckActiveClanMember(string tag)
		{
			JObject clan = (JObject)Clans.Call("GetClan", tag);
			if (clan == null) return false;
			foreach( var member in clan["members"])
				if (DataExistsFromID(Convert.ToUInt64(member)))
					if (UnixTimeStampUTC() - playerConnections.PlayerInfo[Convert.ToUInt64(member)].LastTime < inactiveAfter)
						return true;
			return false;
		}

		private bool CheckActiveFriends(ulong id)
		{
			foreach( var pair in playerConnections.PlayerInfo)
				if((bool)Friends?.CallHook("AreFriends", pair.Key, id))
					if (UnixTimeStampUTC() - playerConnections.PlayerInfo[pair.Key].LastTime < inactiveAfter)
						return true;
			return false;
		}
		
		#region serverhooks
		
		private void OnPlayerInit(BasePlayer player)
        {
            UpdatePlayer(player);
        }
		
		private void OnPlayerDisconnected(BasePlayer player)
        {
            UpdatePlayer(player);
        }
		
		private void OnServerSave()
        {
            SaveData();
        }

		private void OnServerShutdown()
        {
            SaveData();
        }
		
		private void Unload()
        {
            SaveData();
        }
        
		private void Loaded()
        {
            LoadVariables();
		}
	
		private void OnServerInitialized()
        {
			lang.RegisterMessages(new Dictionary<string, string>
			{
				{"RunBefore", "<color=yellow>INFO:</color> Запущена <color=red>очистка</color>.(<color=yellow>Может быть незначительная задержка, пожалуйста не спамьте в чат</color>)"},
				{"RunComplete", "Очистка <color=green>завершена</color> (<color=yellow>{0}</color> удалено обьектов <color=yellow>{1}</color> неактивных игроков)."},
			}, this);


			if (!permission.PermissionExists(excludePermission)) permission.RegisterPermission(excludePermission, this);
			playerConnections = Interface.GetMod().DataFileSystem.ReadObject<StoredData>(this.Title);
			foreach (BasePlayer player in BasePlayer.activePlayerList)
				UpdatePlayer(player);
			StoredData cleanedConnections = new StoredData();			
			foreach( var pair in playerConnections.PlayerInfo)
			{
				if(UnixTimeStampUTC()-pair.Value.LastTime < removeRecordAfterDays * 86400)
					cleanedConnections.PlayerInfo.Add(pair.Key, pair.Value);
				//cleanedConnections.PlayerInfo[pair.Key].LastDateTime = UnixTimeStampToDateTime(pair.Value.LastTime).ToString();
			}
			playerConnections = cleanedConnections;
			SaveData();
			cleanedConnections = null;
			if (excludeGroupOwner)
				foreach ( var user in ServerUsers.GetAll(ServerUsers.UserGroup.Owner).ToList())
					groupOwner.Add(user.steamid);
			if (excludeGroupModerator)
				foreach ( var user in ServerUsers.GetAll(ServerUsers.UserGroup.Moderator).ToList())
					groupModerator.Add(user.steamid);
			NextTick( () => {
				TimeSpan its = TimeSpan.FromSeconds(inactiveAfter);
				TimeSpan ts = TimeSpan.FromSeconds(timerJob);
				if (timerEnabled)
				{
					Puts($"Purge will be executed every: {ts.TotalHours.ToString("0")} hours ({ts.Days.ToString("0")}D | {ts.Hours.ToString("0")}H | {ts.Minutes.ToString("0")}M | {ts.Seconds.ToString("0")}S)");
					Puts($"Players become inactive after: {its.TotalDays.ToString("0")} days ({its.Days.ToString("0")}D | {its.Hours.ToString("0")}H | {its.Minutes.ToString("0")}M | {its.Seconds.ToString("0")}S)");
					timer.Every(timerJob, () => MainTimer(false));
				}
				if (useRealTimer)
					Puts($"RealTimer active with '{realTimers.Count}' entries");
				
				if (Clans && useClansIO)
				{
					clansEnabled = true;
					Puts("Plugin 'Clans' found - Clan support activated");
				}
				if (!Clans && useClansIO)
					PrintWarning("Plugin 'Clans' not found - Clan support not active");
				if (Friends && useFriendsApi)
				{
					friendsEnabled = true;
					Puts("Plugin 'Friends' found - Friends support activated");
				}
				if (!Friends && useFriendsApi)
					PrintWarning("Plugin 'Friends' not found - Friends support not active");
				if (testMode) PrintWarning("Running in TestMode.Nothing will be purged");
				if (purgeOnStart)
					MainTimer(true);
			});
		}
		
		void OnTick()
		{
			if (!useRealTimer || lastMinute == DateTime.UtcNow.Minute) return;
			lastMinute = DateTime.UtcNow.Minute;
			if (realTimers.Contains(DateTime.Now.ToString("HH:mm")))
			{
				if (logRealTimerToConsole)
					Puts($"Running RealTimer purge ({DateTime.Now.ToString("HH:mm")})");
				ccmdRunPurge( new ConsoleSystem.Arg(null) );
			}
		}

		#endregion serverhooks

		[ConsoleCommand("autopurge.remove")]
        void ccmdRunRemove(ConsoleSystem.Arg arg)
        {
            if(arg.connection != null && arg.connection.authLevel < 2)
				return;
			if (arg.Args == null)
			{
				SendReply(arg, string.Format("Please specify a target steamid"));
				return;
			}
			ulong owner = 0;
			if(arg.Args.Length >= 1) ulong.TryParse(arg.Args[0], out owner);
			if (owner == 0) return;
			
			int count = 0;
            foreach(var entity in BaseNetworkable.serverEntities.Where(p => (p as BaseEntity).OwnerID == owner).ToList())
			{
				entity.Kill();
				count++;
			}
			SendReply(arg, $"Removed: {count} entities from ID: {owner}");
			if (logPurgeToFile && count > 0)
				ConVar.Server.Log(logFile, $"Manually removed: {count} entities from ID: {owner}");
		}

        [ConsoleCommand("autopurge.run")]
        void ccmdRunPurge(ConsoleSystem.Arg arg)
        {
            if(arg.connection != null && arg.connection.authLevel < 2)
				return;
			MainTimer();
        }

		void MainTimer(bool freshStart = false)
        {
			if (freshStart)
			{
				if (useClansIO && !clansEnabled) return;
				if (useFriendsApi && !friendsEnabled) return;
			}
			if (showMessages && !freshStart)
			{
				if(showMessagesAdminOnly)
				{
					foreach(var admin in BasePlayer.activePlayerList.Where(p => p.IsAdmin()).ToList())
					SendReply(admin, string.Format(lang.GetMessage("RunBefore", this, admin.UserIDString)));
				}
			}
			
			int count = 0;
			List<ulong> UNIQUE_HITS = new List<ulong>();
			List<ulong> EXCLUDE_BY_CLAN = new List<ulong>();
			List<ulong> CLANCHECK_NEGATIVE = new List<ulong>();
			List<ulong> EXCLUDE_BY_FRIEND = new List<ulong>();
			List<ulong> FRIENDCHECK_NEGATIVE = new List<ulong>();			
			List<ulong> ONLINE_PLAYERS = new List<ulong>();
			List<ulong> EXCLUDE_BY_PERM = new List<ulong>();	
			foreach (BasePlayer onliner in BasePlayer.activePlayerList)
			{
				ONLINE_PLAYERS.Add(onliner.userID);
				UpdatePlayer(onliner);
			}
			
			var entities = BaseNetworkable.serverEntities.Where(p => (p as BaseEntity).OwnerID != 0).ToList();
			Puts("Included entity count on this run: "+entities.Count);
			foreach (var entity in entities)
            {
				if (entity == null) continue;
				ulong owner = 0;
				try { owner = (entity as BaseEntity).OwnerID; }
				catch { continue; }
				if (DataExistsFromID(owner) && !ONLINE_PLAYERS.Contains(owner) && !EXCLUDE_BY_CLAN.Contains(owner) && !EXCLUDE_BY_FRIEND.Contains(owner) && !EXCLUDE_BY_PERM.Contains(owner) && !groupOwner.Contains(owner) && !groupModerator.Contains(owner))
                {
                    if (UnixTimeStampUTC() - playerConnections.PlayerInfo[owner].LastTime >= inactiveAfter)
					{ 
						if (UNIQUE_HITS.Contains(owner))
						{
							if (!testMode)
								entity.Kill();
							count++;
							continue;
						}
							
						// PermCheck begin
						if (permission.UserHasPermission(owner.ToString(), excludePermission))
						{
							EXCLUDE_BY_PERM.Add(owner);
							continue;
						}
						// PermCheck end
						// Clancheck begin
						if(clansEnabled)
							if (Clans.Call("GetClanOf", owner) != null && !CLANCHECK_NEGATIVE.Contains(owner))
								if (CheckActiveClanMember((string)Clans.Call("GetClanOf", owner)))
								{
									EXCLUDE_BY_CLAN.Add(owner);
									continue;
								}
								else
									CLANCHECK_NEGATIVE.Add(owner);
						// Clancheck end
						// FriendCheck begin
						if(friendsEnabled)
							if (!FRIENDCHECK_NEGATIVE.Contains(owner))
								if(CheckActiveFriends(owner))
								{
									EXCLUDE_BY_FRIEND.Add(owner);
									continue;
								}
								else
									FRIENDCHECK_NEGATIVE.Add(owner);
						// FriendCheck end
						if (!testMode)
						{
							entity.Kill();
						}
						count++;
						if (!UNIQUE_HITS.Contains(owner))
						{
							UNIQUE_HITS.Add(owner);
						}
					}
                }
            }
			if (showMessages && !freshStart)
			{
				if (showMessagesAdminOnly)
				{
					foreach(var admin in BasePlayer.activePlayerList.Where(p => p.IsAdmin()).ToList())
					SendReply(admin, string.Format(lang.GetMessage("RunComplete", this, admin.UserIDString), count, UNIQUE_HITS.Count));
				}
			}
            if (count != 0)
			{
				string playerIds = "";
				string ifTest = "";
				if(testMode)
				{
					ifTest = "TestMode >> ";
				}
				foreach (var id in UNIQUE_HITS)
				{
					playerIds += playerConnections.PlayerInfo[id].DisplayName+"("+id.ToString()+") ";
					if (removeRecordAfterPurge && !testMode) playerConnections.PlayerInfo.Remove(id);
					if (killSleepers && !testMode)
					{
						foreach (BasePlayer sleeper in BasePlayer.sleepingPlayerList.ToList())
						{
							if (UNIQUE_HITS.Contains(sleeper.userID))
								sleeper.KillMessage();
						}
					}
				}
				Puts(ifTest+ "Removed: " + count.ToString() + " entities from: " + UNIQUE_HITS.Count.ToString() + " inactive players");
				Puts(ifTest+ "Affected IDs: " + playerIds);
				if (logPurgeToFile)
				{
					ConVar.Server.Log(logFile, ifTest+ "Removed: " + count.ToString() + " entities from: " + UNIQUE_HITS.Count.ToString() + " inactive players");
					ConVar.Server.Log(logFile, ifTest+ "Affected IDs: " + playerIds);
				}
			}
			else
			{
				Puts("Nothing to remove...up to date.");
				if (logPurgeToFile)
					ConVar.Server.Log(logFile,"Nothing to remove...up to date.");
			}
        }

	}
}

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