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

FREE AirdropExtended : 1.0.0 1.0.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Globalization;
using System.Reflection;
using System.Text.RegularExpressions;
using AirdropExtended;
using AirdropExtended.Airdrop.Services;
using AirdropExtended.Airdrop.Settings;
using AirdropExtended.Airdrop.Settings.Generate;
using AirdropExtended.Behaviors;
using AirdropExtended.Commands;
using AirdropExtended.Diagnostics;
using AirdropExtended.Permissions;
using AirdropExtended.Rust.Extensions;
using AirdropExtended.WeightedSearch;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Oxide.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Libraries;
using Oxide.Plugins;
using Rust;
using UnityEngine;
using Constants = AirdropExtended.Constants;
using LogType = Oxide.Core.Logging.LogType;
using Timer = Oxide.Core.Libraries.Timer;

// ReSharper disable once CheckNamespace

namespace Oxide.Plugins
{
	[Info(Constants.PluginName, "baton", "1.0.9", ResourceId = 1210)]
	[Description("Customizable airdrop")]
	public class AirdropExtended : RustPlugin
	{
		private readonly SettingsContext _settingsContext;
		private readonly AirdropController _airdropController;
		private Dictionary<string, AirdropExtendedCommand> _commands;

		public AirdropExtended()
		{
			_settingsContext = new SettingsContext(() => Config);
			_airdropController = new AirdropController(_settingsContext);
		}

		private void OnServerInitialized()
		{
			LoadConfig();
			Bootstrap();
		}

		protected override void LoadDefaultConfig()
		{
			var settings = AirdropSettingsFactory.CreateDefault();
			Config.WriteObject(settings);
		}

		private void Bootstrap()
		{
			LoadAireSettings();

			var commands = CommandFactory.Create(_settingsContext, _airdropController);
			PermissionService.RegisterPermissions(this, commands);

			_commands = commands.ToDictionary(c => c.Name, c => c);
			var consoleSystem = Interface.Oxide.GetLibrary<Command>();
			foreach (var command in commands.Where(c => !c.IsChatOnly))
			{
				var command1 = command;
				consoleSystem.AddConsoleCommand(command.Name, this, arg =>
				{
					command1.Execute(arg, arg.Player());
					return true;
				});
			}
		}

		private void LoadAireSettings()
		{
			Diagnostics.MessageToServer("Loaded settings");
			var previousSetting = Config.Get<string>("settingsName");
			if (!string.IsNullOrEmpty(previousSetting))
			{
				_settingsContext.Settings = AidropSettingsRepository.LoadFrom(previousSetting);
				Diagnostics.MessageToServer("Saved current config settings: {0} to normal config in config/AirdropExtended.json", previousSetting);
				Diagnostics.MessageToServer("Copied old settings file to data/{0}.json", previousSetting);
				AidropSettingsRepository.Save(_settingsContext.ConfigFile(), _settingsContext.Settings);
				AidropSettingsRepository.SaveTo(previousSetting, _settingsContext.Settings);
			}
			else
			{
				_settingsContext.Settings = AidropSettingsRepository.Load(Config);
			}
			_airdropController.ApplySettings();
		}

		private void Unload()
		{
			_airdropController.Cleanup();
		}

		void OnLootEntity(BasePlayer player, BaseEntity entity)
		{
			var supplyDrop = entity as SupplyDrop;
			if (entity == null || player == null || supplyDrop == null)
				return;

			var settings = _settingsContext.Settings;

			Diagnostics.MessageTo(
				settings.Localization.NotifyOnPlayerLootingStartedMessage,
				settings.CommonSettings.NotifyOnPlayerLootingStarted,
				player.displayName);
		}

		private void OnEntitySpawned(BaseEntity entity)
		{
			if (_airdropController.IsInitialized())
				_airdropController.OnEntitySpawned(entity);
		}

		private void OnExplosiveThrown(BasePlayer player, BaseEntity entity)
		{
			if (entity is SupplySignal)
				_airdropController.OnSupplySignal(player, entity);
		}

		#region command handlers

