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

FREE PortableFurnaces : 1.0.4 1.0.4

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

namespace Oxide.Plugins
{
	[Info("PortableFurnaces", "Raul-Sorin Sorban", "1.0.4")]
	[Description("Allows players to privately access furnaces from afar.")]
	public class PortableFurnaces : RustPlugin
	{
		public static PortableFurnaces Instance { get; set; }

		public Dictionary<ulong, BaseOven> Furnaces { get; set; } = new Dictionary<ulong, BaseOven>();
		public Dictionary<ulong, float> CooledDownPlayers { get; set; } = new Dictionary<ulong, float>();

		public BaseOven GetFurnace(BasePlayer player)
		{
			foreach (var x in Furnaces)
			{
				if (x.Key == player.userID)
				{
					var furnace = x.Value;

					if (furnace != null)
					{
						furnace.transform.position = GetPosition(player);
						furnace.SendNetworkUpdateImmediate();
						furnace.UpdateNetworkGroup();
					}

					return furnace;
				}
			}

			return null;
		}
		public BaseOven SetFurnace(BasePlayer player, BaseOven furnace)
		{
			if (Furnaces.ContainsKey(player.userID))
				Furnaces[player.userID] = furnace;
			else Furnaces.Add(player.userID, furnace);

			return furnace;
		}
		public bool CanOpenFurnace(BasePlayer player, out string reason)
		{
			reason = null;

			if (IsCooledDown(player, false))
			{
				reason = string.Format(Config.Phrases.CooledDown, CooldownSecondsLeft(player).ToString("0"));
				return false;
			}

			if (!Config.Rules.CanUseFurnaceWhileBuildingBlocked && !player.CanBuild())
			{
				reason = Config.Phrases.BuildingBlocked;
				return false;
			}

			if (NoEscape != null)
			{
				if (!Config.Rules.CanUseFurnaceWhileCombatBlocked && NoEscape.Call<bool>("IsCombatBlocked", player))
				{
					reason = Config.Phrases.CombatBlocked;
					return false;
				}

				if (!Config.Rules.CanUseFurnaceWhileRaidBlocked && NoEscape.Call<bool>("IsRaidBlocked", player))
				{
					reason = Config.Phrases.RaidBlocked;
					return false;
				}
			}

			return true;
		}
		public bool HasLockerContents(BasePlayer player)
		{
			var locker = GetFurnace(player);
			if (locker == null) return false;

			return locker.inventory.itemList.Count > 0;
		}
		public bool IsCooledDown(BasePlayer player, bool coolDownPlayer = true)
		{
			foreach (var group in Config.GroupCooldowns)
			{
				if (permission.UserHasGroup(player.UserIDString, group.Key))
				{
					if (CooledDownPlayers.ContainsKey(player.userID))
					{
						if (Time.realtimeSinceStartup - CooledDownPlayers[player.userID] > group.Value)
						{
							if (coolDownPlayer)
							{
								CooledDownPlayers[player.userID] = Time.realtimeSinceStartup;
								return true;
							}
							else
							{
								CooledDownPlayers.Remove(player.userID);
								return false;
							}
						}
						else
						{
							return true;
						}
					}
					else if (coolDownPlayer)
					{
						CooledDownPlayers.Add(player.userID, Time.realtimeSinceStartup);
						return true;
					}
				}
			}

			return false;
		}
		public float CooldownSecondsLeft(BasePlayer player)
		{
			if (IsCooledDown(player, false))
			{
				foreach (var group in Config.GroupCooldowns)
				{
					if (permission.UserHasGroup(player.UserIDString, group.Key))
					{
						return group.Value - (Time.realtimeSinceStartup - CooledDownPlayers[player.userID]);
					}
				}
			}

			return 0f;
		}

		public const string CampfirePrefab = "assets/prefabs/deployable/campfire/campfire.prefab";
		public const string FurnacePrefab = "assets/prefabs/deployable/furnace/furnace.prefab";
		public const string LargeFurnacePrefab = "assets/prefabs/deployable/furnace.large/furnace.large.prefab";
		public const string SmallOilRefineryPrefab = "assets/prefabs/deployable/oil refinery/refinery_small_deployed.prefab";
		public const string OpenEffect = "assets/prefabs/deployable/furnace/effects/furnace-deploy.prefab";

		public enum FurnaceTypes
		{
			Campfire,
			Furnace,
			LargeFurnace,
			SmallOilRefinery
		}

		#region Permissions

		public const string UsePerm = "portablefurnaces.use";

		public void InstallPermissions()
		{
			permission.RegisterPermission(UsePerm, this);
		}

