C#:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Broken Items Cleaner", "sdapro", "1.2.6")]
//YouTube https://www.youtube.com/channel/UCaatLYzqycP6He7TEbK-IDA
//https://t.me/+jb13FvJyK4o5MTli
[Description("Cleaning server from broken items and held entities")]
public class BrokenItemsCleaner : RustPlugin
{
#region Vars
private Coroutine loop;
#endregion
#region Oxide Hooks
private void OnServerInitialized()
{
timer.Once(3f, () => {DoRoutine();});
timer.Every(3600, DoRoutine);
}
private void Unload()
{
if (loop != null)
{
ServerMgr.Instance.StopCoroutine(loop);
}
}
#endregion
#region Core
private void DoRoutine()
{
if (loop == null)
{
loop = ServerMgr.Instance.StartCoroutine(Loop());
}
}
private IEnumerator Loop()
{
var countRemoved = 0;
var allItems = new List<Item>();
var allHeld = new List<BaseEntity>();
var allEntities = BaseNetworkable.serverEntities?.entityList?.ToArray();
if (allEntities == null)
{
PrintError("Entities is null!");
yield break;
}
PrintWarning($"Checking {allEntities.Length} entities, it will take a while");
foreach (var pair in allEntities)
{
yield return new WaitForEndOfFrame();
if (pair.Key == null || pair.Value == null)
{
continue;
}
var entity = pair.Value.GetComponent<BaseEntity>();
if (entity == null || entity.IsValid() == false)
{
continue;
}
if (entity is HeldEntity)
{
allHeld.Add(entity);
continue;
}
var player = entity.GetComponent<BasePlayer>();
if (player != null)
{
var items = player.inventory?.AllItems();
if (items != null)
{
allItems.AddRange(items);
}
continue;
}
var corpse = entity.GetComponent<LootableCorpse>();
if (corpse != null)
{
var items = corpse.containers?.SelectMany(x => x?.itemList);
if (items != null)
{
allItems.AddRange(items);
}
continue;
}
var containerNormal = entity.GetComponent<StorageContainer>();
if (containerNormal != null)
{
var items = containerNormal.inventory?.itemList;
if (items != null)
{
allItems.AddRange(items);
}
continue;
}
var containerIO = entity.GetComponent<ContainerIOEntity>();
if (containerIO != null)
{
var items = containerIO.inventory?.itemList;
if (items != null)
{
allItems.AddRange(items);
}
continue;
}
var ground = entity.GetComponent<DroppedItem>();
if (ground != null)
{
if (ground.item != null)
{
allItems.Add(ground.item);
}
continue;
}
var dropped = entity.GetComponent<DroppedItemContainer>();
if (dropped != null)
{
var items = dropped.inventory?.itemList;
if (items != null)
{
allItems.AddRange(items);
}
continue;
}
}
foreach (var item in allItems.ToArray())
{
yield return new WaitForEndOfFrame();
var items = item.contents?.itemList;
if (items != null)
{
allItems.AddRange(items);
}
}
foreach (var item in allItems.ToArray())
{
yield return new WaitForEndOfFrame();
var held = item.GetHeldEntity();
if (held != null)
{
allHeld.Remove(held);
}
}
foreach (var entity in allHeld.ToArray())
{
yield return new WaitForEndOfFrame();
if (entity.IsValid() == true)
{
entity.Kill();
countRemoved++;
}
}
var text = $"{allItems.Count} items was checked, {countRemoved} was removed";
PrintWarning(text);
LogToFile("log", text, this);
}
#endregion
}
}