		[ChatCommand("aire.load")]
		private void LoadSettingsChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.load"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.save")]
		private void SaveSettingsChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.save"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.generate")]
		private void GenerateSettingsChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.generate"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.reload")]
		private void ReloadSettingsChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.reload"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.players")]
		private void SetPlayersChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.players"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.event")]
		private void SetEventEnabledChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.event"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.supply")]
		private void SetSupplyEnabledChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.supply"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.timer")]
		private void SetTimerEnabledChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.timer"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.despawntime")]
		private void SetDespawnTimeChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.despawntime"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.minfreq")]
		private void SetMinFrequencyChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.minfreq"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.maxfreq")]
		private void SetMaxFrequencyChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.maxfreq"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.setitem")]
		private void SetItemChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.setitem"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.setitemgroup")]
		private void SetItemGroupChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.setitemgroup"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.capacity")]
		private void SetDropCapacityChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.capacity"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.enableplanelimit")]
		private void EnablePlaneLimitChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.enableplanelimit"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.planelimit")]
		private void SetPlaneLimitChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.planelimit"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.planespeed")]
		private void SetPlaneSpeedChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.planespeed"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.crates")]
		private void SetCratesChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.crates"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.onelocation")]
		private void SetDropToOneLocationChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.onelocation"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.drop")]
		private void CallRandomDropChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.drop"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.massdrop")]
		private void CallMassDropChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.massdrop"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.topos")]
		private void CallDropToPosChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.topos"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.toplayer")]
		private void CallDropToPlayerChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.toplayer"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.tome")]
		private void CallDropToMeChatCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.tome"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.localize")]
		private void CallLocalizeCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.localize"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.notify")]
		private void CallNotifyCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.notify"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.customloot")]
		private void CallSetCustomLootCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.customloot"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.pick")]
		private void CallSetPickStrategyCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.pick"].ExecuteFromChat(player, command, args);
		}

		[ChatCommand("aire.test")]
		private void CallTestLootCommand(BasePlayer player, string command, string[] args)
		{
			_commands["aire.test"].ExecuteFromChat(player, command, args);
		}

		#endregion
	}
}

namespace AirdropExtended
{
	public sealed class Constants
	{
		public const string PluginName = "AirdropExtended";
		public const string CargoPlanePrefab = "assets/prefabs/npc/cargo plane/cargo_plane.prefab";
	}

	public sealed class SettingsContext
	{
		public SettingsContext([NotNull] Func<DynamicConfigFile> configFile)
		{
			if (configFile == null) throw new ArgumentNullException("configFile");
			ConfigFile = configFile;
		}

		public AirdropSettings Settings { get; set; }
		public Func<DynamicConfigFile> ConfigFile { get; set; }
	}
}

namespace AirdropExtended.Rust.Extensions
{
	public static class LocalizationExtensions
	{
		public static string GetDirectionsFromAngle(float angle, DirectionLocalizationSettings settings)
		{
			if (settings == null) throw new ArgumentNullException("settings");

			if (angle > 337.5 || angle < 22.5)
				return settings.North;
			if (angle > 22.5 && angle < 67.5)
				return settings.NorthEast;
			if (angle > 67.5 && angle < 112.5)
				return settings.East;
			if (angle > 112.5 && angle < 157.5)
				return settings.SouthEast;
			if (angle > 157.5 && angle < 202.5)
				return settings.South;
			if (angle > 202.5 && angle < 247.5)
				return settings.SouthWest;
			if (angle > 247.5 && angle < 292.5)
				return settings.West;
			if (angle > 292.5 && angle < 337.5)
				return settings.NorthWest;
			return string.Empty;
		}
	}

	public static class CargoPlaneExtensions
	{
		public static void SetPlaneEndPosition(
			this CargoPlane plane,
			Vector3 startPosition,
			Vector3 endPosition,
			int planeSpeedInSeconds)
		{
			if (plane == null) throw new ArgumentNullException("plane");
			CargoPlaneFields.StartPositionField.SetValue(plane, startPosition);
			CargoPlaneFields.EndPositionField.SetValue(plane, endPosition);

			plane.SetSpeed(startPosition, endPosition, planeSpeedInSeconds);
		}

		public static void SetSpeed(this CargoPlane plane, Vector3 startPosition, Vector3 endPosition, int planeSpeedInSeconds)
		{
			if (plane == null) throw new ArgumentNullException("plane");
			var speed = Vector3.Distance(endPosition, startPosition) / planeSpeedInSeconds;
			plane.transform.rotation = Quaternion.LookRotation(endPosition - startPosition);

			CargoPlaneFields.SecondsTakenField.SetValue(plane, 0);
			CargoPlaneFields.SecondsToTakeField.SetValue(plane, speed);
		}

		public static void SetSpeed(this CargoPlane plane, int planeSpeedInSeconds)
		{
			if (plane == null) throw new ArgumentNullException("plane");
			var startPosition = (Vector3)CargoPlaneFields.StartPositionField.GetValue(plane);
			var endPosition = (Vector3)CargoPlaneFields.EndPositionField.GetValue(plane);

			plane.SetSpeed(startPosition, endPosition, planeSpeedInSeconds);
		}

		public static void NotifyNextDropPosition(this CargoPlane plane, Vector3 dropPos, AirdropSettings settings)
		{
			Diagnostics.Diagnostics.MessageTo(
				settings.Localization.NotifyOnNextDropPositionMessage,
				settings.CommonSettings.NotifyOnNextDropPosition,
				dropPos.x,
				dropPos.y,
				dropPos.z);
		}
	}
}