		private bool HasPermission(BasePlayer player, string perm, bool quiet = false)
		{
			if (!permission.UserHasPermission(player.UserIDString, perm))
			{
				if (!quiet) Print($"You need to have the \"{perm}\" permission.", player);
				return false;
			}

			return true;
		}

		#endregion

		#region Hooks

		private void OnServerInitialized()
		{
			Instance = this;

			Loaded();

			InstallPermissions();
			InstallCommands();

			RefreshPlugins();

			var furnaces = BaseNetworkable.serverEntities.OfType<BaseOven>();

			Furnaces.Clear();

			foreach (var furnace in furnaces)
			{
				if (Furnaces.ContainsKey(furnace.OwnerID) || furnace.skinID != 8008132) continue;

				Furnaces.Add(furnace.OwnerID, furnace);
				ProcessFurnace(furnace);
			}
		}
		private void Loaded()
		{
			if (Instance == null) return;

			if (ConfigFile == null) ConfigFile = new Core.Configuration.DynamicConfigFile($"{Manager.ConfigPath}{Path.DirectorySeparatorChar}{Name}.json");
			if (DataFile == null) DataFile = Interface.Oxide.DataFileSystem.GetFile($"{Name}_data");

			if (!ConfigFile.Exists())
			{
				Config = new RootConfig();
				ConfigFile.WriteObject(Config);
			}
			else
			{
				try
				{
					Config = ConfigFile.ReadObject<RootConfig>();
				}
				catch (Exception exception)
				{
					Puts($"Broken configuration: {exception.Message}");
				}
			}

			if (Config != null)
			{
				var updated = false;

				if (Config.GroupCooldowns == null)
				{
					Config.GroupCooldowns = new Dictionary<string, float>();
					Config.GroupCooldowns.Add("default", 60f);
					updated = true;
				}

				if (updated)
				{
					ConfigFile.WriteObject(Config ?? (Config = new RootConfig()));
				}
			}
		}

		private void OnPluginLoaded(Plugin name)
		{
			RefreshPlugins();
		}
		private void OnPluginUnloaded(Plugin name)
		{
			RefreshPlugins();
		}

		private object OnEntityVisibilityCheck(BaseEntity ent, BasePlayer player, uint id, string debugName, float maximumDistance)
		{
			var furnace = ent as BaseOven;
			if (furnace == null) return null;

			if (Furnaces.ContainsKey(player.userID) && Furnaces[player.userID] == ent)
			{
				return true;
			}

			return null;
		}
		private object OnEntityDistanceCheck(BaseEntity ent, BasePlayer player, uint id, string debugName, float maximumDistance)
		{
			var furnace = ent as BaseOven;
			if (furnace == null) return null;

			if (Furnaces.ContainsKey(player.userID) && Furnaces[player.userID] == ent)
			{
				return true;
			}

			return null;
		}
		private object CanLootPlayer(BasePlayer looted, BasePlayer looter)
		{
			var furnace = GetFurnace(looter);

			if (furnace != null && looter.inventory.loot.containers.Count > 0 && furnace.inventory == looter.inventory.loot.containers[0])
			{
				return true;
			}

			return null;
		}
		private void OnServerSave()
		{
			if (Instance == null) return;

			ConfigFile.WriteObject(Config ?? (Config = new RootConfig()));
		}

		#endregion

		#region Plugins

		private Plugin NoEscape;

		#endregion

		#region Helpers

		public void Print(object message, BasePlayer player = null)
		{
			if (player == null) ConsoleNetwork.BroadcastToAllClients("chat.add", 2, Config.ChatIconSteamId, $"<color=orange>{Config.Prefix}</color>: {message}");
			else player.SendConsoleCommand("chat.add", 2, Config.ChatIconSteamId, $"<color=orange>{Config.Prefix}</color> (OY): {message}");
		}
		public float Scale(float oldValue, float oldMin, float oldMax, float newMin, float newMax)
		{
			var num = oldMax - oldMin;
			var num2 = newMax - newMin;
			return (oldValue - oldMin) * num2 / num + newMin;
		}
		public string Join(string[] array, string separator, string lastSeparator = null)
		{
			if (string.IsNullOrEmpty(lastSeparator))
			{
				lastSeparator = separator;
			}

			if (array.Length == 0)
			{
				return string.Empty;
			}

			if (array.Length == 1)
			{
				return array[0];
			}

			var list = Pool.GetList<string>();
			for (int i = 0; i < array.Length - 1; i++)
			{
				list.Add(array[i]);
			}
			var value = string.Join(separator, list.ToArray());
			Pool.FreeList(ref list);
			return value + $"{lastSeparator}{array[array.Length - 1]}";
		}
		public void SendEffectTo(string effect, BasePlayer player)
		{
			if (player == null) return;

			var effectInstance = new Effect();
			effectInstance.Init(Effect.Type.Generic, player, 0, Vector3.up, Vector3.zero);
			effectInstance.pooledstringid = StringPool.Get(effect);
			NetWrite netWrite = Net.sv.StartWrite();
			netWrite.PacketID(Message.Type.Effect);
			effectInstance.WriteToStream(netWrite);
			netWrite.Send(new SendInfo(player.net.connection));
			effectInstance.Clear();
		}

