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

FREE FriendlyFire : 1.0.2 1.0.2

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

namespace Oxide.Plugins
{
    [Info("FriendlyFire", "https://topplugin.ru/", "1.0.2")]    
    public class FriendlyFire : RustPlugin
    {        					
						
		#region Variables				
						
		[PluginReference] 
		private Plugin Clans;				
		
		[PluginReference] 
		private Plugin Friends;
						
		private static FieldInfo hookSubscriptions = typeof(PluginManager).GetField("hookSubscriptions", (BindingFlags.Instance | BindingFlags.NonPublic));            
		private static HashSet<ulong> PlayersWithEnabledDamage = new HashSet<ulong>();
		private static Dictionary<ulong, List<ulong>> PlayerFriends = new Dictionary<ulong, List<ulong>>();
		
		#endregion
		
		#region Hooks
		
		private void Init()
		{
			LoadVariables();
			LoadDefaultMessages();
			LoadData();
		}
		
		private void OnServerInitialized() 
		{
			if (configData.UseNoFriendDamage || configData.UseNoClanDamage)
				SubscribeInternalHook("IOnBasePlayerHurt");		
		}	
		
		private void Unload()
		{
			if (configData.UseNoFriendDamage || configData.UseNoClanDamage)
				UnsubscribeInternalHook("IOnBasePlayerHurt");
			
			SaveData();
		}
		
		private void OnServerSave() => SaveData();
		
		private object IOnBasePlayerHurt(BasePlayer player, HitInfo info)
        {
			if (player == null || player is NPCPlayer || info?.Initiator == null) return null;
			var aggressor = info?.Initiator.ToPlayer();
			if (aggressor == null || aggressor is NPCPlayer) return null;						
			
			if (PlayersWithEnabledDamage.Contains(aggressor.userID)) return null;
			
			if (!PlayerFriends.ContainsKey(aggressor.userID))
				InitFriends(aggressor.userID);
			
			if (PlayerFriends[aggressor.userID].Contains(player.userID))
			{
				DamageType type = info.damageTypes.GetMajorityDamageType();								
				
				if (type != null && type == DamageType.Explosion)
				{
					if (configData.IgnoreExplosion)
					{	
						DisableDamage(info);
						return false;
					}
					else
						return null;
				}
				
				if (type != null && type == DamageType.Heat)
				{
					if (configData.IgnoreFire)
					{	
						DisableDamage(info);
						return false;
					}
					else
						return null;
				}								
								
				DisableDamage(info);
				return false;					
			}	
			
			return null;
        }
		
		private void OnPlayerConnected(BasePlayer player) => InitFriends(player.userID);
        
		// поддержка Friends от Moscow.ovh
		
		private void OnActiveFriendsUpdate(BasePlayer player) => InitFriends(player.userID, 1);
		
		private void OnActiveFriendsUpdateUserId(ulong userID) => InitFriends(userID, 1);		
		
		// поддержка Friends c Oxide
		
		private void OnFriendAdded(string userID) => InitFriends((ulong)Convert.ToInt64(userID), 1);		
		
		private void OnFriendRemoved(string userID) => InitFriends((ulong)Convert.ToInt64(userID), 1);		
		
		// без поддержки Clans от Moscow.ovh и Oxide (из-за неподходящих api)
		
		// поддержка собственного Clans (еще не разработан)
		
		private void OnClanMemberAdded(string tag, ulong userID) => InitFriends(userID, 2);		
		
		private void OnClanMemberRemoved(string tag, ulong userID) => InitFriends(userID, 2);
		
		// private List<ulong> GetClanMembers(string tag);
		
		#endregion
		
		#region Main
		
		// Если scanAll = 0 - чекать и друзей и кланы, scanAll = 1 - чекать только друзей, scanAll = 2 - чекать только кланы
		private void InitFriends(ulong userID, int scanAll = 0)
		{		
			List<ulong> friends_ = new List<ulong>();
			
			if (configData.UseNoFriendDamage && Friends != null && (scanAll == 0 || scanAll == 1))
			{					
				var friends = Friends.Call("GetFriends", userID);				
				
				if (friends != null && friends is ulong[])								
					friends_.AddRange(friends as ulong[]);								
			}
			
			if (configData.UseNoClanDamage && Clans != null && (scanAll == 0 || scanAll == 2))
			{						
				var friends = Clans.Call("GetClanMembers", userID);				
				
				if (friends != null && friends is List<ulong>)
					friends_.AddRange(friends as List<ulong>);				
			}
			
			if (!PlayerFriends.ContainsKey(userID))
				PlayerFriends.Add(userID, friends_);
			else
				PlayerFriends[userID] = friends_;
		}
		
		#endregion
		
		#region Common
		
		private void SubscribeInternalHook(string hook)
		{
			var hookSubscriptions_ = hookSubscriptions.GetValue(Interface.Oxide.RootPluginManager) as IDictionary<string, IList<Plugin>>;
			
			IList<Plugin> plugins;
			if (!hookSubscriptions_.TryGetValue(hook, out plugins))
            {
                plugins = new List<Plugin>();
                hookSubscriptions_.Add(hook, plugins);
            }
			
            if (!plugins.Contains(this))            
                plugins.Add(this);            
		}
		
