C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;
using Newtonsoft.Json;
using System.Text;
using System.IO.Compression;
using Oxide.Core.Plugins;
using Oxide.Core.Configuration;
namespace Oxide.Plugins
{
[Info("UpgradeTimer", "Jake_Rich", "2.0.0", ResourceId = 2740)]
[Description("Time limit to upgrade twig after it has been placed")]
public class UpgradeTimer : RustPlugin
{
public static UpgradeTimer _plugin;
public static JSONFile<ConfigData> _settingsFile;
public static ConfigData Settings { get { return _settingsFile.Instance; } }
public Dictionary<BaseEntity,EntityData> EntityDictionary;
void Init()
{
_plugin = this;
}
void Loaded()
{
_settingsFile = new JSONFile<ConfigData>($"{Name}", ConfigLocation.Config, extension: ".cfg");
EntityDictionary = new Dictionary<BaseEntity, EntityData>();
}
void Unload()
{
}
public class ConfigData
{
public int UpgradeDelay = 10;
public int WoodUpgradeDelay = 3 * 60;
public int StoneUpgradeDelay = 10 * 60;
public int MetalUpgradeDelay = 20 * 60;
public int ArmouredUpgradeDelay = 30 * 60;
public float ExplosiveDamageDelay = 90f;
public float NormalDamageDelay = 10f;
public Dictionary<string, int> EntityUpgradeTime = new Dictionary<string, int>()
{
{ "wall.external.high.stone", 20 * 60},
{ "wall.external.high.wood", 10 * 60},
{ "gates.external.high.stone", 20 * 60},
{ "gates.external.high.wood", 10 * 60},
{ "door.hinged.wood", 3 * 60},
{ "door.hinged.metal", 10 * 60},
{ "door.hinged.toptier", 20 * 60},
{ "door.double.hinged.wood", 3 * 60},
{ "door.double.hinged.metal", 10 * 60},
{ "door.double.hinged.toptier", 20 * 60},
{ "wall.frame.garagedoor", 10 * 60},
};
}
public class EntityData
{
public BaseCombatEntity Entity;
public Timer timer;
public int TimerRate = 6;
public float NextRepairTime;
public float NextUpgradeTime;
public EntityData(BaseCombatEntity block)
{
Entity = block;
}
public void ResetTimer()
{
StartTimer();
}
public void StartTimer()
{
NextRepairTime = Mathf.Max(UnityEngine.Time.time + TimerRate + 4, NextRepairTime);
timer?.Destroy();
timer = _plugin.timer.Every(TimerRate, TimerLoop);
}
private void TimerLoop()
{
if (Entity == null)
{
return;
}
NextRepairTime = Mathf.Max(UnityEngine.Time.time + TimerRate + 4, NextRepairTime);
float rate = 0;
if (Entity is BuildingBlock)
{
switch (((BuildingBlock)Entity).grade)
{
case BuildingGrade.Enum.Wood: { rate = Settings.WoodUpgradeDelay; break; }
case BuildingGrade.Enum.Stone: { rate = Settings.StoneUpgradeDelay; break; }
case BuildingGrade.Enum.Metal: { rate = Settings.MetalUpgradeDelay; break; }
case BuildingGrade.Enum.TopTier: { rate = Settings.ArmouredUpgradeDelay; break; }
default: { return; }
}
}
int amount;
if (Settings.EntityUpgradeTime.TryGetValue(Entity.ShortPrefabName, out amount))
{
rate = amount;
}
Entity.healthFraction = Mathf.Min(1f, Entity.healthFraction + (TimerRate / rate));
if (Entity.healthFraction >= 1f)
{
Destroy();
}
if (!(Entity is BuildingBlock))
{
Entity.SendNetworkUpdate();
}
}
public void Destroy()
{
timer?.Destroy();
}
}
public EntityData GetEntityData(BaseCombatEntity entity)
{
EntityData data;
if (!EntityDictionary.TryGetValue(entity, out data))
{
data = new EntityData(entity);
EntityDictionary.Add(entity, data);
}
return data;
}
void OnEntityBuilt(Planner plan, GameObject go)
{
BaseCombatEntity entity = go.ToBaseEntity() as BaseCombatEntity;
if (entity == null)
{
return;
}
if (Settings.EntityUpgradeTime.ContainsKey(entity.ShortPrefabName) == false)
{
return;
}
var data = GetEntityData(entity);
entity.healthFraction = (float)data.TimerRate / Settings.EntityUpgradeTime[entity.ShortPrefabName];
entity.SendNetworkUpdate();
data.StartTimer();
return;
Timer _timer = null;
entity.healthFraction = 0;
entity.lastAttackedTime = Time.time;
_timer = timer.Repeat(1f, Settings.UpgradeDelay, () =>
{
if (entity == null || entity.IsDestroyed || _timer == null)
{
_timer?.Destroy();
return;
}
entity.lastAttackedTime = Time.time;
entity.healthFraction = 1f / Settings.UpgradeDelay * (Settings.UpgradeDelay - _timer.Repetitions);
if (_timer.Repetitions == 0)
{
entity.lastAttackedTime = 0;
//timers.Remove(entity);
}
});
//timers.Add(entity, _timer);
}
void OnEntityKill(BaseNetworkable net)
{
var entity = net as BaseCombatEntity;
if (entity == null)
{
return;
}
if (entity is BuildingBlock || Settings.EntityUpgradeTime.ContainsKey(net.ShortPrefabName))
{
GetEntityData(entity).Destroy();
EntityDictionary.Remove(entity);
}
}
void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
{
if ((entity is BuildingBlock || Settings.EntityUpgradeTime.ContainsKey(entity.ShortPrefabName)) == false)
{
return;
}
var data = GetEntityData(entity);
if (info.damageTypes.Has(Rust.DamageType.Explosion))
{
data.Destroy();
data.NextRepairTime = Mathf.Max(UnityEngine.Time.time + Settings.ExplosiveDamageDelay, data.NextRepairTime);
data.NextUpgradeTime = data.NextRepairTime;
return;
}
if (info.damageTypes.Has(Rust.DamageType.Decay))
{
return;
}
data.NextRepairTime = Mathf.Max(UnityEngine.Time.time + Settings.NormalDamageDelay, data.NextRepairTime);
data.NextUpgradeTime = data.NextRepairTime;
data.ResetTimer();
}
object OnStructureUpgrade(BuildingBlock block, BasePlayer player, BuildingGrade.Enum grade)
{
var data = GetEntityData(block);
if (data.NextUpgradeTime > UnityEngine.Time.time)
{
return false;
}
float oldHealth = block.health;
NextFrame(() =>
{
if (block == null)
{
return;
}
block.health = oldHealth;
data.ResetTimer();
});
return null;
}
object OnStructureRepair(BaseCombatEntity entity, BasePlayer player)
{
var block = entity as BuildingBlock;
if (block == null)
{
return null;
}
var data = GetEntityData(block);
if (data.NextRepairTime <= UnityEngine.Time.time)
{
return null;
}
return false;
}
#region Configuration Files
public enum ConfigLocation
{
Data = 0,
Config = 1,
Logs = 2,
Plugins = 3,
Lang = 4,
Custom = 5,
}
public class JSONFile<Type> where Type : class
{
private DynamicConfigFile _file;
public string _name { get; set; }
public Type Instance { get; set; }
private ConfigLocation _location { get; set; }
private string _path { get; set; }
public bool SaveOnUnload = false;
public bool Compressed = false;
public JSONFile(string name, ConfigLocation location = ConfigLocation.Data, string path = null, string extension = ".json", bool saveOnUnload = false)
{
SaveOnUnload = saveOnUnload;
_name = name.Replace(".json", "");
_location = location;
switch (location)
{
case ConfigLocation.Data:
{
_path = $"{Oxide.Core.Interface.Oxide.DataDirectory}/{name}{extension}";
break;
}
case ConfigLocation.Config:
{
_path = $"{Oxide.Core.Interface.Oxide.ConfigDirectory}/{name}{extension}";
break;
}
case ConfigLocation.Logs:
{
_path = $"{Oxide.Core.Interface.Oxide.LogDirectory}/{name}{extension}";
break;
}
case ConfigLocation.Lang:
{
_path = $"{Oxide.Core.Interface.Oxide.LangDirectory}/{name}{extension}";
break;
}
case ConfigLocation.Custom:
{
_path = $"{path}/{name}{extension}";
break;
}
}
_file = new DynamicConfigFile(_path);
_file.Settings = new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
Init();
}
public virtual void Init()
{
_plugin.OnRemovedFromManager.Add(new Action<Plugin, PluginManager>(Unload));
Load();
Save();
Load();
}
public virtual void Load()
{
if (Compressed)
{
LoadCompressed();
return;
}
if (!_file.Exists())
{
Save();
}
Instance = _file.ReadObject<Type>();
if (Instance == null)
{
Instance = Activator.CreateInstance<Type>();
Save();
}
return;
}
private void LoadCompressed()
{
string str = _file.ReadObject<string>();
if (str == null || str == "")
{
Instance = Activator.CreateInstance<Type>();
return;
}
using (var compressedStream = new MemoryStream(Convert.FromBase64String(str)))
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
using (var resultStream = new MemoryStream())
{
var buffer = new byte[4096];
int read;
while ((read = zipStream.Read(buffer, 0, buffer.Length)) > 0)
{
resultStream.Write(buffer, 0, read);
}
Instance = JsonConvert.DeserializeObject<Type>(Encoding.UTF8.GetString(resultStream.ToArray()));
}
}
public virtual void Save()
{
if (Compressed)
{
SaveCompressed();
return;
}
_file.WriteObject(Instance);
return;
}
private void SaveCompressed()
{
using (var stream = new MemoryStream())
{
using (GZipStream zipStream = new GZipStream(stream, CompressionMode.Compress))
{
byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(Instance));
zipStream.Write(bytes, 0, bytes.Length);
zipStream.Close();
_file.WriteObject(Convert.ToBase64String(stream.ToArray()));
}
}
}
public virtual void Reload()
{
Load();
}
private void Unload(Plugin sender, PluginManager manager)
{
if (SaveOnUnload)
{
Save();
}
}
}
#endregion
}
}