		public Vector3 GetPosition(BasePlayer player)
		{
			var position = player.transform.position;
			return new Vector3(position.x, position.y - 50f, position.z);
		}
		public BaseOven CreateFurnace(BasePlayer forPlayer, string prefab)
		{
			var furnace = GameManager.server.CreateEntity(prefab, GetPosition(forPlayer), Quaternion.identity) as BaseOven;
			furnace.skinID = 8008132;
			furnace.OwnerID = forPlayer.userID;
			ProcessFurnace(furnace);
			furnace.Spawn();
			furnace.inventory.Clear();

			return furnace;
		}
		public void ProcessFurnace(BaseOven furnace)
		{
			if (furnace == null) return;

			UnityEngine.Object.DestroyImmediate(furnace.GetComponent<DestroyOnGroundMissing>());
			UnityEngine.Object.DestroyImmediate(furnace.GetComponent<GroundWatch>());

			furnace.GetComponent<DecayEntity>().decay = null;
		}
		public void StartLooting(BasePlayer player, BaseOven furnace)
		{
			if (Config.PlayOpenEffect) SendEffectTo(OpenEffect, player);

			timer.In(0.2f, () =>
			{
				player.inventory.loot.StartLootingEntity(furnace, false);
				player.inventory.loot.AddContainer(furnace.inventory);
				player.inventory.loot.PositionChecks = false;
				player.inventory.loot.SendImmediate();
				player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", furnace.panelName);
			});

			IsCooledDown(player);
		}
		public void EnsureEntityToPlayer(BasePlayer player, BaseEntity player2)
		{
			var connection = player.Connection;
			var write = Net.sv.StartWrite();
			if (write == null || connection == null) return;
			++connection.validate.entityUpdates;
			var saveInfo = new BaseNetworkable.SaveInfo() { forConnection = connection, forDisk = false };
			write.PacketID(Message.Type.Entities);
			write.UInt32(connection.validate.entityUpdates);
			player2.ToStreamForNetwork(write, saveInfo);
			write.Send(new SendInfo(connection));
		}
		public void RefreshPlugins()
		{
			if (NoEscape == null || !NoEscape.IsLoaded) NoEscape = plugins.Find(nameof(NoEscape));
		}
		public FurnaceTypes GetType(BasePlayer forPlayer)
		{
			var furnace = GetFurnace(forPlayer);
			switch (furnace.PrefabName)
			{
				case CampfirePrefab:
					return FurnaceTypes.Campfire;

				case FurnacePrefab:
					return FurnaceTypes.Furnace;

				case LargeFurnacePrefab:
					return FurnaceTypes.LargeFurnace;

				case SmallOilRefineryPrefab:
					return FurnaceTypes.SmallOilRefinery;
			}

			return FurnaceTypes.Furnace;
		}
		public FurnaceTypes FindType(string input)
		{
			for (int i = 0; i < _typesValues.Length; i++)
			{
				var val = _typesValues[i].ToLower();
				if (val.Contains(input.ToLower())) return (FurnaceTypes)i;
			}

			return 0;
		}

		internal string[] _typesValues = Enum.GetNames(typeof(FurnaceTypes));

		#endregion

		#region Methods

		public void InstallCommands()
		{
			cmd.AddChatCommand(Config.OpenCommand, this, (player, command, args) => OpenFurnace(player, args));
			cmd.AddConsoleCommand(Config.OpenCommand, this, (arg) => { OpenFurnace(arg.Player(), arg.Args); return true; });

			cmd.AddChatCommand(Config.HelpCommand, this, (player, command, args) => HelpFurnace(player, args));
			cmd.AddConsoleCommand(Config.HelpCommand, this, (arg) => { HelpFurnace(arg.Player(), arg.Args); return true; });

			cmd.AddChatCommand(Config.SetCommand, this, (player, command, args) => SetFurnace(player, args));
			cmd.AddConsoleCommand(Config.SetCommand, this, (arg) => { SetFurnace(arg.Player(), arg.Args); return true; });
		}

