C#:
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using System.Collections;
namespace Oxide.Plugins
{
[Info("GradeTimedDestroyed", "xkrystalll", "1.0.1")]
class GradeTimedDestroyed : RustPlugin
{
#region Fields
private List<NetworkableId> objectsIds = new List<NetworkableId>();
private const ushort UPDATE_TIME = 1800;
private const ushort DELETE_TIME = 1800;
#endregion
#region Hooks
private void OnServerInitialized()
{
PrintWarning("Starting invoking clearing of wooden and stone walls...");
PrintWarning($"Update cooldown = {UPDATE_TIME}sec., destroy = {DELETE_TIME}sec.");
InvokeHandler.Instance.InvokeRepeating(UpdateObjects, UPDATE_TIME, UPDATE_TIME);
InvokeHandler.Instance.InvokeRepeating(DestroyObjects, DELETE_TIME, DELETE_TIME);
}
private void Unload()
{
InvokeHandler.Instance.CancelInvoke(UpdateObjects);
InvokeHandler.Instance.CancelInvoke(DestroyObjects);
}
#endregion
#region Methods
private bool IsValid<T>(NetworkableId id, out T ent) where T : BaseEntity
{
var entity = BaseNetworkable.serverEntities.FirstOrDefault(x => x.net.ID == id);
if (entity != null && entity.net != null && entity.net.ID == id)
{
ent = entity as T;
return true;
}
ent = null;
return false;
}
private void UpdateObjects()
{
Stopwatch watch = Stopwatch.StartNew();
watch.Start();
var entities = BaseNetworkable.serverEntities.Where(x => x.PrefabName.Contains("gates.external.high") || x.PrefabName.Contains("wall.external.high"));
foreach (var x in entities)
{
if (!objectsIds.Contains(x.net.ID))
objectsIds.Add(x.net.ID);
}
watch.Stop();
if (watch.ElapsedMilliseconds > 1000)
{
PrintWarning($"Elapsed time of {nameof(UpdateObjects)} = {watch.ElapsedMilliseconds}ms. " +
$"Objects of type = {entities.Count()}, " +
$"acceptible objects = {entities.Count()}");
}
}
private IEnumerator DestroyObjectsSteps()
{
Queue<NetworkableId> objects = new Queue<NetworkableId>(objectsIds);
int killedobjects = 0;
int attempts = 0;
while (objects.Count > 0)
{
if (attempts > 1000)
yield break;
var id = objects.Dequeue();
BaseEntity entity = null;
if (IsValid<BaseEntity>(id, out entity))
{
entity.Kill(BaseNetworkable.DestroyMode.None);
}
attempts++;
killedobjects++;
yield return new WaitForSeconds(0.2f);
}
Puts($"Deleted {killedobjects} wood and stone high walls.");
}
private void DestroyObjects()
{
Stopwatch watch = Stopwatch.StartNew();
watch.Start();
ServerMgr.Instance.StartCoroutine(DestroyObjectsSteps());
watch.Stop();
if (watch.ElapsedMilliseconds > 1000)
{
PrintWarning($"Elapsed time of {nameof(DestroyObjects)} (ms) = {watch.ElapsedMilliseconds}");
}
Puts($"Deleted {objectsIds.Count} wood and stone high walls.");
objectsIds.Clear();
}
#endregion
}
}