namespace AirdropExtended.Behaviors
{
	public sealed class SupplyDropLandedBehavior : MonoBehaviour
	{
		private const string DefaultNotifyOnCollisionMessage = "Supply drop has landed at {0:F0},{1:F0},{2:F0}";

		private bool _isTriggered;

		public string NotifyOnLandedMessage { get; set; }
		public bool NotifyOnLanded { get; set; }

		public bool NotifyAboutPlayersAroundOnDropLand { get; set; }
		public string NotifyAboutPlayersAroundOnDropLandMessage { get; set; }

		public bool NotifyAboutDirectionAroundOnDropLand { get; set; }
		public string NotifyAboutDirectionAroundOnDropLandMessage { get; set; }

		public int DropNotifyMaxDistance { get; set; }

		public DirectionLocalizationSettings Settings { get; set; }

		public SupplyDropLandedBehavior()
		{
			NotifyOnLandedMessage = DefaultNotifyOnCollisionMessage;
			NotifyOnLanded = true;
		}

		void OnCollisionEnter(Collision col)
		{
			if (_isTriggered || col.gameObject.GetComponent<CargoPlane>() != null)
				return;

			_isTriggered = true;

			var baseEntity = GetComponent<BaseEntity>();

			var dropPosition = baseEntity.transform.position;
			var landedX = dropPosition.x;
			var landedY = dropPosition.y;
			var landedZ = dropPosition.z;

			Diagnostics.Diagnostics.MessageTo(NotifyOnLandedMessage, NotifyOnLanded, landedX, landedY, landedZ);

			if (NotifyAboutDirectionAroundOnDropLand || NotifyAboutPlayersAroundOnDropLand)
				NotifyPlayersAround(dropPosition, baseEntity);

			var despawnBehavior = baseEntity.GetComponent<SupplyDropDespawnBehavior>();
			if (despawnBehavior != null)
				despawnBehavior.Despawn();
		}

		private void NotifyPlayersAround(Vector3 dropPosition, BaseEntity baseEntity)
		{
			var players = BasePlayer.activePlayerList;
			var nearbyPlayers = players.Where(p => Vector3.Distance(p.transform.position, dropPosition) < DropNotifyMaxDistance).ToList();

			foreach (var player in nearbyPlayers)
			{
				var distance = Vector3.Distance(player.transform.position, dropPosition);
				var dropVector = (baseEntity.transform.position - player.eyes.position).normalized;
				var rotation = Quaternion.LookRotation(dropVector);

				var compassDirection = LocalizationExtensions.GetDirectionsFromAngle(rotation.eulerAngles.y, Settings);

				if (NotifyAboutDirectionAroundOnDropLand)
					Diagnostics.Diagnostics.MessageToPlayer(player, NotifyAboutDirectionAroundOnDropLandMessage, distance, compassDirection);
				if (NotifyAboutPlayersAroundOnDropLand)
					Diagnostics.Diagnostics.MessageToPlayer(player, NotifyAboutPlayersAroundOnDropLandMessage, nearbyPlayers.Count);
			}
		}

		public static void AddTo(
			BaseEntity entity,
			AirdropSettings settings)
		{
			if (entity == null) throw new ArgumentNullException("entity");
			if (settings == null) throw new ArgumentNullException("settings");

			entity.gameObject.AddComponent<SupplyDropLandedBehavior>();

			var dropCollisionCheck = entity.gameObject.GetComponent<SupplyDropLandedBehavior>();

			dropCollisionCheck.NotifyOnLanded = settings.CommonSettings.NotifyOnCollision;
			dropCollisionCheck.NotifyOnLandedMessage = settings.Localization.NotifyOnCollisionMessage;

			dropCollisionCheck.DropNotifyMaxDistance = settings.CommonSettings.DropNotifyMaxDistance;

			dropCollisionCheck.NotifyAboutDirectionAroundOnDropLand = settings.CommonSettings.NotifyAboutDirectionAroundOnDropLand;
			dropCollisionCheck.NotifyAboutDirectionAroundOnDropLandMessage = settings.Localization.NotifyAboutDirectionAroundOnDropLandMessage;

			dropCollisionCheck.NotifyAboutPlayersAroundOnDropLand = settings.CommonSettings.NotifyAboutPlayersAroundOnDropLand;
			dropCollisionCheck.NotifyAboutPlayersAroundOnDropLandMessage = settings.Localization.NotifyAboutPlayersAroundOnDropLandMessage;

			dropCollisionCheck.Settings = settings.Localization.Directions;
		}

	}

	public sealed class SupplyDropDespawnBehavior : MonoBehaviour
	{
		private const string DefaultNotifyOnDespawnMessage = "Supply drop has been despawned at <color=red>{0:F0},{1:F0},{2:F0}</color>";
		private const float DefaultSupplyStayTime = 300.0f;

