C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("NoSleepers", "collect_vood", "0.5.7")]
[Description("Prevents players from sleeping and optionally removes player corpses and bags")]
class NoSleepers : CovalencePlugin
{
#region Config
private ConfigurationFile Configuration;
private class ConfigurationFile
{
[JsonProperty(PropertyName = "Kill existing")]
public bool KillExisting = false;
[JsonProperty(PropertyName = "Remove corpses")]
public bool RemoveCorpses = true;
[JsonProperty(PropertyName = "Remove bags")]
public bool RemoveBags = false;
[JsonProperty(PropertyName = "Save last position")]
public bool SaveLastPosition = false;
[JsonProperty(PropertyName = "Save last inventory")]
public bool SaveLastInventory = false;
[JsonProperty(PropertyName = "Exclude Permission")]
public string PermExclude = "nosleepers.exclude";
[JsonProperty(PropertyName = "Player Inactivity Data Removal (hours)")]
public int InactivityRemovalTime = 168;
}
protected override void LoadDefaultConfig()
{
PrintWarning("Creating a new configuration file");
Configuration = new ConfigurationFile();
}
protected override void LoadConfig()
{
base.LoadConfig();
Configuration = Config.ReadObject<ConfigurationFile>();
SaveConfig();
}
protected override void SaveConfig() => Config.WriteObject(Configuration);
#endregion
#region Data
private StoredData AllStoredData;
private Dictionary<string, PlayerData> AllPlayerData => AllStoredData.AllPlayerData;
private class StoredData
{
[JsonProperty("All Player Data", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, PlayerData> AllPlayerData { get; private set; } = new Dictionary<string, PlayerData>();
}
public class PlayerData
{
[JsonProperty("Player Items")]
public List<PlayerItem> PlayerItems;
[JsonProperty("Last position")]
public Vector3 LastPosition;
[JsonProperty("Last active")]
public long LastActive = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
public PlayerData()
{
}
}
public class PlayerItem
{
public enum ContainerType { Wear, Main, Belt }
[JsonProperty("Name")]
public string Shortname;
[JsonProperty("Amount")]
public int Amount;
[JsonProperty("SkinId")]
public ulong SkinId;
[JsonProperty("Position")]
public int Position;
[JsonProperty("Condition")]
public float Condition;
[JsonProperty("Magazine")]
public int Magazine;
[JsonProperty("Container")]
public ContainerType Container;
[JsonProperty("Mods")]
public List<int> Mods;
public PlayerItem(string shortName, int amount, ulong skinId, int position, float condition, int magazine, ContainerType container, List<int> mods)
{
Shortname = shortName;
Amount = amount;
SkinId = skinId;
Position = position;
Condition = condition;
Magazine = magazine;
Container = container;
Mods = mods;
}
}
private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, AllStoredData);
private void LoadData()
{
AllStoredData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
if (AllStoredData == null) AllStoredData = new StoredData();
SaveData();
}
private void OnServerSave() => ClearUpData();
private void Unload() => SaveData();
private void ClearUpData()
{
if (Configuration.InactivityRemovalTime == 0)
return;
var copy = new Dictionary<string, PlayerData>(AllPlayerData);
foreach (var colData in copy)
{
if (colData.Value.LastActive == 0)
continue;
if (colData.Value.LastActive + (Configuration.InactivityRemovalTime * 3600) < DateTimeOffset.UtcNow.ToUnixTimeSeconds())
AllPlayerData.Remove(colData.Key);
}
SaveData();
}
#endregion
#region Initialization
void OnServerInitialized()
{
#if !RUST
throw new NotSupportedException("This plugin does not support this game");
#endif
permission.RegisterPermission(Configuration.PermExclude, this);
LoadData();
if (!Configuration.KillExisting)
return;
var killCount = 0;
foreach (var ply in BasePlayer.sleepingPlayerList.ToList())
{
if (BasePlayer.activePlayerList.Contains(ply)) continue;
if (!ply.IsDestroyed && !permission.UserHasPermission(ply.UserIDString, Configuration.PermExclude))
{
ply.Die();
killCount++;
}
}
if (killCount > 0)
Puts($"Killed {killCount} {(killCount == 1 ? "sleeper" : "sleepers")}");
}
#endregion
#region Hooks
void OnPlayerRespawned(BasePlayer player)
{
if (player.IsSleeping() && !permission.UserHasPermission(player.UserIDString, Configuration.PermExclude))
{
player.EndSleeping();
if (!AllPlayerData.ContainsKey(player.UserIDString))
return;
var playerData = AllPlayerData[player.UserIDString];
if (playerData.PlayerItems != null)
GivePlayerItems(player, playerData.PlayerItems);
AllPlayerData.Remove(player.UserIDString);
}
}
object OnPlayerRespawn(BasePlayer player)
{
if (!AllPlayerData.ContainsKey(player.UserIDString))
return null;
var playerData = AllPlayerData[player.UserIDString];
if (playerData.LastPosition == Vector3.zero)
return null;
Vector3 latestPos = playerData.LastPosition;
playerData.LastPosition = Vector3.zero;
return new BasePlayer.SpawnPoint { pos = latestPos };
}
void OnPlayerDisconnected(BasePlayer player)
{
if (!player.IsDestroyed && !permission.UserHasPermission(player.UserIDString, Configuration.PermExclude))
{
if (Configuration.SaveLastPosition || Configuration.SaveLastInventory)
{
var playerData = new PlayerData();
if (Configuration.SaveLastPosition)
playerData.LastPosition = player.transform.position;
if (Configuration.SaveLastInventory)
playerData.PlayerItems = GetAllItems(player.inventory);
if (AllPlayerData.ContainsKey(player.UserIDString))
AllPlayerData[player.UserIDString] = playerData;
else
AllPlayerData.Add(player.UserIDString, playerData);
}
player.Die();
}
}
object OnServerCommand(ConsoleSystem.Arg arg)
{
if (arg.cmd.Name == "sleep")
{
var bPlayer = arg.Player();
if (bPlayer == null || bPlayer.IsAdmin || permission.UserHasPermission(bPlayer.UserIDString, Configuration.PermExclude))
return null;
return false;
}
return null;
}
void OnEntitySpawned(BaseNetworkable entity)
{
if (Configuration.RemoveCorpses && entity.ShortPrefabName.Equals("player_corpse"))
entity.Kill();
if (Configuration.RemoveBags && entity.ShortPrefabName.Equals("item_drop_backpack"))
entity.Kill();
}
//object OnPlayerSleep(BasePlayer player) => true; // TODO: Hook might be causing local player duplication
#endregion
#region Helpers
List<PlayerItem> GetAllItems(PlayerInventory inventory)
{
var playerItems = new List<PlayerItem>();
foreach (var item in inventory.containerBelt.itemList)
{
List<int> mods = new List<int>();
int magazine = 0;
BaseProjectile weapon = item.GetHeldEntity() as BaseProjectile;
if (weapon != null) magazine = weapon.primaryMagazine.contents;
if (item.contents != null)
{
foreach (var contentItem in item.contents.itemList)
{
mods.Add(contentItem.info.itemid);
};
}
playerItems.Add(new PlayerItem(item.info.shortname, item.amount, item.skin, item.position, item.condition, magazine, PlayerItem.ContainerType.Belt, mods));
}
foreach (var item in inventory.containerMain.itemList)
{
List<int> mods = new List<int>();
int magazine = 0;
BaseProjectile weapon = item.GetHeldEntity() as BaseProjectile;
if (weapon != null) magazine = weapon.primaryMagazine.contents;
if (item.contents != null)
{
foreach (var contentItem in item.contents.itemList)
{
mods.Add(contentItem.info.itemid);
};
}
playerItems.Add(new PlayerItem(item.info.shortname, item.amount, item.skin, item.position, item.condition, magazine, PlayerItem.ContainerType.Main, mods));
}
foreach (var item in inventory.containerWear.itemList)
{
playerItems.Add(new PlayerItem(item.info.shortname, item.amount, item.skin, item.position, item.condition, 0, PlayerItem.ContainerType.Wear, new List<int>()));
}
return playerItems;
}
void GivePlayerItems(BasePlayer player, List<PlayerItem> playerItems)
{
player.inventory.containerBelt.Clear();
player.inventory.containerMain.Clear();
player.inventory.containerWear.Clear();
ItemManager.DoRemoves();
foreach (var playerItem in playerItems)
{
var item = ItemManager.CreateByName(playerItem.Shortname, playerItem.Amount, playerItem.SkinId);
var weapon = item.GetHeldEntity() as BaseProjectile;
if (weapon != null) weapon.primaryMagazine.contents = playerItem.Magazine;
item.condition = playerItem.Condition;
switch (playerItem.Container)
{
case PlayerItem.ContainerType.Belt:
item.MoveToContainer(player.inventory.containerBelt, playerItem.Position);
break;
case PlayerItem.ContainerType.Main:
item.MoveToContainer(player.inventory.containerMain, playerItem.Position);
break;
case PlayerItem.ContainerType.Wear:
item.MoveToContainer(player.inventory.containerWear, playerItem.Position);
break;
}
foreach (var mod in playerItem.Mods)
{
Item modItem = ItemManager.CreateByItemID(mod, 1, 0);
item.contents.AddItem(modItem.info, 1);
}
}
}
#endregion
}
}