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 cachedFinder = new Dictionary(); static string findPermission = "finder.find"; static int findAuthlevel = 1; protected override void LoadDefaultConfig() { } private void CheckCfg(string Key, ref T var) { if (Config[Key] is T) var = (T)Config[Key]; else Config[Key] = var; } void Init() { CheckCfg("auth level permission", ref findAuthlevel); CheckCfg("oxide Permission", ref findPermission); SaveConfig(); } void Loaded() { permission.RegisterPermission(findPermission, this); lang.RegisterMessages(new Dictionary { {"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 Data = new List(); 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().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().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().Where(x => x.OwnerID == targetID).ToList(); if (bb.Count == 0) { returnstring += GetMsg("This player hasn't built anything yet", player); } var dic = new Dictionary>(); foreach(var b in bb) { if(!dic.ContainsKey(b.buildingID)) { dic.Add(b.buildingID, new Dictionary { {"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()) { ItemContainer inventory = sc.inventory; if (inventory == null) continue; List 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)); } } }