		private bool _isTriggered;
		private Timer.TimerInstance _timerInstance;
		private BaseEntity _baseEntity;

		public float TimeoutInSeconds { get; set; }

		public string NotifyOnDespawnMessage { get; set; }
		public bool NotifyOnDespawn { get; set; }

		public SupplyDropDespawnBehavior()
		{
			TimeoutInSeconds = DefaultSupplyStayTime;
			NotifyOnDespawnMessage = DefaultNotifyOnDespawnMessage;
			NotifyOnDespawn = false;
		}

		public void Despawn()
		{
			if (_isTriggered)
				return;

			_baseEntity = gameObject.GetComponent<BaseEntity>();
			_isTriggered = true;

			_timerInstance = Interface.Oxide.GetLibrary<Timer>("Timer").Once(TimeoutInSeconds, DespawnCallback);
		}

		private void DespawnCallback()
		{
			var x = _baseEntity.transform.position.x;
			var y = _baseEntity.transform.position.y;
			var z = _baseEntity.transform.position.z;

			Diagnostics.Diagnostics.MessageTo(NotifyOnDespawnMessage, NotifyOnDespawn, x, y, z);
			_baseEntity.KillMessage();

			OnDestroy();
		}

		void OnDestroy()
		{
			_baseEntity = null;

			if (_timerInstance == null || _timerInstance.Destroyed)
				return;

			_timerInstance.Destroy();
			_timerInstance = null;
			_isTriggered = false;
		}

		public static void AddTo(BaseEntity supplyDrop, AirdropSettings settings)
		{
			if (supplyDrop == null) throw new ArgumentNullException("supplyDrop");
			if (settings == null) throw new ArgumentNullException("settings");

			var supplyCrateDespawnTime = settings.CommonSettings.SupplyCrateDespawnTime;
			if (supplyCrateDespawnTime <= TimeSpan.Zero)
				return;

			var timeoutInSeconds = Convert.ToSingle(supplyCrateDespawnTime.TotalSeconds);

			supplyDrop.gameObject.AddComponent<SupplyDropDespawnBehavior>();
			var despawnBehavior = supplyDrop.gameObject.GetComponent<SupplyDropDespawnBehavior>();

			despawnBehavior.TimeoutInSeconds = timeoutInSeconds;
			despawnBehavior.NotifyOnDespawn = settings.CommonSettings.NotifyOnDespawn;
			despawnBehavior.NotifyOnDespawnMessage = settings.Localization.NotifyOnDespawnMessage;
		}
	}

	public sealed class PlaneNotifyOnDestroyBehavior : MonoBehaviour
	{
		public Action<CargoPlane> Callback { get; set; }

		void OnDestroy()
		{
			Diagnostics.Diagnostics.MessageToServer("On destroy plane");
			if (Callback == null)
				return;

			var cargoPlane = GetComponent<CargoPlane>();
			if (cargoPlane != null)
			{
				Callback(cargoPlane);
				Diagnostics.Diagnostics.MessageToServer("cargoPlane [id:{0}] was destroyed", cargoPlane.GetInstanceID());
			}

			Callback = null;
		}
	}

	public sealed class MultipleCratesBehavior : MonoBehaviour
	{
		public int TotalCratesToDrop { get; set; }
		public Vector3 InitialEndPosition { get; set; }
		public bool DropToOneLocation { get; set; }
		public int DroppedCrates { get; set; }

		private Vector3 IntersectionPoint { get; set; }

		public void OnPlaneDroppedCrate(CargoPlane plane, AirdropSettings settings, Vector3 position)
		{
			DroppedCrates++;
			var planeSpeedInSeconds = settings.CommonSettings.PlaneSpeedInSeconds;
			if (DroppedCrates >= TotalCratesToDrop)
			{
				plane.SetPlaneEndPosition(position, InitialEndPosition, planeSpeedInSeconds);
				return;
			}

			if (IntersectionPoint == Vector3.zero)
				IntersectionPoint = GetIntersectionPoint(settings.DropLocation, position, InitialEndPosition);

			CargoPlaneFields.DroppedField.SetValue(plane, false);

			Vector3 currentEndPos;
			Vector3 nextDropPosition;
			if (DropToOneLocation)
			{
				currentEndPos = Vector3.MoveTowards(position, InitialEndPosition, 50f);
				nextDropPosition = Vector3.MoveTowards(position, InitialEndPosition,
					25f);
			}
			else
			{
				var cratesToDrop = (TotalCratesToDrop - DroppedCrates);
				var distanceToNextEndPos = Vector3.Distance(position, IntersectionPoint) / cratesToDrop;
				var distanceToNextDrop = distanceToNextEndPos / 2;
				currentEndPos = Vector3.MoveTowards(position, IntersectionPoint, distanceToNextEndPos);
				nextDropPosition = Vector3.MoveTowards(position, IntersectionPoint, distanceToNextDrop);
			}
			plane.NotifyNextDropPosition(nextDropPosition, settings);
			CargoPlaneFields.DropPositionField.SetValue(plane, nextDropPosition);
			plane.SetPlaneEndPosition(position, currentEndPos, planeSpeedInSeconds);
		}