		public void OpenFurnace(BasePlayer player, string[] args)
		{
			if (player == null || !HasPermission(player, UsePerm)) return;

			var reason = string.Empty;
			if (!CanOpenFurnace(player, out reason))
			{
				Print(reason, player);
				return;
			}

			var furnace = GetFurnace(player);

			if (furnace == null) furnace = SetFurnace(player, CreateFurnace(player, FurnacePrefab));

			EnsureEntityToPlayer(player, furnace);
			StartLooting(player, furnace);
		}
		public void HelpFurnace(BasePlayer player, string[] args)
		{
			if (player == null || !HasPermission(player, UsePerm)) return;

			player.ChatMessage(string.Format(Config.Phrases.Help, $"{GetType(player)}"));
		}
		public void SetFurnace(BasePlayer player, string[] args)
		{
			if (player == null || !HasPermission(player, UsePerm)) return;

			var type = args == null || args.Length == 0 ? (FurnaceTypes)1 : !char.IsDigit(args[0][0]) ? FindType(args[0]) : (FurnaceTypes)int.Parse(args[0]);
			if (type < 0) type = 0; else if ((int)type > _typesValues.Length - 1) type = (FurnaceTypes)_typesValues.Length - 1;
			var furnace = GetFurnace(player);
			var previousType = GetType(player);
			if (type == previousType)
			{
				Print(string.Format(Config.Phrases.SwitchedFurnaceTypeAlreadySelected, type.ToString()), player);
				return;
			}
			var prefab = string.Empty;
			{
				switch (type)
				{
					case FurnaceTypes.Campfire:
						prefab = CampfirePrefab;
						break;

					case FurnaceTypes.Furnace:
						prefab = FurnacePrefab;
						break;

					case FurnaceTypes.LargeFurnace:
						prefab = LargeFurnacePrefab;
						break;

					case FurnaceTypes.SmallOilRefinery:
						prefab = SmallOilRefineryPrefab;
						break;
				}
			}

			var changed = (type == FurnaceTypes.Campfire && furnace?.PrefabName != CampfirePrefab) ||
						  (type == FurnaceTypes.Furnace && furnace?.PrefabName != FurnacePrefab) ||
						  (type == FurnaceTypes.LargeFurnace && furnace?.PrefabName != LargeFurnacePrefab) ||
						  (type == FurnaceTypes.SmallOilRefinery && furnace?.PrefabName != SmallOilRefineryPrefab);

			if (changed && furnace != null)
			{
				DropUtil.DropItems(furnace.inventory, player.eyes.position);
				furnace.Kill();
				furnace = null;
			}

			if (furnace == null) furnace = SetFurnace(player, CreateFurnace(player, prefab));

			Print(string.Format(Config.Phrases.SwitchedFurnaceType, previousType.ToString(), type.ToString()), player);
		}

		#endregion

		#region Config

		public Core.Configuration.DynamicConfigFile ConfigFile { get; set; }
		public Core.Configuration.DynamicConfigFile DataFile { get; set; }

		public RootConfig Config { get; set; } = new RootConfig();

		public class RootConfig
		{
			public string Prefix { get; set; } = "Portable Furnaces";
			public string OpenCommand { get; set; } = "furnace";
			public string HelpCommand { get; set; } = "furnaces";
			public string SetCommand { get; set; } = "setfurnace";
			public bool PlayOpenEffect { get; set; } = true;
			public ulong ChatIconSteamId { get; set; } = 0UL;
			public RuleSettings Rules { get; set; } = new RuleSettings();
			public PhraseSettings Phrases { get; set; } = new PhraseSettings();
			public Dictionary<string, float> GroupCooldowns { get; set; }

			public class RuleSettings
			{
				public bool CanUseFurnaceWhileBuildingBlocked { get; set; } = true;
				public bool CanUseFurnaceWhileCombatBlocked { get; set; } = true;
				public bool CanUseFurnaceWhileRaidBlocked { get; set; } = true;
			}
			public class PhraseSettings
			{
				public string CooledDown { get; set; } = "You're in cooldown.\n<size=12><color=orange>{0}</color> seconds left.</size>";
				public string SwitchedFurnaceTypeAlreadySelected { get; set; } = "<color=orange>{0}</color> is already selected.";
				public string SwitchedFurnaceType { get; set; } = "You've changed the furnace type from {0} to <color=orange>{1}</color>.";
				public string BuildingBlocked { get; set; } = "You're building-blocked.";
				public string CombatBlocked { get; set; } = "You're combat-blocked.";
				public string RaidBlocked { get; set; } = "You're raid-blocked.";
				public string Help { get; set; } = "Current: <color=orange>{0}</color>\n0 = Campfire, 1 = Furnace, 2 = Large Furnace, 3 = Small Oil Refinery";
			}
		}

		#endregion
	}
}

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