C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Facepunch;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Core.Libraries.Covalence;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Entity Owner", "Calytic", "3.4.1")]
[Description("Modify entity ownership and cupboard/turret authorization")]
class EntityOwner : RustPlugin
{
#region Data & Config
readonly int layerMasks = LayerMask.GetMask("Construction", "Construction Trigger", "Trigger", "Deployed");
int EntityLimit = 8000;
float DistanceThreshold = 3f;
float CupboardDistanceThreshold = 20f;
bool debug;
#endregion
#region Data Handling & Initialization
Dictionary<string, string> texts = new Dictionary<string, string> {
{"Denied: Permission", "You are not allowed to use this command"},
{"Error: Unknown", "Undefined error occurred.Look up the log for more info"},
{"Target: None", "No target found"},
{"Target: Owner", "Owner: {0}"},
{"Target: Limit", "Exceeded entity limit."},
{"Syntax: Owner", "Invalid syntax: /owner"},
{"Syntax: SetOwner", "Incorrect Syntax.\n/setowner <playername|steamid>"},
{"Syntax: Own", "Invalid Syntax.\n/own type player\nTypes: all/block/storage/cupboard/sign/sleepingbag/plant/oven/door/turret\n/own player"},
{"Syntax: Unown", "Invalid Syntax.\n/unown type player\nTypes: all/block/storage/cupboard/sign/sleepingbag/plant/oven/door/turret\n/unown player"},
{"Syntax: Prod2", "Invalid Syntax.\n/prod2 type \nTypes:\n all/block/entity/storage/cupboard/sign/sleepingbag/plant/oven/door/turret"},
{"Syntax: Auth", "Invalid Syntax.\n/auth turret player\n/auth cupboard player/auth player\n/auth"},
{"Syntax: Deauth", "Invalid Syntax.\n/deauth turret player\n/deauth cupboard player/deauth player\n/deauth"},
{"Ownership: Changing", "Changing ownership.."},
{"Ownership: Removing", "Removing ownership.."},
{"Ownership: New", "New owner of all around is: {0}"},
{"Ownership: New Self", "Owner: You were given ownership of this house and nearby deployables"},
{"Ownership: Count", "Count ({0})"},
{"Ownership: Removed", "Ownership removed"},
{"Ownership: Changed", "Ownership changed"},
{"Entities: None", "No entities found."},
{"Entities: Authorized", "({0}) Authorized"},
{"Entities: Count", "Counted {0} entities ({1}/{2})"},
{"Structure: Prodding","Prodding structure.."},
{"Structure: Condition Percent", "Condition: {0}%"},
{"Player: Unknown Percent", "Unknown: {0}%"},
{"Player: None", "Target player not found"},
{"Cupboards: Prodding", "Prodding cupboards.."},
{"Cupboards: Authorizing", "Authorizing cupboards.."},
{"Cupboards: Authorized", "Authorized {0} on {1} cupboards"},
{"Cupboards: Deauthorizing", "Deauthorizing cupboards.."},
{"Cupboard: Deauthorized", "Deauthorized {0} on {1} cupboards"},
{"Turrets: Authorized", "Authorized {0} on {1} turrets"},
{"Turrets: Authorizing", "Authorizing turrets.."},
{"Turrets: Prodding", "Prodding turrets.."},
{"Turrets: Deauthorized", "Deauthorized {0} on {1} turrets"},
{"Turrets: Deauthorizing", "Deauthorizing turrets.."},
{"Lock: Code", "Code: {0}"},
{"Lock: Owner", "Lock owner: {0}"},
{"Bag: Assignee", "Assigned: {0}"}
};
// Loads the default configuration
protected override void LoadDefaultConfig()
{
Config["Debug"] = false;
Config["EntityLimit"] = EntityLimit;
Config["DistanceThreshold"] = DistanceThreshold;
Config["CupboardDistanceThreshold"] = CupboardDistanceThreshold;
Config["VERSION"] = Version.ToString();
Config.Save();
}
new void LoadDefaultMessages()
{
lang.RegisterMessages(texts, this);
}
protected void ReloadConfig()
{
Config["VERSION"] = Version.ToString();
// NEW CONFIGURATION OPTIONS HERE
Config["Debug"] = false;
Config["EntityLimit"] = EntityLimit;
Config["DistanceThreshold"] = DistanceThreshold;
Config["CupboardDistanceThreshold"] = CupboardDistanceThreshold;
// END NEW CONFIGURATION OPTIONS
PrintToConsole("Upgrading Configuration File");
SaveConfig();
}
// Gets a config value of a specific type
T GetConfig<T>(string name, T defaultValue)
{
if (Config[name] == null)
{
return defaultValue;
}
return (T)Convert.ChangeType(Config[name], typeof(T));
}
string GetMsg(string key, BasePlayer player = null)
{
return lang.GetMessage(key, this, player == null ? null : player.UserIDString);
}
void OnServerInitialized()
{
try
{
LoadConfig();
debug = GetConfig("Debug", false);
EntityLimit = GetConfig("EntityLimit", 8000);
DistanceThreshold = GetConfig("DistanceThreshold", 3f);
CupboardDistanceThreshold = GetConfig("CupboardDistanceThreshold", 20f);
if (DistanceThreshold >= 5)
{
PrintWarning("ALERT: Distance threshold configuration option is ABOVE 5.This may cause serious performance degradation (lag) when using EntityOwner commands");
}
permission.RegisterPermission("entityowner.cancheckowners", this);
permission.RegisterPermission("entityowner.cancheckcodes", this);
permission.RegisterPermission("entityowner.canchangeowners", this);
permission.RegisterPermission("entityowner.seedetails", this);
LoadData();
}
catch (Exception ex)
{
PrintError("OnServerInitialized failed: {0}", ex.Message);
}
}
void LoadData()
{
if (Config["VERSION"] == null)
{
// FOR COMPATIBILITY WITH INITIAL VERSIONS WITHOUT VERSIONED CONFIG
ReloadConfig();
}
else if (GetConfig("VERSION", Version.ToString()) != Version.ToString())
{
// ADDS NEW, IF ANY, CONFIGURATION OPTIONS
ReloadConfig();
}
}
[HookMethod("SendHelpText")]
void SendHelpText(BasePlayer player)
{
var sb = new StringBuilder();
if (canCheckOwners(player) || canChangeOwners(player))
{
sb.Append("<size=18>EntityOwner</size> by <color=#ce422b>Calytic</color> at <color=#ce422b>http://rustservers.io</color>\n");
}
if (canCheckOwners(player))
{
sb.Append(" ").Append("<color=\"#ffd479\">/prod</color> - Check ownership of entity you are looking at").Append("\n");
sb.Append(" ").Append("<color=\"#ffd479\">/prod2</color> - Check ownership of entire structure/all deployables").Append("\n");
sb.Append(" ").Append("<color=\"#ffd479\">/prod2 block</color> - Check ownership structure only").Append("\n");
sb.Append(" ").Append("<color=\"#ffd479\">/prod2 cupboard</color> - Check authorization on all nearby cupboards").Append("\n");
sb.Append(" ").Append("<color=\"#ffd479\">/auth</color> - Check authorization list of tool cupboard you are looking at").Append("\n");
}
if (canChangeOwners(player))
{
sb.Append(" ").Append("<color=\"#ffd479\">/own [all/block]</color> - Take ownership of entire structure").Append("\n");
sb.Append(" ").Append("<color=\"#ffd479\">/own [all/block] PlayerName</color> - Give ownership of entire structure to specified player").Append("\n");
sb.Append(" ").Append("<color=\"#ffd479\">/unown [all/block]</color> - Remove ownership from entire structure").Append("\n");
sb.Append(" ").Append("<color=\"#ffd479\">/auth PlayerName</color> - Authorize specified player on all nearby cupboards").Append("\n");
}
SendReply(player, sb.ToString());
}
#endregion
#region Chat Commands
[ChatCommand("prod")]
void cmdProd(BasePlayer player, string command, string[] args)
{
if (!canCheckOwners(player))
{
SendReply(player, GetMsg("Denied: Permission", player));
return;
}
if (args == null || args.Length == 0)
{
//var input = serverinput.GetValue(player) as InputState;
//var currentRot = Quaternion.Euler(input.current.aimAngles) * Vector3.forward;
//var target = RaycastAll<BaseEntity>(player.transform.position + new Vector3(0f, 1.5f, 0f), currentRot);
var target = RaycastAll<BaseEntity>(player.eyes.HeadRay());
if (target is bool)
{
SendReply(player, GetMsg("Target: None", player));
return;
}
if (target is BaseEntity)
{
var targetEntity = target as BaseEntity;
var owner = GetOwnerName((BaseEntity)target);
if (string.IsNullOrEmpty(owner))
{
owner = "N/A";
}
string msg = string.Format(GetMsg("Target: Owner", player), owner);
var baseLock = targetEntity.GetSlot(BaseEntity.Slot.Lock) as BaseLock;
if (baseLock != null)
{
if (baseLock.OwnerID != 0 && baseLock.OwnerID != targetEntity.OwnerID)
{
var lockOwnerName = GetOwnerName(baseLock);
msg += "\n" + string.Format(GetMsg("Lock: Owner", player), lockOwnerName);
}
}
if (canSeeDetails(player))
{
msg += "\n<color=#D3D3D3>Name: " + targetEntity.ShortPrefabName + "</color>";
if (targetEntity.skinID > 0)
{
msg += "\n<color=#D3D3D3>Skin: " + targetEntity.skinID + "</color>";
}
if (targetEntity.PrefabName != targetEntity.ShortPrefabName)
{
msg += "\n<color=#D3D3D3>Prefab: \"" + targetEntity.PrefabName + "\"</color>";
}
msg += "\n<color=#D3D3D3>Outside: " + (targetEntity.IsOutside() ? "Yes" : "No") + "</color>";
}
if (canCheckCodes(player))
{
var codeLock = baseLock as CodeLock;
if (codeLock != null)
{
string keyCode = codeLock.code;
msg += "\n" + string.Format(GetMsg("Lock: Code", player), keyCode);
}
}
if (canCheckAssignee(player))
{
if (targetEntity is SleepingBag)
{
SleepingBag bag = (SleepingBag)targetEntity;
msg += "\n" + string.Format(GetMsg("Bag: Assignee", player), FindPlayerName(bag.deployerUserID));
}
}
SendReply(player, msg);
}
}
else
{
SendReply(player, GetMsg("Syntax: Owner", player));
}
}
//or any wanted new chat command.maybe even integrated in existing /own
//this one will only change ownership of the one particular entity you are looking at
[ChatCommand("setowner")]
void cmdSetowner(BasePlayer player, string command, string[] args)
{
//check if user has permission
if (!canChangeOwners(player))
{
SendReply(player, GetMsg("Denied: Permission", player));
return;
}
//check if given argument exists and is not empty
if (string.IsNullOrEmpty(args[0]))
{
SendReply(player, GetMsg("Syntax: SetOwner", player));
return;
}
//getting valid UserID
ulong new_ownerid = FindUserIDByPartialName(args[0].ToString());
if (new_ownerid == 0)
{
SendReply(player, GetMsg("Player: None", player));
return;
}
try
{
//try to get the entity user is looking at
var target_entity = RaycastAll<BaseEntity>(player.eyes.HeadRay());
if (target_entity is bool)
{
SendReply(player, GetMsg("Target: None", player));
return;
}
else if (target_entity is BaseEntity)
{
//just to make future usage of the var easier
var target_BaseEntity = target_entity as BaseEntity;
try
{
//get the current owner
var old_owner = GetOwnerName(target_BaseEntity);
if (string.IsNullOrEmpty(old_owner))
{
old_owner = "N/A";
}
ChangeOwner(target_BaseEntity, new_ownerid);
//check if the owner was actually changed
var new_owner = GetOwnerName(target_BaseEntity);
if (string.IsNullOrEmpty(new_owner))
{
new_owner = "N/A";
}
SendReply(player, "Changed owner of [" + target_BaseEntity.ShortPrefabName + "] from [" + old_owner + "] to [" + new_owner + "]");
}
catch (Exception ex)
{
SendReply(player, GetMsg("Error: Unknown", player));
Debug.LogException(ex);
}
}
}
catch (Exception ex)
{
SendReply(player, GetMsg("Error: Unknown", player));
Debug.LogException(ex);
}
}
[ChatCommand("own")]
void cmdOwn(BasePlayer player, string command, string[] args)
{
if (!canChangeOwners(player))
{
SendReply(player, GetMsg("Denied: Permission", player));
return;
}
var massTrigger = false;
string type = null;
ulong target = player.userID;
if (args.Length == 0)
{
args = new string[1] { "1" };
}
if (args.Length > 2)
{
SendReply(player, GetMsg("Syntax: Own", player));
return;
}
if (args.Length == 1)
{
if (type == "all" || type == "storage" || type == "block" || type == "cupboard" || type == "sign" || type == "sleepingbag" || type == "plant" || type == "oven" || type == "door" || type == "turret")
{
massTrigger = true;
target = player.userID;
}
else if (!string.IsNullOrEmpty(type))
{
target = FindUserIDByPartialName(type);
type = "1";
if (target == 0)
{
SendReply(player, GetMsg("Player: None", player));
}
else
{
massTrigger = true;
}
}
else
{
massTrigger = true;
type = "1";
}
}
else if (args.Length == 2)
{
type = args[0];
target = FindUserIDByPartialName(args[1]);
if (target == 0)
{
SendReply(player, GetMsg("Player: None", player));
}
else
{
massTrigger = true;
}
}
if (!massTrigger || type == null) return;
switch (type)
{
case "1":
BaseEntity entity;
if (TryGetEntity<BaseEntity>(player, out entity))
{
ChangeOwner(entity, target);
SendReply(player, GetMsg("Ownership: Changed", player));
}
else
{
SendReply(player, GetMsg("Target: None", player));
}
break;
case "all":
massChangeOwner<BaseEntity>(player, target);
break;
case "block":
massChangeOwner<BuildingBlock>(player, target);
break;
case "storage":
massChangeOwner<StorageContainer>(player, target);
break;
case "sign":
massChangeOwner<Signage>(player, target);
break;
case "sleepingbag":
massChangeOwner<SleepingBag>(player, target);
break;
case "plant":
massChangeOwner<GrowableEntity>(player, target);
break;
case "oven":
massChangeOwner<BaseOven>(player, target);
break;
case "turret":
massChangeOwner<AutoTurret>(player, target);
break;
case "door":
massChangeOwner<Door>(player, target);
break;
case "cupboard":
massChangeOwner<BuildingPrivlidge>(player, target);
break;
}
}
[ChatCommand("unown")]
void cmdUnown(BasePlayer player, string command, string[] args)
{
if (!canChangeOwners(player))
{
SendReply(player, GetMsg("Denied: Permission", player));
return;
}
if (args.Length == 0)
{
args = new[] { "1" };
}
if (args.Length > 1)
{
SendReply(player, GetMsg("Syntax: Unown", player));
return;
}
if (args.Length != 1) return;
switch (args[0])
{
case "1":
BaseEntity entity;
if (TryGetEntity<BaseEntity>(player, out entity))
{
RemoveOwner(entity);
SendReply(player, GetMsg("Ownership: Removed", player));
}
else
{
SendReply(player, GetMsg("Target: None", player));
}
break;
case "all":
massChangeOwner<BaseEntity>(player);
break;
case "block":
massChangeOwner<BuildingBlock>(player);
break;
case "storage":
massChangeOwner<StorageContainer>(player);
break;
case "sign":
massChangeOwner<Signage>(player);
break;
case "sleepingbag":
massChangeOwner<SleepingBag>(player);
break;
case "plant":
massChangeOwner<GrowableEntity>(player);
break;
case "oven":
massChangeOwner<BaseOven>(player);
break;
case "turret":
massChangeOwner<AutoTurret>(player);
break;
case "door":
massChangeOwner<Door>(player);
break;
case "cupboard":
massChangeOwner<BuildingPrivlidge>(player);
break;
}
}
[ChatCommand("auth")]
void cmdAuth(BasePlayer player, string command, string[] args)
{
if (!canChangeOwners(player))
{
SendReply(player, GetMsg("Denied: Permission", player));
return;
}
var massCupboard = false;
var massTurret = false;
var checkCupboard = false;
var checkTurret = false;
var error = false;
BasePlayer target = null;
if (args.Length > 2)
{
error = true;
}
else if (args.Length == 1)
{
if (args[0] == "cupboard")
{
checkCupboard = true;
}
else if (args[0] == "turret")
{
checkTurret = true;
}
else
{
massCupboard = true;
target = FindPlayerByPartialName(args[0]);
}
}
else if (args.Length == 0)
{
checkCupboard = true;
}
else if (args.Length == 2)
{
if (args[0] == "cupboard")
{
massCupboard = true;
target = FindPlayerByPartialName(args[1]);
}
else if (args[0] == "turret")
{
massTurret = true;
target = FindPlayerByPartialName(args[1]);
}
else
{
error = true;
}
}
if ((massTurret || massCupboard) && target?.net?.connection == null)
{
SendReply(player, GetMsg("Player: None", player));
return;
}
if (error)
{
SendReply(player, GetMsg("Syntax: Auth", player));
return;
}
if (massCupboard)
{
massCupboardAuthorize(player, target);
}
if (checkCupboard)
{
var priv = RaycastAll<BuildingPrivlidge>(player.eyes.HeadRay());
if (priv is bool)
{
SendReply(player, GetMsg("Target: None", player));
return;
}
if (priv is BuildingPrivlidge)
{
ProdCupboard(player, (BuildingPrivlidge)priv);
}
}
if (massTurret)
{
massTurretAuthorize(player, target);
}
if (checkTurret)
{
var turret = RaycastAll<AutoTurret>(player.eyes.HeadRay());
if (turret is bool)
{
SendReply(player, GetMsg("Target: None", player));
return;
}
if (turret is AutoTurret)
{
ProdTurret(player, (AutoTurret)turret);
}
}
}
[ChatCommand("deauth")]
void cmdDeauth(BasePlayer player, string command, string[] args)
{
if (!canChangeOwners(player))
{
SendReply(player, GetMsg("Denied: Permission", player));
return;
}
var massCupboard = false;
var massTurret = false;
var error = false;
BasePlayer target = null;
if (args.Length > 2)
{
error = true;
}
else if (args.Length == 1)
{
if (args[0] == "cupboard")
{
SendReply(player, "Invalid Syntax./deauth cupboard PlayerName");
return;
}
if (args[0] == "turret")
{
SendReply(player, "Invalid Syntax./deauth turret PlayerName");
return;
}
massCupboard = true;
target = FindPlayerByPartialName(args[0]);
}
else if (args.Length == 0)
{
SendReply(player, "Invalid Syntax./deauth PlayerName\n/deauth turret/cupboard PlayerName");
return;
}
else if (args.Length == 2)
{
if (args[0] == "cupboard")
{
massCupboard = true;
target = FindPlayerByPartialName(args[1]);
}
else if (args[0] == "turret")
{
massTurret = true;
target = FindPlayerByPartialName(args[1]);
}
else
{
error = true;
}
}
if ((massTurret || massCupboard) && target?.net?.connection == null)
{
SendReply(player, GetMsg("Player: None", player));
return;
}
if (error)
{
SendReply(player, GetMsg("Syntax: Deauth", player));
return;
}
if (massCupboard)
{
massCupboardDeauthorize(player, target);
}
if (massTurret)
{
massTurretDeauthorize(player, target);
}
}
[ChatCommand("prod2")]
void cmdProd2(BasePlayer player, string command, string[] args)
{
if (!canCheckOwners(player))
{
SendReply(player, GetMsg("Denied: Permission", player));
return;
}
bool highlight = false;
if (args.Length > 0)
{
if (args[0] == "highlight")
{
highlight = true;
args = args.Skip(1).ToArray();
}
if (args.Length == 0)
{
massProd<BaseEntity>(player, highlight);
return;
}
switch (args[0])
{
case "all":
args = args.Skip(1).ToArray();
massProd<BaseEntity>(player, highlight, args);
break;
case "block":
massProd<BuildingBlock>(player, highlight);
break;
case "storage":
massProd<StorageContainer>(player, highlight);
break;
case "sign":
massProd<Signage>(player, highlight);
break;
case "sleepingbag":
massProd<SleepingBag>(player, highlight);
break;
case "plant":
massProd<GrowableEntity>(player, highlight);
break;
case "oven":
massProd<BaseOven>(player, highlight);
break;
case "turret":
massProdTurret(player, highlight);
break;
case "cupboard":
massProdCupboard(player, highlight);
break;
default:
massProd<BaseEntity>(player, highlight, args);
break;
}
}
else if (args.Length == 0)
{
massProd<BaseEntity>(player);
}
else
{
SendReply(player, GetMsg("Syntax: Prod2", player));
}
}
#endregion
#region Permission Checks
bool canCheckOwners(BasePlayer player)
{
if (player == null) return false;
if (player.net.connection.authLevel > 0) return true;
return permission.UserHasPermission(player.UserIDString, "entityowner.cancheckowners");
}
bool canCheckCodes(BasePlayer player)
{
if (player == null) return false;
if (player.net.connection.authLevel > 0) return true;
return permission.UserHasPermission(player.UserIDString, "entityowner.cancheckcodes");
}
bool canCheckAssignee(BasePlayer player)
{
if (player == null) return false;
if (player.net.connection.authLevel > 0) return true;
return permission.UserHasPermission(player.UserIDString, "entityowner.cancheckassignee");
}
bool canSeeDetails(BasePlayer player)
{
if (player == null) return false;
if (player.net.connection.authLevel > 0) return true;
return permission.UserHasPermission(player.UserIDString, "entityowner.seedetails");
}
bool canChangeOwners(BasePlayer player)
{
if (player == null) return false;
if (player.net.connection.authLevel > 0) return true;
return permission.UserHasPermission(player.UserIDString, "entityowner.canchangeowners");
}
#endregion
#region Ownership Methods
bool TryGetEntity<T>(BasePlayer player, out BaseEntity entity) where T : BaseEntity
{
entity = null;
var target = RaycastAll<BaseEntity>(player.eyes.HeadRay());
if (target is T)
{
entity = target as T;
return true;
}
return false;
}
void massChangeOwner<T>(BasePlayer player, ulong target = 0) where T : BaseEntity
{
object entityObject = false;
if (typeof(T) == typeof(BuildingBlock))
{
entityObject = FindBuilding(player.transform.position, DistanceThreshold);
}
else
{
entityObject = FindEntity(player.transform.position, DistanceThreshold);
}
if (entityObject is bool)
{
SendReply(player, GetMsg("Entities: None", player));
}
else
{
if (target == 0)
{
SendReply(player, GetMsg("Ownership: Removing", player));
}
else
{
SendReply(player, GetMsg("Ownership: Changing", player));
}
var entity = entityObject as T;
var entityList = new HashSet<T>();
var checkFrom = new List<Vector3>();
entityList.Add((T)entity);
checkFrom.Add(entity.transform.position);
var c = 1;
if (target == 0)
{
RemoveOwner(entity);
}
else
{
ChangeOwner(entity, target);
}
var current = 0;
var bbs = 0;
var ebs = 0;
if (entity is BuildingBlock)
{
bbs++;
}
else
{
ebs++;
}
while (true)
{
current++;
if (current > EntityLimit)
{
if (debug)
{
SendReply(player, GetMsg("Target: Limit", player) + " " + EntityLimit);
}
SendReply(player, string.Format(GetMsg("Entities: Count", player), c, bbs, ebs));
break;
}
if (current > checkFrom.Count)
{
SendReply(player, string.Format(GetMsg("Entities: Count", player), c, bbs, ebs));
break;
}
var hits = FindEntities<T>(checkFrom[current - 1], DistanceThreshold);
foreach (var entityComponent in hits.ToList())
{
if (!entityList.Add(entityComponent)) continue;
c++;
checkFrom.Add(entityComponent.transform.position);
if (entityComponent is BuildingBlock)
{
bbs++;
}
else
{
ebs++;
}
if (target == 0)
{
RemoveOwner(entityComponent);
}
else
{
ChangeOwner(entityComponent, target);
}
}
Pool.FreeList(ref hits);
}
if (target == 0)
{
SendReply(player, string.Format(GetMsg("Ownership: New", player), "No one"));
}
else
{
BasePlayer targetPlayer = BasePlayer.FindByID(target);
if (targetPlayer != null)
{
SendReply(player, string.Format(GetMsg("Ownership: New", player), targetPlayer.displayName));
SendReply(targetPlayer, GetMsg("Ownership: New Self", player));
}
else
{
IPlayer pl = covalence.Players.FindPlayerById(target.ToString());
SendReply(player, string.Format(GetMsg("Target: Owner", player), pl.Name));
}
}
}
}
void massProd<T>(BasePlayer player, bool highlight = false, params string[] filter) where T : BaseEntity
{
object entityObject = false;
entityObject = FindEntity(player.transform.position, DistanceThreshold);
if (entityObject is bool)
{
SendReply(player, GetMsg("Entities: None", player));
}
else
{
float health = 0f;
float maxHealth = 0f;
var prodOwners = new Dictionary<ulong, int>();
var entity = entityObject as BaseEntity;
if (entity.transform == null)
{
SendReply(player, GetMsg("Entities: None", player));
return;
}
SendReply(player, GetMsg("Structure: Prodding", player));
var entityList = new HashSet<T>();
var checkFrom = new List<Vector3>();
if (entity is T)
{
entityList.Add((T)entity);
}
var total = 0;
var skip = false;
if (entity is T)
{
if (filter.Length > 0)
{
skip = true;
foreach (var f in filter)
{
if (entity.name.ToLower().Contains(f.ToLower()))
{
skip = false;
break;
}
}
}
if (!skip)
{
prodOwners.Add(entity.OwnerID, 1);
health += entity.Health();
maxHealth += entity.MaxHealth();
total++;
}
}
var current = -1;
var distanceThreshold = DistanceThreshold;
if (typeof(T) != typeof(BuildingBlock) && typeof(T) != typeof(BaseEntity))
distanceThreshold += 30;
while (true)
{
current++;
if (current > EntityLimit)
{
SendReply(player, GetMsg("Target: Limit", player) + " " + EntityLimit);
break;
}
if (current > checkFrom.Count)
{
break;
}
var hits = FindEntities<T>(checkFrom.Count > 0 ? checkFrom[current - 1] : entity.transform.position, distanceThreshold);
skip = false;
foreach (var fentity in hits)
{
if (fentity.transform == null || !entityList.Add(fentity) || fentity.name == "player/player")
continue;
if (filter.Length > 0)
{
skip = true;
foreach (var f in filter)
{
if (fentity.name.ToLower().Contains(f.ToLower()))
{
skip = false;
break;
}
}
}
checkFrom.Add(fentity.transform.position);
if (!skip)
{
total++;
if (highlight)
{
SendHighlight(player, fentity.transform.position);
}
var pid = fentity.OwnerID;
if (prodOwners.ContainsKey(pid))
{
prodOwners[pid]++;
}
else
{
prodOwners.Add(pid, 1);
}
health += fentity.Health();
maxHealth += fentity.MaxHealth();
}
}
Pool.FreeList(ref hits);
}
var unknown = 100;
var msg = string.Empty;
msg = "<size=16>Structure</size>\n";
msg += $"Entities: {total}\n";
if (health > 0 && maxHealth > 0)
{
var condition = Mathf.Round(health * 100 / maxHealth);
msg += string.Format(GetMsg("Structure: Condition Percent", player), condition);
}
SendReply(player, msg);
msg = "<size=16>Ownership</size>\n";
if (total > 0)
{
foreach (var kvp in prodOwners)
{
var perc = kvp.Value * 100 / total;
if (kvp.Key != 0)
{
var n = FindPlayerName(kvp.Key);
msg += $"{n}: {perc}%\n";
unknown -= perc;
}
}
}
if (unknown > 0)
msg += string.Format(GetMsg("Player: Unknown Percent", player), unknown);
SendReply(player, msg);
}
}
void SendHighlight(BasePlayer player, Vector3 position)
{
player.SendConsoleCommand("ddraw.sphere", 30f, Color.magenta, position, 2f);
player.SendNetworkUpdateImmediate();
}
void ProdCupboard(BasePlayer player, BuildingPrivlidge cupboard)
{
List<string> authorizedUsers;
var sb = new StringBuilder();
if (TryGetCupboardUserNames(cupboard, out authorizedUsers))
{
sb.AppendLine(string.Format(GetMsg("Entities: Authorized", player), authorizedUsers.Count));
foreach (var n in authorizedUsers)
sb.AppendLine(n);
}
else
sb.Append(string.Format(GetMsg("Target: None", player)));
SendReply(player, sb.ToString());
}
void ProdTurret(BasePlayer player, AutoTurret turret)
{
List<string> authorizedUsers;
var sb = new StringBuilder();
if (TryGetTurretUserNames(turret, out authorizedUsers))
{
sb.AppendLine(string.Format(GetMsg("Entities: Authorized", player), authorizedUsers.Count));
foreach (var n in authorizedUsers)
sb.AppendLine(n);
}
else
{
sb.Append(string.Format(GetMsg("Target: None", player)));
}
SendReply(player, sb.ToString());
}
void massProdCupboard(BasePlayer player, bool highlight = false)
{
object entityObject = false;
entityObject = FindEntity(player.transform.position, DistanceThreshold);
if (entityObject is bool)
{
SendReply(player, GetMsg("Entities: None", player));
}
else
{
var total = 0;
var prodOwners = new Dictionary<ulong, int>();
SendReply(player, GetMsg("Cupboards: Prodding", player));
var entity = entityObject as BaseEntity;
var entityList = new HashSet<BaseEntity>();
var checkFrom = new List<Vector3>();
checkFrom.Add(entity.transform.position);
var current = 0;
while (true)
{
current++;
if (current > EntityLimit)
{
if (debug)
SendReply(player, GetMsg("Target: Limit", player) + " " + EntityLimit);
SendReply(player, string.Format(GetMsg("Ownership: Count", player), total));
break;
}
if (current > checkFrom.Count)
{
SendReply(player, string.Format(GetMsg("Ownership: Count", player), total));
break;
}
var entities = FindEntities<BuildingPrivlidge>(checkFrom[current - 1], CupboardDistanceThreshold);
foreach (var e in entities)
{
if (!entityList.Add(e)) { continue; }
if (highlight)
{
SendHighlight(player, e.transform.position);
}
checkFrom.Add(e.transform.position);
foreach (var pnid in e.authorizedPlayers)
{
if (prodOwners.ContainsKey(pnid.userid))
prodOwners[pnid.userid]++;
else
prodOwners.Add(pnid.userid, 1);
}
total++;
}
Pool.FreeList(ref entities);
}
var percs = new Dictionary<ulong, int>();
var unknown = 100;
if (total > 0)
{
foreach (var kvp in prodOwners)
{
var perc = kvp.Value * 100 / total;
percs.Add(kvp.Key, perc);
var n = FindPlayerName(kvp.Key);
if (!n.Contains("Unknown: "))
{
SendReply(player, n + ": " + perc + "%");
unknown -= perc;
}
}
if (unknown > 0)
SendReply(player, string.Format(GetMsg("Player: Unknown Percent", player), unknown));
}
}
}
void massProdTurret(BasePlayer player, bool highlight = false)
{
object entityObject = false;
entityObject = FindEntity(player.transform.position, DistanceThreshold);
if (entityObject is bool)
{
SendReply(player, GetMsg("Entities: None", player));
}
else
{
var total = 0;
var prodOwners = new Dictionary<ulong, int>();
SendReply(player, GetMsg("Turrets: Prodding", player));
var entity = entityObject as BaseEntity;
var entityList = new HashSet<BaseEntity>();
var checkFrom = new List<Vector3>();
checkFrom.Add(entity.transform.position);
var current = 0;
while (true)
{
current++;
if (current > EntityLimit)
{
if (debug)
SendReply(player, GetMsg("Target: Limit", player) + " " + EntityLimit);
SendReply(player, string.Format(GetMsg("Ownership: Count", player), total));
break;
}
if (current > checkFrom.Count)
{
SendReply(player, string.Format(GetMsg("Ownership: Count", player), total));
break;
}
var entities = FindEntities<BaseEntity>(checkFrom[current - 1], DistanceThreshold);
foreach (var e in entities)
{
if (!entityList.Add(e)) { continue; }
if (highlight)
{
SendHighlight(player, e.transform.position);
}
checkFrom.Add(e.transform.position);
if (e is AutoTurret)
{
var turret = e as AutoTurret;
if (turret.OwnerID.IsSteamId())
{
// ... [Code preview truncated due to length. Full source in attached file] ...