		public Vector3 GetIntersectionPoint(DropLocationSettings settings, Vector3 position, Vector3 endpos)
		{
			var lines = new List<Vector2[]>
			{
				new[] {new Vector2(settings.MinX, settings.MinZ), new Vector2(settings.MinX, settings.MaxZ)},
				new[] {new Vector2(settings.MinX, settings.MaxZ), new Vector2(settings.MaxX, settings.MaxZ)},
				new[] {new Vector2(settings.MaxX, settings.MaxZ), new Vector2(settings.MaxX, settings.MinZ)},
				new[] {new Vector2(settings.MaxX, settings.MinZ), new Vector2(settings.MinX, settings.MinZ)},
			};

			var lineStart = new Vector2(position.x, position.z);
			var lineEnd = new Vector2(endpos.x, endpos.z);

			foreach (var line in lines)
			{
				var intersectionPoint = LineIntersectionPoint(line[0], line[1], lineStart, lineEnd);
				if (intersectionPoint != Vector2.zero)
					return new Vector3(intersectionPoint.x, position.y, intersectionPoint.y);
			}

			return Vector3.zero;
		}

		private Vector2 LineIntersectionPoint(Vector2 lineOneStart, Vector2 lineOneEnd1, Vector2 lineTwoStart, Vector2 lineTwoEnd)
		{
			var d = (lineOneStart.x - lineOneEnd1.x) * (lineTwoStart.y - lineTwoEnd.y) - (lineOneStart.y - lineOneEnd1.y) * (lineTwoStart.x - lineTwoEnd.x);
			if (Math.Abs(d) < 0.01)
				return Vector2.zero;

			var xi = ((lineTwoStart.x - lineTwoEnd.x) * (lineOneStart.x * lineOneEnd1.y - lineOneStart.y * lineOneEnd1.x) - (lineOneStart.x - lineOneEnd1.x) * (lineTwoStart.x * lineTwoEnd.y - lineTwoStart.y * lineTwoEnd.x)) / d;
			var yi = ((lineTwoStart.y - lineTwoEnd.y) * (lineOneStart.x * lineOneEnd1.y - lineOneStart.y * lineOneEnd1.x) - (lineOneStart.y - lineOneEnd1.y) * (lineTwoStart.x * lineTwoEnd.y - lineTwoStart.y * lineTwoEnd.x)) / d;

			var p = new Vector2(xi, yi);
			if (xi < Math.Min(lineOneStart.x, lineOneEnd1.x) || xi > Math.Max(lineOneStart.x, lineOneEnd1.x))
				return Vector2.zero;

			if (xi < Math.Min(lineTwoStart.x, lineTwoEnd.x) || xi > Math.Max(lineTwoStart.x, lineTwoEnd.x))
				return Vector2.zero;

			return p;
		}
	}

	public static class SupplyDropBehaviorService
	{
		public static void AttachCustomBehaviorsToSupplyDrops(AirdropSettings settings)
		{
			if (settings == null)
				throw new ArgumentNullException("settings");

			var supplyDrops = UnityEngine.Object.FindObjectsOfType<SupplyDrop>();

			foreach (var supplyDrop in supplyDrops)
			{
				var despawnBehavior = supplyDrop.GetComponent<SupplyDropDespawnBehavior>();
				if (Equals(despawnBehavior, null))
					SupplyDropDespawnBehavior.AddTo(supplyDrop, settings);

				despawnBehavior = supplyDrop.GetComponent<SupplyDropDespawnBehavior>();
				var hasParachute = HasParachute(supplyDrop);

				var collisionBehavior = supplyDrop.GetComponent<SupplyDropLandedBehavior>();
				if (hasParachute && Equals(collisionBehavior, null))
					SupplyDropLandedBehavior.AddTo(supplyDrop, settings);

				if (hasParachute)
					continue;

				despawnBehavior.Despawn();
			}
		}

		private static bool HasParachute(SupplyDrop supplyDrop)
		{
			var parachuteField = typeof(SupplyDrop).GetField("parachute",
				Interface.Oxide.GetLibrary<Oxide.Game.Rust.Libraries.Rust>().PrivateBindingFlag());
			if (parachuteField == null)
				return false;

			return parachuteField.GetValue(supplyDrop) != null;
		}

