C#:
using System.Collections.Generic;
using System.Data;
using UnityEngine;
using System.Linq;
using Oxide.Core.Plugins;
namespace Oxide.Plugins {
[Info("Finder", "Reneb", "3.0.7", ResourceId = 692)]
class Finder : RustPlugin {
//////////////////////////////////////////////////////////////////////////////////////////
///// Plugin References
//////////////////////////////////////////////////////////////////////////////////////////
[PluginReference]
Plugin PlayerDatabase;
Dictionary<ulong, PlayerFinder> cachedFinder = new Dictionary<ulong, PlayerFinder>();
static string findPermission = "finder.find";
static int findAuthlevel = 1;
protected override void LoadDefaultConfig() {
}
private void CheckCfg<T>(string Key, ref T var) {
if (Config[Key] is T) var = (T)Config[Key];
else Config[Key] = var;
}
void Init() {
CheckCfg<int>("auth level permission", ref findAuthlevel);
CheckCfg<string>("oxide Permission", ref findPermission);
SaveConfig();
}
void Loaded() {
permission.RegisterPermission(findPermission, this);
lang.RegisterMessages(new Dictionary<string, string> {
{
"You don't have the permission to use this command", "You don't have the permission to use this command"
}
, {
"ListCommands", "/find player PLAYERNAME/STEAMID\n\r/find cupboard PLAYERNAME/STEAMID\n\r/find bag PLAYERNAME/STEAMID\n\r/find building PLAYERNAME/STEAMID\n\r/find item ITEMNAME MINAMOUNT\n\r/find tp FINDID\n\r/find deployable PLAYENAME/STEAMID"
}
, {
"Multiple players found:\n\r", "Multiple players found:\n\r"
}
, {
"No matching players found.", "No matching players found."
}
, {
"You need to select a target player.", "You need to select a target player."
}
, {
"This player doesn't have a position", "This player doesn't have a position"
}
, {
"This player doesn't have any cupboard privileges", "This player doesn't have any cupboard privileges"
}
, {
"You didn't find anything yet", "You didn't find anything yet"
}
, {
"You need to select a target findid.", "You need to select a target findid."
}
, {
"This id is out of range.", "This id is out of range."
}
, {
"You are using the console, you can't tp!", "You are using the console, you can't tp!"
}
, {
"This player hasn't built anything yet", "This player hasn't built anything yet"
}
, {
"usage: /find item ITEMNAME MINAMOUNT.", "usage: /find item ITEMNAME MINAMOUNT."
}
, {
"You didn't use a valid item name.", "You didn't use a valid item name."
}
}
, this);
}
bool hasPermission(BasePlayer player, string perm, int authLevel) {
var lvl = player?.net?.connection?.authLevel;
if (lvl == null || lvl >= authLevel) {
return true;
}
return permission.UserHasPermission(player.userID.ToString(), perm);
}
string GetMsg(string key, BasePlayer player = null) {
return lang.GetMessage(key, this, player == null ? null : player.userID.ToString());
}
class FindData {
string Name;
public Vector3 Pos;
string TypeName;
public FindData(string TypeName, Vector3 Pos, string Name) {
this.Name = Name;
this.TypeName = TypeName;
this.Pos = Pos;
}
public override string ToString() {
return string.Format("{0} - {1}{2}", TypeName, Pos.ToString(), Name == string.Empty ? string.Empty : (" - " + Name));
}
}
class PlayerFinder {
string Name;
string Id;
bool Online;
public List<FindData> Data = new List<FindData>();
public PlayerFinder(string Name, string Id, bool Online) {
this.Name = Name;
this.Id = Id;
this.Online = Online;
}
public void AddFind(string TypeName, Vector3 Pos, string Name) {
Data.Add(new FindData(TypeName, Pos, Name));
}
public override string ToString() {
return string.Format("{0} {1} - {2}", Id, Name, Online ? "Connected" : "Offline");
}
}
PlayerFinder GetPlayerInfo(ulong userID) {
var steamid = userID.ToString();
var player = covalence.Players.FindPlayer(steamid);
if(player != null) {
return new PlayerFinder(player.Name, player.Id, player.IsConnected);
}
if(PlayerDatabase != null) {
var name = (string)PlayerDatabase?.Call("GetPlayerData", steamid, "name");
if(name != null) {
return new PlayerFinder(name, steamid, false);
}
}
return new PlayerFinder("Unknown", steamid, false);
}
private object FindPosition(ulong userID) {
BasePlayer p = null;
foreach (var plyr in BasePlayer.activePlayerList.Where(x=>x.userID == userID)) p = plyr;
if(p == null) {
foreach (var slplyr in BasePlayer.sleepingPlayerList.Where(x=>x.userID == userID)) p = slplyr;
if (p == null) return null;
}
return p.transform.position;
}
private object FindPlayerID(string arg, BasePlayer source = null) {
ulong userID = 0L;
if (arg.Length == 17 && ulong.TryParse(arg, out userID)) return userID;
var players = covalence.Players.FindPlayers(arg).ToList();
if(players.Count > 1) {
var returnstring = GetMsg("Multiple players found:\n\r", source);
foreach(var p in players) {
returnstring += string.Format("{0} - {1}\n\r", p.Id, p.Name);
}
return returnstring;
}
if(players.Count == 1) {
return ulong.Parse(players[0].Id);
}
if (PlayerDatabase != null) {
string success = PlayerDatabase.Call("FindPlayer", arg) as string;
if (success.Length == 17 && ulong.TryParse(success, out userID)) {
return userID;
}
else return success;
}
return GetMsg("No matching players found.", source);
}
string Find(BasePlayer player, string[] args) {
string returnstring = string.Empty;
if(!hasPermission(player, findPermission, findAuthlevel)) {
return GetMsg("You don't have the permission to use this command.", player);
}
if(args == null || args.Length == 0) {
return GetMsg("ListCommands", player);
}
var puserid = player == null ? 0L : player.userID;
switch(args[0].ToLower()) {
case "player" : case "bag" : case "cupboard" : case "deployable" : case "building" : if(args.Length == 1) {
return GetMsg("You need to select a target player.", player);
}
var f = FindPlayerID(args[1], player);
if(!(f is ulong)) {
return f.ToString();
}
ulong targetID = (ulong)f;
var d = GetPlayerInfo(targetID);
returnstring = d.ToString() + ":\n\r";
switch (args[0].ToLower()) {
case "player" : var p = FindPosition(targetID);
if(p == null) {
returnstring += GetMsg("This player doesn't have a position", player);
}
else d.AddFind("Position", (Vector3)p, string.Empty);
break;
case "bag" : var bs = SleepingBag.FindForPlayer(targetID, true).ToList();
if (bs.Count == 0) {
returnstring += GetMsg("This player doesn't have any bags", player);
}
foreach(var b in bs) {
d.AddFind(b.ShortPrefabName, b.transform.position, b.niceName);
}
break;
case "cupboard" : var cs = BaseNetworkable.serverEntities.OfType<BuildingPrivlidge>().Where(x => x.authorizedPlayers.Any((ProtoBuf.PlayerNameID z) => z.userid == targetID)).ToList();
if(cs.Count== 0) {
returnstring += GetMsg("This player doesn't have any cupboard privileges", player);
}
foreach(var c in cs) {
d.AddFind("Tool Cupboard", c.transform.position, string.Empty);
}
break;
case "deployable" : var ep = BaseNetworkable.serverEntities.OfType<BaseEntity>().Where(x => x.OwnerID == targetID ).ToList();
if (ep.Count == 0) {
returnstring += GetMsg("This player has no deployables", player);
}
foreach(var c in ep) {
d.AddFind("Deployable", c.transform.position, c.ShortPrefabName);
}
break;
case "building" : var bb = BaseNetworkable.serverEntities.OfType<BuildingBlock>().Where(x => x.OwnerID == targetID).ToList();
if (bb.Count == 0) {
returnstring += GetMsg("This player hasn't built anything yet", player);
}
var dic = new Dictionary<uint, Dictionary<string, object>>();
foreach(var b in bb) {
if(!dic.ContainsKey(b.buildingID)) {
dic.Add(b.buildingID, new Dictionary<string, object> {
{
"pos", b.transform.position
}
, {
"num", 0
}
}
);
}
dic[b.buildingID]["num"] = (int)dic[b.buildingID]["num"] + 1;
}
foreach (var c in dic) {
d.AddFind("Building", (Vector3)c.Value["pos"], c.Value["num"].ToString());
}
break;
default : break;
}
for (int i = 0; i < d.Data.Count; i++) {
returnstring += i.ToString() + " - " + d.Data[i].ToString() + "\n\r";
}
if (cachedFinder.ContainsKey(puserid)) {
cachedFinder[puserid].Data.Clear();
cachedFinder[puserid] = null;
cachedFinder.Remove(puserid);
}
cachedFinder.Add(puserid, d);
break;
//Here
case "item" : if(args.Length < 3) {
return GetMsg("usage: /find item ITEMNAME MINAMOUNT optional:STEAMID.", player);
}
var pu = GetPlayerInfo(puserid);
var itemname = args[1].ToLower();
ulong ownerid = 0L;
if (args.Length > 3) ulong.TryParse(args[3], out ownerid);
var itemamount = 0;
if(!(int.TryParse(args[2], out itemamount))) {
return GetMsg("usage: /find item ITEMNAME MINAMOUNT optional:STEAMID.", player);
}
ItemDefinition item = null;
for(int i = 0; i < ItemManager.itemList.Count; i++) {
if(ItemManager.itemList[i].displayName.english.ToLower() == itemname) {
item = ItemManager.itemList[i];
break;
}
}
if(item == null) {
return GetMsg("You didn't use a valid item name.", player);
}
foreach (StorageContainer sc in BaseNetworkable.serverEntities.OfType<StorageContainer>()) {
ItemContainer inventory = sc.inventory;
if (inventory == null) continue;
List<Item> list = inventory.itemList.FindAll((Item x) => x.info.itemid == item.itemid);
int total = 0;
for (int i = 0; i < list.Count; i++) total += list[i].amount;
if (total < itemamount) continue;
pu.AddFind("Box", sc.transform.position, total.ToString());
}
foreach (var plyr in BasePlayer.activePlayerList) {
PlayerInventory inventory = plyr.inventory;
if (inventory == null) continue;
int amount = inventory.GetAmount(item.itemid);
if (amount < itemamount) continue;
pu.AddFind(string.Format("{0} {1}", plyr.userID.ToString(), plyr.displayName), plyr.transform.position, amount.ToString());
}
for (int i = 0; i < pu.Data.Count; i++) {
returnstring += i.ToString() + " - " + pu.Data[i].ToString() + "\n\r";
}
if (cachedFinder.ContainsKey(puserid)) {
cachedFinder[puserid].Data.Clear();
cachedFinder[puserid] = null;
cachedFinder.Remove(puserid);
}
cachedFinder.Add(puserid, pu);
break;
case "tp" : if(player == null) {
return GetMsg("You are using the console, you can't tp!", player);
}
if (!cachedFinder.ContainsKey(puserid)) {
return GetMsg("You didn't find anything yet", player);
}
if (args.Length == 1) {
return GetMsg("You need to select a target findid.", player);
}
var fp = cachedFinder[puserid];
var id = 0;
int.TryParse(args[1], out id);
if(id >= fp.Data.Count) {
return GetMsg("This id is out of range.", player);
}
var data = cachedFinder[puserid].Data[id];
player.MovePosition(data.Pos);
player.ClientRPCPlayer(null, player, "ForcePositionTo", data.Pos);
returnstring += data.ToString();
break;
default : returnstring += GetMsg("ListCommands", player);
break;
}
return returnstring;
}
[ChatCommand("find")]
void cmdChatFind(BasePlayer player, string command, string[] args) {
SendReply(player, Find(player, args));
}
[ConsoleCommand("finder.find")]
void cmdConsoleFind(ConsoleSystem.Arg arg) {
var player = arg.Player();
arg.ReplyWith(Find(player, arg.Args));
}
}
}