		private void UnsubscribeInternalHook(string hook)
        {            
			var hookSubscriptions_ = hookSubscriptions.GetValue(Interface.Oxide.RootPluginManager) as IDictionary<string, IList<Plugin>>;		
			
			IList<Plugin> plugins;			 
            if (hookSubscriptions_.TryGetValue(hook, out plugins) && plugins.Contains(this))            
                plugins.Remove(this);            
        }				

		private void DisableDamage(HitInfo info)
		{
			info.damageTypes = new DamageTypeList();
            info.DidHit = false;
            info.HitEntity = null;
            info.Initiator = null;
            info.DoHitEffects = false;
            info.HitMaterial = 0;
		}
		
		#endregion		

		#region Commands
		
		[ChatCommand("ff")]
        private void CmdChatFF(BasePlayer player, string command, string[] args)
        {
            if (!configData.UseNoFriendDamage && !configData.UseNoClanDamage) return;
            
			if (args.Length == 0)
			{
				SendReply(player, string.Format(GetLangMessage("CMD.FF.HELP"), PlayersWithEnabledDamage.Contains(player.userID) ? "включён" : "выключен"));
                return;
			}	
			
			var param = args[0].ToLower();
			
            if (param != "on" && param != "off")
            {
                SendReply(player, string.Format(GetLangMessage("CMD.FF.UNKNOWN.ARG"), args[0]));
                return;
            }
			            
            switch (param)
            {                
                case "on":             
                    if (PlayersWithEnabledDamage.Contains(player.userID))
                        SendReply(player, GetLangMessage("FRIENDLY.FIRE.ALREADY.ON"));
                    else
                    {
                        PlayersWithEnabledDamage.Add(player.userID);
                        SendReply(player, GetLangMessage("FRIENDLY.FIRE.ON"));						
                    }
                    break;                
                case "off":                
                    if (!PlayersWithEnabledDamage.Contains(player.userID))
                        SendReply(player, GetLangMessage("FRIENDLY.FIRE.ALREADY.OFF"));
                    else
                    {
                        PlayersWithEnabledDamage.Remove(player.userID);
                        SendReply(player, GetLangMessage("FRIENDLY.FIRE.OFF"));
                    }
                    break;                
            }
        }
		
		#endregion

		#region Lang
		
        private void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {                
				{"CMD.FF.HELP", "ДОСТУПНЫЕ КОМАНДЫ:\n<color=#aae9f2>/ff on</color> - включить огонь по друзьям/соклановцам.\n<color=#aae9f2>/ff off</color> - выключить огонь по друзьям/соклановцам.\nТекущее состояние <color=#aae9f2>{0}</color>."},
				{"FRIENDLY.FIRE.ON", "Вы включили огонь по друзьям/соклановцам."},
				{"FRIENDLY.FIRE.OFF", "Вы выключили огонь по друзьям/соклановцам."},
				{"FRIENDLY.FIRE.ALREADY.ON", "У вас уже включен огонь по друзьям/соклановцам."},
				{"FRIENDLY.FIRE.ALREADY.OFF", "У вас уже выключен огонь по друзьям/соклановцам."},
				{"CMD.FF.UNKNOWN.ARG", "Неизвестный параметр <color=#aae9f2>\"{0}\"</color>.\nИспользуйте <color=#aae9f2>/ff</color> чтобы посмотреть список доступных команд."}
            }, this);
        }

        private string GetLangMessage(string key, string steamID = null) => lang.GetMessage(key, this, steamID);
		
		#endregion		
		
		#region Config        				
		
        private static ConfigData configData;
		
        private class ConfigData
        {            						
			[JsonProperty(PropertyName = "Разрешить отключение огня по друзьям")]
			public bool UseNoFriendDamage;
			[JsonProperty(PropertyName = "Разрешить отключение огня по соклановцам")]
			public bool UseNoClanDamage;
			[JsonProperty(PropertyName = "Игнорировать урон от взрывов")]
			public bool IgnoreExplosion;
			[JsonProperty(PropertyName = "Игнорировать урон от огня")]
			public bool IgnoreFire;
        }
		
        private void LoadVariables() => configData = Config.ReadObject<ConfigData>();        
		
        protected override void LoadDefaultConfig()
        {
            var config = new ConfigData
            {
                UseNoFriendDamage = false,
				UseNoClanDamage = false,
				IgnoreExplosion = false,
				IgnoreFire = false
            };
            SaveConfig(config);
			timer.Once(0.1f, ()=>SaveConfig(config));
        }        
		
        private void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
		
        #endregion
		
		#region Data
		
		private void LoadData() => PlayersWithEnabledDamage = Interface.GetMod().DataFileSystem.ReadObject<HashSet<ulong>>("FriendlyFireData");					
		
		private void SaveData() => Interface.GetMod().DataFileSystem.WriteObject("FriendlyFireData", PlayersWithEnabledDamage);		
		
		#endregion
		
    }
}

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

Другие ресурсы пользователя 15FPS

Сверху