		public static void RemoveCustomBehaviorsFromSupplyDrops()
		{
			var despawnBehaviors = UnityEngine.Object.FindObjectsOfType<SupplyDropDespawnBehavior>();
			if (despawnBehaviors != null && despawnBehaviors.Any())
			{
				foreach (var despawnBehavior in despawnBehaviors)
					UnityEngine.Object.Destroy(despawnBehavior);
			}

			var landBehaviors = UnityEngine.Object.FindObjectsOfType<SupplyDropLandedBehavior>();
			if (landBehaviors != null && landBehaviors.Any())
			{
				foreach (var landBehavior in landBehaviors)
					UnityEngine.Object.Destroy(landBehavior);
			}
		}
	}
}

namespace AirdropExtended.Diagnostics
{
	public static class Diagnostics
	{
		public static string Prefix = "aire:";
		public static string Color = "orange";
		private const string Format = "<color={0}>{1}</color>";

		public static void MessageTo(string message, bool sendToAll, params object[] args)
		{
			if (sendToAll)
				MessageToAll(message, args);
			MessageToServer(message, args);
		}

		public static void MessageToPlayer(BasePlayer player, string message, params object[] args)
		{
			player.SendConsoleCommand("chat.add", new object[] { 0, string.Format(Format, Color, Prefix) + string.Format(message, args), 1f });
		}

		public static void MessageToAll(string message, params object[] args)
		{
			var msg = string.Format(Format, Color, Prefix) + string.Format(message, args);
			ConsoleSystem.Broadcast("chat.add \"SERVER\" " + msg.Quote() + " 1.0", new object[0]);
		}

		public static void MessageToServer(string message, params object[] args)
		{
			Interface.GetMod().RootLogger.Write(LogType.Info, string.Format("{0}{1}", Prefix, message), args);
		}

		public static void MessageToServerAndPlayer(BasePlayer player, string message, params object[] args)
		{
			if (player != null)
				MessageToPlayer(player, message, args);
			MessageToServer(message, args);
		}
	}
}

namespace AirdropExtended.Permissions
{
	public static class PermissionService
	{
		public static Permission Permission = Interface.GetMod().GetLibrary<Permission>();

		public static bool HasPermission(BasePlayer player, string permissionName)
		{
			if (player == null || string.IsNullOrEmpty(permissionName))
				return false;

			var uid = Convert.ToString(player.userID);
			if (Permission.UserHasPermission(uid, permissionName))
				return true;

			return false;
		}

		public static void RegisterPermissions(Plugin owner, List<AirdropExtendedCommand> commands)
		{
			if (owner == null) throw new ArgumentNullException("owner");
			if (commands == null) throw new ArgumentNullException("commands");

			foreach (var permissionName in commands.Select(c => c.PermissionName))
			{
				if (!Permission.PermissionExists(permissionName))
					Permission.RegisterPermission(permissionName, owner);
			}
		}
	}
}

namespace AirdropExtended.Commands
{
	public abstract class AirdropExtendedCommand
	{
		public string Name { get; private set; }
		public string PermissionName { get; private set; }
		public bool IsChatOnly { get; private set; }

		protected AirdropExtendedCommand(string name, string permissionName = "", bool chatOnly = false)
		{
			if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");

			Name = name;
			PermissionName = permissionName;
			IsChatOnly = chatOnly;
		}

		public virtual void ExecuteFromChat(BasePlayer player, string command, string[] args)
		{
			if (player == null || !PermissionService.HasPermission(player, PermissionName) || !player.IsAdmin())
			{
				Diagnostics.Diagnostics.MessageToPlayer(player, "You are not admin.You are required to have permission \"{0}\" to run command: {1}", PermissionName, Name);
				return;
			}

			var commandString = args.Aggregate(command, (s, s1) => s + " " + s1.Quote());
			Diagnostics.Diagnostics.MessageToServer("'{0}' called by {1}", commandString, player.displayName);
			var commandArgs = new ConsoleSystem.Arg(commandString);
			ExecuteInternal(commandArgs, player);
		}

		public virtual void Execute(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (player != null && !PermissionService.HasPermission(player, PermissionName) && !player.IsAdmin())
			{
				Diagnostics.Diagnostics.MessageToPlayer(player, "You are not admin.You are required to have permission \"{0}\" to run command: {1}", PermissionName, Name);
				return;
			}

			ExecuteInternal(arg, player);
		}

		protected abstract void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player);

		protected void PrintUsage(BasePlayer player)
		{
			var message = GetUsageString();
			if (player != null)
				Diagnostics.Diagnostics.MessageToPlayer(player, message);
			Diagnostics.Diagnostics.MessageToServer(message);
		}

		protected virtual string GetUsageString()
		{
			return GetDefaultUsageString();
		}

