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

FREE WantedForMurder : 1.0.7 1.0.7

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Text;
using System.Collections.Generic;
using UnityEngine;
using Facepunch;
using Rust;
using Oxide.Core;
using Oxide.Core.Libraries;


namespace Oxide.Plugins
{
	[Info( "Wanted For Murder", "Raptor007", "1.0.7" )]
	[Description( "Players can punish unwanted PvP." )]
	
	class WantedForMurder : RustPlugin
	{
		bool DataChanged = false;
		Dictionary< ulong, List<ulong> > Murderers = new Dictionary< ulong, List<ulong> >();
		Dictionary< ulong, ulong > LastKillerOf = new Dictionary< ulong, ulong >();
		Dictionary< ulong, ulong > LastAttackerOf = new Dictionary< ulong, ulong >();
		Dictionary< string, string > EN = new Dictionary< string, string >();
		
		
		// Poor man's locking because we can't use System.Threading.volatile bool DataLocked = false;
		
		void LockData()
		{
			while( DataLocked );
			DataLocked = true;
		}
		
		void UnlockData()
		{
			DataLocked = false;
		}
		
		
		void ChatToPlayer( BasePlayer player, string key, params object[] args )
		{
			PrintToChat( player, string.Format( lang.GetMessage( key, this, player.UserIDString ), args ) );
		}
		
		
		void ChatToAll( string key, params object[] args )
		{
			foreach( BasePlayer player in BasePlayer.activePlayerList )
				ChatToPlayer( player, key, args );
		}
		
		
		bool SetUnconfiguredDefaults()
		{
			bool changed = false;
			
			if( Config[ "AnnounceWhenLoaded" ] == null )
			{
				Config[ "AnnounceWhenLoaded" ] = true;
				changed = true;
			}
			if( Config[ "AwakeAutoPunish" ] == null )
			{
				Config[ "AwakeAutoPunish" ] = false;
				changed = true;
			}
			if( Config[ "CastleDoctrine" ] == null )
			{
				Config[ "CastleDoctrine" ] = true;
				changed = true;
			}
			if( Config[ "RemoveMurdererBags" ] == null )
			{
				Config[ "RemoveMurdererBags" ] = true;
				changed = true;
			}
			if( Config[ "Sheriffs" ] == null )
			{
				Config[ "Sheriffs" ] = new List<ulong>();
				changed = true;
			}
			if( Config[ "ShowOnWake" ] == null )
			{
				Config[ "ShowOnWake" ] = true;
				changed = true;
			}
			if( Config[ "SleepersAutoPunish" ] == null )
			{
				Config[ "SleepersAutoPunish" ] = true;
				changed = true;
			}
			
			return changed;
		}
		
		
		protected override void LoadDefaultConfig()
		{
			LockData();
			
			Config.Clear();
			SetUnconfiguredDefaults();
			SaveConfig();
			
			UnlockData();
		}
		
		
		void LoadData()
		{
			Murderers = Interface.GetMod().DataFileSystem.ReadObject< Dictionary< ulong, List<ulong> > >( "WantedForMurder-Murderers" );
		}
		
		
		void SaveData()
		{
			Interface.GetMod().DataFileSystem.WriteObject( "WantedForMurder-Version", Version.ToString() );
			Interface.GetMod().DataFileSystem.WriteObject( "WantedForMurder-Murderers", Murderers );
		}
		
		
		void OnServerSave()
		{
			if( DataChanged )
			{
				LockData();
				
				if( DataChanged )
				{
					DataChanged = false;
					SaveData();
				}
				
				UnlockData();
			}
		}
		
		
		string GetPlayerNameFromID( ulong player_id )
		{
			foreach( BasePlayer player in BasePlayer.activePlayerList )
			{
				if( player.userID == player_id )
					return player.displayName;
			}
			foreach( BasePlayer player in BasePlayer.sleepingPlayerList )
			{
				if( player.userID == player_id )
					return player.displayName;
			}
			
			return "Somebody";
		}
		
		
		ulong GetPlayerIDFromName( string name )
		{
			foreach( BasePlayer player in BasePlayer.activePlayerList )
			{
				if( player.displayName.ToLower().Contains(name.ToLower()) )
					return player.userID;
			}
			foreach( BasePlayer player in BasePlayer.sleepingPlayerList )
			{
				if( player.displayName.ToLower().Contains(name.ToLower()) )
					return player.userID;
			}
			
			return 0;
		}
		
		
		bool IsMurderer( ulong player_id )
		{
			if( Murderers.ContainsKey(player_id) )
				return true;
			return false;
		}
		
		
		bool IsKiller( ulong player_id )
		{
			foreach( KeyValuePair<ulong,ulong> pair in LastKillerOf )
			{
				if( pair.Value == player_id )
					return true;
			}
			return false;
		}
		
		
		bool PunishLastKillerOf( ulong player_id )
		{
			if( Murderers.ContainsKey(player_id) )
				return false;
			if( ! LastKillerOf.ContainsKey(player_id) )
				return false;
			
			ulong murderer_id = LastKillerOf[ player_id ];
			
			if( ! Murderers.ContainsKey(murderer_id) )
				Murderers[ murderer_id ] = new List<ulong>();
			
			// We don't care who kills murderers.if( LastKillerOf.ContainsKey(murderer_id) )
				LastKillerOf.Remove( murderer_id );
			
			if( ! Murderers[ murderer_id ].Contains(player_id) )
			{
				Murderers[ murderer_id ].Add( player_id );
				DataChanged = true;
				RemoveSleepingBagsFor( murderer_id );
				
				ChatToAll( "Punish", GetPlayerNameFromID(murderer_id), GetPlayerNameFromID(player_id) );
				
				return true;
			}
			
			return false;
		}
		
		
		void RemoveSleepingBagsFor( ulong player_id )
		{
			if( Config.Get<bool>("RemoveMurdererBags") )
			{
				foreach( SleepingBag bag in SleepingBag.FindForPlayer( player_id, true ) )
					bag.Kill();
			}
		}
		
		
		void RemoveMurdererSleepingBags()
		{
			foreach( BasePlayer player in BasePlayer.activePlayerList )
			{
				if( IsMurderer(player.userID) )
					RemoveSleepingBagsFor( player.userID );
			}
		}
		
		
		void OnItemDeployed( Deployer deployer, BaseEntity entity )
		{
			LockData();
			RemoveMurdererSleepingBags();
			UnlockData();
		}
		
		
		void OnEntityTakeDamage( BaseCombatEntity entity, HitInfo info )
		{
			if( entity == null )
				return;
			
			if( (info != null) && (info.Initiator != null) && info.Initiator.name.Contains("player") && entity.name.Contains("player") )
			{
				var victim = entity as BasePlayer;
				var killer = info.Initiator as BasePlayer;
				
				if( (victim == null) || (killer == null) )
					return;
				
				// Don't track self-harm.if( victim.userID != killer.userID )
				{
					LockData();
					
					// Don't track kills of murderers, and if Castle Doctrine is enabled, don't allow punishment for wounding home invaders.if( IsMurderer(victim.userID) || (Config.Get<bool>("CastleDoctrine") && killer.CanBuild() && ! victim.CanBuild()) )
					{
						// Prevent accidentally punishing the wrong person.if( LastAttackerOf.ContainsKey(victim.userID) )
							LastAttackerOf.Remove( victim.userID );
					}
					else
						LastAttackerOf[ victim.userID ] = killer.userID;
					
					UnlockData();
				}
			}
		}
		
		
		void OnEntityDeath( BaseCombatEntity entity, HitInfo info )
		{
			if( entity == null )
				return;
			
			if( entity.name.Contains("player") )
			{
				var victim = entity as BasePlayer;
				if( victim == null )
					return;
				
				bool sleep_murder = false;
				bool locked_data = false;
				
				if( (info != null) && (info.Initiator != null) && info.Initiator.name.Contains("player") )
				{
					var killer = info.Initiator as BasePlayer;
					if( killer == null )
						return;
					
					// Don't track suicides.if( victim.userID != killer.userID )
					{
						LockData();
						locked_data = true;
						
						// Don't track kills of murderers, and if Castle Doctrine is enabled, don't allow punishment for killing home invaders.if( IsMurderer(victim.userID) || (Config.Get<bool>("CastleDoctrine") && killer.CanBuild() && ! victim.CanBuild()) )
						{
							// Prevent accidentally punishing the wrong person.if( LastKillerOf.ContainsKey(victim.userID) )
								LastKillerOf.Remove( victim.userID );
						}
						else
						{
							LastKillerOf[ victim.userID ] = killer.userID;
							sleep_murder = victim.IsSleeping();
						}
					}
				}
				else
				{
					LockData();
					locked_data = true;
					
					if( LastAttackerOf.ContainsKey(victim.userID) )
					{
						LastKillerOf[ victim.userID ] = LastAttackerOf[ victim.userID ];
						sleep_murder = victim.IsSleeping();
					}
				}
				
				if( ! locked_data )
					LockData();
				
				// Always remove stale attacked-by data when a player dies.LastAttackerOf.Remove( victim.userID );
				
				if( Config.Get<bool>("SleepersAutoPunish") && sleep_murder )
					PunishLastKillerOf( victim.userID );
				else if( Config.Get<bool>("AwakeAutoPunish") && ! sleep_murder )
					PunishLastKillerOf( victim.userID );
				
				UnlockData();
			}
		}
		
		
		void ShowWantedListTo( BasePlayer player )
		{
			if( Murderers.Count > 0 )
			{
				foreach( KeyValuePair< ulong, List<ulong> > pair in Murderers )
				{
					string murderer = GetPlayerNameFromID( pair.Key );
					string victims = GetPlayerNameFromID( pair.Value[ 0 ] );
					if( pair.Value.Count == 2 )
						victims += " and " + GetPlayerNameFromID( pair.Value[ 1 ] );
					else if( pair.Value.Count > 2 )
					{
						for( int i = 1; i < pair.Value.Count - 1; i ++ )
							victims += ", " + GetPlayerNameFromID( pair.Value[ i ] );
						victims += ", and " + GetPlayerNameFromID( pair.Value[ pair.Value.Count - 1 ] );
					}
					
					ChatToPlayer( player, "Wanted", murderer, victims );
				}
			}
			else
				ChatToPlayer( player, "NobodyWanted" );
		}
		
		
		void OnPlayerSleepEnded( BasePlayer player )
		{
			LockData();
			
			if( Config.Get<bool>("ShowOnWake") )
			{
				if( Config.Get< List<ulong> >("Sheriffs").Contains(player.userID) )
					ChatToPlayer( player, "CommandsSheriff" );
				else
					ChatToPlayer( player, "Commands" );
				
				ShowWantedListTo( player );
			}
			
			UnlockData();
		}
		
		
		[ChatCommand("wanted")]
		void WantedCommand( BasePlayer player, string command, string[] args )
		{
			LockData();
			ShowWantedListTo( player );
			UnlockData();
		}
		
		
		[ChatCommand("punish")]
		void PunishCommand( BasePlayer player, string command, string[] args )
		{
			LockData();
			
			if( IsMurderer(player.userID) )
			{
				string victims = GetPlayerNameFromID( Murderers[ player.userID ][ 0 ] );
				if( Murderers[ player.userID ].Count == 2 )
					victims += " and " + GetPlayerNameFromID( Murderers[ player.userID ][ 1 ] );
				else if( Murderers[ player.userID ].Count > 2 )
				{
					for( int i = 1; i < Murderers[ player.userID ].Count - 1; i ++ )
						victims += ", " + GetPlayerNameFromID( Murderers[ player.userID ][ i ] );
					victims += ", and " + GetPlayerNameFromID( Murderers[ player.userID ][ Murderers[ player.userID ].Count - 1 ] );
				}
				
				ChatToPlayer( player, "PunishForbidden", victims );
			}
			else if( IsKiller(player.userID) )
			{
				List<string> victim_list = new List<string>();
				foreach( KeyValuePair<ulong,ulong> pair in LastKillerOf )
				{
					if( pair.Value == player.userID )
						victim_list.Add( GetPlayerNameFromID(pair.Key) );
				}
				string victims = victim_list[ 0 ];
				if( victim_list.Count == 2 )
					victims += " and " + victim_list[ 1 ];
				else if( victim_list.Count > 2 )
				{
					for( int i = 1; i < victim_list.Count - 1; i ++ )
						victims += ", " + victim_list[ i ];
					victims += ", and " + victim_list[ victim_list.Count - 1 ];
				}
				
				ChatToPlayer( player, "PunishForbidden", victims );
			}
			else if( LastKillerOf.ContainsKey(player.userID) )
			{
				ulong murderer_id = LastKillerOf[ player.userID ];
				if( Murderers.ContainsKey(murderer_id) && Murderers[ murderer_id ].Contains(player.userID) )
					ChatToPlayer( player, "PunishAlready", GetPlayerNameFromID(murderer_id) );
				else
					PunishLastKillerOf( player.userID );
			}
			else
				ChatToPlayer( player, "PunishNotFound" );
			
			UnlockData();
		}
		
		
		[ChatCommand("forgive")]
		void ForgiveCommand( BasePlayer player, string command, string[] args )
		{
			LockData();
			
			ulong murderer_id = 0;
			
			if( args.Length > 0 && args[ 0 ].Length > 0 )
				murderer_id = GetPlayerIDFromName( args[ 0 ] );
			else if( LastKillerOf.ContainsKey(player.userID) )
				murderer_id = LastKillerOf[ player.userID ];
			else
			{
				foreach( KeyValuePair< ulong, List<ulong> > pair in Murderers )
				{
					if( pair.Value.Contains(player.userID) )
					{
						murderer_id = pair.Key;
						break;
					}
				}
				
				if( (murderer_id == 0) && LastAttackerOf.ContainsKey(player.userID) )
					murderer_id = LastAttackerOf[ player.userID ];
			}
			
			if( murderer_id != 0 )
			{
				string murderer = GetPlayerNameFromID( murderer_id );
				
				if( LastKillerOf.ContainsKey(player.userID) && (LastKillerOf[ player.userID ] == murderer_id) )
					LastKillerOf.Remove( player.userID );
				
				if( LastAttackerOf.ContainsKey(player.userID) && (LastAttackerOf[ player.userID ] == murderer_id) )
					LastAttackerOf.Remove( player.userID );
				
				if( Murderers.ContainsKey(murderer_id) && Murderers[ murderer_id ].Contains(player.userID) )
				{
					Murderers[ murderer_id ].Remove( player.userID );
					if( Murderers[ murderer_id ].Count == 0 )
					{
						Murderers.Remove( murderer_id );
						ChatToAll( "ForgiveByAll", murderer, player.displayName );
					}
					else
						ChatToAll( "ForgiveBySome", murderer, player.displayName );
					
					DataChanged = true;
				}
				else
					ChatToPlayer( player, "ForgiveKill", murderer );
			}
			else
				ChatToPlayer( player, "ForgiveNotFound" );
			
			UnlockData();
		}
		
		
		[ChatCommand("pardon")]
		void PardonCommand( BasePlayer player, string command, string[] args )
		{
			LockData();
			
			if( Config.Get< List<ulong> >("Sheriffs").Contains(player.userID) )
			{
				ulong murderer_id = 0;
				
				if( args.Length > 0 && args[ 0 ].Length > 0 )
					murderer_id = GetPlayerIDFromName( args[ 0 ] );
				
				if( murderer_id != 0 )
				{
					string murderer = GetPlayerNameFromID( murderer_id );
					
					foreach( KeyValuePair<ulong,ulong> pair in LastKillerOf )
					{
						if( pair.Value == murderer_id )
							LastKillerOf.Remove( pair.Key );
					}
					
					foreach( KeyValuePair<ulong,ulong> pair in LastAttackerOf )
					{
						if( pair.Value == murderer_id )
							LastAttackerOf.Remove( pair.Key );
					}
					
					if( Murderers.ContainsKey(murderer_id) )
					{
						Murderers.Remove( murderer_id );
						DataChanged = true;
						ChatToAll( "Pardon", murderer, player.displayName );
					}
					else
						ChatToPlayer( player, "PardonNotWanted", murderer );
				}
				else
					ChatToPlayer( player, "PardonNotFound" );
			}
			else
				ChatToPlayer( player, "PardonForbidden" );
			
			UnlockData();
		}
		
		
		void Loaded()
		{
			LockData();
			
			EN.Clear();
			EN[ "Loaded"          ] = "WantedForMurder version {0} loaded.";
			EN[ "Commands"        ] = "WantedForMurder commands: /wanted /punish /forgive";
			EN[ "CommandsSheriff" ] = "WantedForMurder commands: /wanted /punish /forgive /pardon  (You are a sheriff.)";
			EN[ "Wanted"          ] = "<color=#ff3333ff>{0}</color> is wanted for murdering {1}.";
			EN[ "NobodyWanted"    ] = "Nobody is currently wanted for murder.";
			EN[ "Punish"          ] = "<color=#ff3333ff>{0}</color> is now wanted for murdering {1}!";
			EN[ "PunishAlready"   ] = "You have already punished {0}.";
			EN[ "PunishNotFound"  ] = "Couldn't find anyone to punish.";
			EN[ "PunishForbidden" ] = "You cannot punish anyone until you are forgiven by {0}.";
			EN[ "ForgiveBySome"   ] = "<color=#ff3333ff>{0}</color> has been forgiven by {1} but is still wanted.";
			EN[ "ForgiveByAll"    ] = "{0} has been forgiven by {1} and is no longer wanted.";
			EN[ "ForgiveKill"     ] = "You forgave {0}.";
			EN[ "ForgiveNotFound" ] = "Couldn't find anyone to forgive.";
			EN[ "Pardon"          ] = "{0} has been pardoned of all crimes by Sheriff {1}.";
			EN[ "PardonNotWanted" ] = "{0} was not wanted.";
			EN[ "PardonNotFound"  ] = "Couldn't find anyone to pardon.";
			EN[ "PardonForbidden" ] = "Only a sheriff may pardon crimes.Try /forgive instead.";
			lang.RegisterMessages( EN, this );
			
			LoadConfig();
			if( SetUnconfiguredDefaults() )
				SaveConfig();
			LoadData();
			
			timer.Repeat( 1f, 0, () => { RemoveMurdererSleepingBags(); } );
			
			if( Config.Get<bool>("AnnounceWhenLoaded") )
				timer.Once( 1f, () => { ChatToAll( "Loaded", Version.ToString() ); } );
			
			UnlockData();
		}
	}
}

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