		protected string GetDefaultUsageString(params string[] parameters)
		{
			var parameterString = string.Join(" ", parameters);
			return string.Format("Command use {0} {1}", Name, parameterString);
		}
	}

	public class LoadSettingsCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public LoadSettingsCommand(
			SettingsContext context,
			AirdropController controller)
			: base("aire.load", "airdropextended.canLoad")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");

			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var settingsName = arg.GetString(0);
			if (string.IsNullOrEmpty(settingsName))
			{
				PrintUsage(player);
				return;
			}

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Loading settings: {0}", settingsName);

			var settings = AidropSettingsRepository.LoadFrom(settingsName);
			if (settings == null)
			{
				Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Failed to load settings, no such file: ", settingsName);
				return;
			}

			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("settingsName");
		}
	}

	public class ReloadSettingsCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public ReloadSettingsCommand(
			SettingsContext context,
			AirdropController controller)
			: base("aire.reload", "airdropextended.canReload")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Reloading plugin");

			_context.Settings = AidropSettingsRepository.Load(_context.ConfigFile());
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("settingsName");
		}
	}

	public class SaveSettingsCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;

		public SaveSettingsCommand(SettingsContext context)
			: base("aire.save", "airdropextended.canSave")
		{
			if (context == null) throw new ArgumentNullException("context");
			_context = context;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			var settingsName = arg.GetString(0, string.Empty);

			if (string.IsNullOrEmpty(settingsName))
			{
				AidropSettingsRepository.Save(_context.ConfigFile(), _context.Settings);
				Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Saved settings to default config");
				return;
			}

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Saving settings to: {0}", settingsName);

			AidropSettingsRepository.SaveTo(settingsName, _context.Settings);
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("settingsName");
		}
	}

	public class GenerateDefaultSettingsAndSaveCommand : AirdropExtendedCommand
	{
		public GenerateDefaultSettingsAndSaveCommand()
			: base("aire.generate", "airdropextended.canGenerate")
		{ }

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var settingsName = arg.GetString(0);
			if (string.IsNullOrEmpty(settingsName))
			{
				PrintUsage(player);
				return;
			}

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Generating default settings to {0}", settingsName);

			var settings = AirdropSettingsFactory.CreateDefault();
			AidropSettingsRepository.SaveTo(settingsName, settings);
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("settingsName");
		}
	}

	public class SetDropMinFrequencyCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetDropMinFrequencyCommand(SettingsContext context, AirdropController controller)
			: base("aire.minfreq", "airdropextended.canMinFreq")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var frequency = arg.GetInt(0);
			frequency = frequency < 0 ? 0 : frequency;
			_context.Settings.CommonSettings.MinDropFrequency = TimeSpan.FromSeconds(frequency);

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Setting min frequency to {0}", frequency);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("3600");
		}
	}

	public class SetDropMaxFrequencyCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetDropMaxFrequencyCommand(SettingsContext context, AirdropController controller)
			: base("aire.maxfreq", "airdropextended.canMaxFreq")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");

			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var frequency = arg.GetInt(0);
			frequency = frequency < 0 ? 0 : frequency;
			_context.Settings.CommonSettings.MaxDropFrequency = TimeSpan.FromSeconds(frequency);

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Setting max frequency to {0}", frequency);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("3600");
		}
	}

	public class SetPlayersCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetPlayersCommand(SettingsContext context, AirdropController controller)
			: base("aire.players", "airdropextended.canPlayers")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var players = arg.GetInt(0);
			players = players < 0 ? 0 : players;
			_context.Settings.CommonSettings.MinimumPlayerCount = players;

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Setting min players to {0}", players);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("25");
		}
	}

	public class SetTimerEnabledCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetTimerEnabledCommand(SettingsContext context, AirdropController controller)
			: base("aire.timer", "airdropextended.canTimer")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var pluginAirdropTimerEnabled = arg.GetBool(0);

			_context.Settings.CommonSettings.PluginAirdropTimerEnabled = pluginAirdropTimerEnabled;

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Setting plugin timer enabled to {0}", pluginAirdropTimerEnabled);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("true");
		}
	}

	public class SetEventEnabledCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetEventEnabledCommand(SettingsContext context, AirdropController controller)
			: base("aire.event", "airdropextended.canEvent")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var builtInAirdropEnabled = arg.GetBool(0);

			_context.Settings.CommonSettings.BuiltInAirdropEnabled = builtInAirdropEnabled;

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Setting built in airdrop enabled to {0}", builtInAirdropEnabled);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("true");
		}
	}

	public class SetSupplyDropEnabledCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetSupplyDropEnabledCommand(SettingsContext context, AirdropController controller)
			: base("aire.supply", "airdropextended.canSupply")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var supplyDropTimerEnabled = arg.GetBool(0);

			_context.Settings.CommonSettings.SupplySignalsEnabled = supplyDropTimerEnabled;

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Setting supply signals enabled to {0}", supplyDropTimerEnabled);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("true");
		}
	}

	public class SetPlaneSpeedCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetPlaneSpeedCommand(SettingsContext context, AirdropController controller)
			: base("aire.planespeed", "airdropextended.canPlaneSpeed")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var planeSpeedInSeconds = arg.GetInt(0);
			_context.Settings.CommonSettings.PlaneSpeedInSeconds = planeSpeedInSeconds;

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Setting plane speed in seconds to {0}", planeSpeedInSeconds);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("300");
		}
	}

	public class SetCrateCountCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetCrateCountCommand(SettingsContext context, AirdropController controller)
			: base("aire.crates", "airdropextended.canCrates")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var minCrates = arg.GetInt(0);
			var maxCrates = arg.HasArgs(2) ? arg.GetInt(1) : minCrates;
			_context.Settings.CommonSettings.MinCrates = minCrates;
			_context.Settings.CommonSettings.MaxCrates = maxCrates;

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Setting min/max crates to {0}-{1}", minCrates, maxCrates);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("300");
		}
	}

	public class SetDropToOneLocationCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetDropToOneLocationCommand(SettingsContext context, AirdropController controller)
			: base("aire.onelocation", "airdropextended.canOneLocation")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var oneLocation = arg.GetBool(0);
			_context.Settings.CommonSettings.DropToOneLocation = oneLocation;

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Setting drop to one location to {0}", oneLocation);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("true");
		}
	}

	public class SetPlaneLimitEnabledCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetPlaneLimitEnabledCommand(SettingsContext context, AirdropController controller)
			: base("aire.enableplanelimit", "airdropextended.canEnablePlaneLimit")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var maximumPlaneLimitEnabled = arg.GetBool(0);

			_context.Settings.CommonSettings.MaximumPlaneLimitEnabled = maximumPlaneLimitEnabled;

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Setting plane limit enabled to {0}", maximumPlaneLimitEnabled);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("true");
		}
	}

	public class SetPlaneLimitCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetPlaneLimitCommand(SettingsContext context, AirdropController controller)
			: base("aire.planelimit", "airdropextended.canPlaneLimit")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var planeLimit = arg.GetInt(0);
			planeLimit = planeLimit < 0 ? 0 : planeLimit;
			_context.Settings.CommonSettings.MaximumNumberOfPlanesInTheAir = planeLimit;

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Setting plane in air limit to {0}", planeLimit);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("10");
		}
	}

	public class SetDespawnTimeCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;

		public SetDespawnTimeCommand(SettingsContext context, AirdropController controller)
			: base("aire.despawntime", "airdropextended.canDespawnTime")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			var despawnTimeInSeconds = arg.GetInt(0);
			despawnTimeInSeconds = despawnTimeInSeconds < 0 ? 0 : despawnTimeInSeconds;
			_context.Settings.CommonSettings.SupplyCrateDespawnTime = TimeSpan.FromSeconds(despawnTimeInSeconds);

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player, "Set SupplyCrateDespawnTime to {0}", _context.Settings.CommonSettings.SupplyCrateDespawnTime);
			_controller.ApplySettings();
		}

		protected override string GetUsageString()
		{
			return GetDefaultUsageString("300");
		}
	}

	public class SetItemSettingsCommand : AirdropExtendedCommand
	{
		private readonly SettingsContext _context;
		private readonly AirdropController _controller;
		private readonly string _usageString;

		public SetItemSettingsCommand(SettingsContext context, AirdropController controller)
			: base("aire.setitem", "airdropextended.canSetItem")
		{
			if (context == null) throw new ArgumentNullException("context");
			if (controller == null) throw new ArgumentNullException("controller");
			_context = context;
			_controller = controller;

			var usageStrings = new[]
			{
				GetDefaultUsageString("item_name [category] [chance] [min] [max]"),
				string.Format("Example: {0} Weapon rocket_launcher 15 1 1 false.", Name),
				"default chance=0, min=0, max=0."
			};

			_usageString = string.Join(Environment.NewLine, usageStrings);
		}

		protected override void ExecuteInternal(ConsoleSystem.Arg arg, BasePlayer player)
		{
			if (!arg.HasArgs())
			{
				PrintUsage(player);
				return;
			}

			string categoryName;
			string itemName;
			float chance;
			int minAmount;
			int maxAmount;

			try
			{
				categoryName = arg.GetString(0);
				itemName = arg.GetString(1);
				chance = arg.GetFloat(2);
				minAmount = arg.GetInt(3);
				maxAmount = arg.GetInt(4);
			}
			catch (Exception)
			{
				PrintUsage(player);
				return;
			}

			var item = _context.Settings.FindItem(categoryName, itemName);

			item.ChanceInPercent = chance;
			item.MinAmount = minAmount;
			item.MaxAmount = maxAmount;

			Diagnostics.Diagnostics.MessageToServerAndPlayer(player,
			"Set settings to item:{0}, chance:{1}, min_amount:{2}, max_amount:{3}",
			itemName,
			chance,
			minAmount,
			maxAmount);

			_control
// ... [Code preview truncated due to length. Full source in attached file] ...

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