using Oxide.Core; using Oxide.Core.Libraries; using Oxide.Core.Libraries.Covalence; using System; using System.Globalization; using System.Text.RegularExpressions; using UnityEngine; namespace Oxide.Game.Rust.Libraries { public class Player : Library { #region Initialization private static readonly string ipPattern = @":{1}[0-9]{1}\d*"; internal readonly Permission permission = Interface.Oxide.GetLibrary(); #endregion Initialization #region Information /// /// Gets the player's language /// public CultureInfo Language(BasePlayer player) => CultureInfo.GetCultureInfo(player.net.connection.info.GetString("global.language") ?? "en"); /// /// Gets the player's IP address /// public string Address(Network.Connection connection) => Regex.Replace(connection.ipaddress, ipPattern, ""); /// /// Gets the player's IP address /// public string Address(BasePlayer player) => player?.net?.connection != null ? Address(player.net.connection) : null; /// /// Gets the player's average network ping /// public int Ping(Network.Connection connection) => Network.Net.sv.GetAveragePing(connection); /// /// Gets the player's average network ping /// public int Ping(BasePlayer player) => Ping(player.net.connection); /// /// Returns if the player is admin /// public bool IsAdmin(ulong id) => ServerUsers.Is(id, ServerUsers.UserGroup.Owner); /// /// Returns if the player is admin /// public bool IsAdmin(string id) => IsAdmin(Convert.ToUInt64(id)); /// /// Returns if the player is admin /// public bool IsAdmin(BasePlayer player) => IsAdmin(player.userID); /// /// Gets if the player is banned /// public bool IsBanned(ulong id) => ServerUsers.Is(id, ServerUsers.UserGroup.Banned); /// /// Gets if the player is banned /// public bool IsBanned(string id) => IsBanned(Convert.ToUInt64(id)); /// /// Gets if the player is banned /// public bool IsBanned(BasePlayer player) => IsBanned(player.userID); /// /// Gets if the player is connected /// public bool IsConnected(BasePlayer player) => player.IsConnected; /// /// Returns if the player is sleeping /// public bool IsSleeping(ulong id) => BasePlayer.FindSleeping(id); /// /// Returns if the player is sleeping /// public bool IsSleeping(string id) => IsSleeping(Convert.ToUInt64(id)); /// /// Returns if the player is sleeping /// public bool IsSleeping(BasePlayer player) => IsSleeping(player.userID); #endregion Information #region Administration /// /// Bans the player from the server based on user ID /// /// /// public void Ban(ulong id, string reason = "") { if (IsBanned(id)) { return; } BasePlayer player = FindById(id); ServerUsers.Set(id, ServerUsers.UserGroup.Banned, player?.displayName ?? "Unknown", reason); ServerUsers.Save(); if (player != null && IsConnected(player)) { Kick(player, reason); } } /// /// Bans the player from the server based on user ID /// /// /// public void Ban(string id, string reason = "") => Ban(Convert.ToUInt64(id), reason); /// /// Bans the player from the server /// /// /// public void Ban(BasePlayer player, string reason = "") => Ban(player.UserIDString, reason); /// /// Heals the player by specified amount /// /// /// public void Heal(BasePlayer player, float amount) => player.Heal(amount); /// /// Damages the player by specified amount /// /// /// public void Hurt(BasePlayer player, float amount) => player.Hurt(amount); /// /// Kicks the player from the server /// /// /// public void Kick(BasePlayer player, string reason = "") => player.Kick(reason); /// /// Causes the player to die /// /// public void Kill(BasePlayer player) => player.Die(); /// /// Renames the player to specified name /// /// /// public void Rename(BasePlayer player, string name) { name = string.IsNullOrEmpty(name.Trim()) ? player.displayName : name; player.net.connection.username = name; player.displayName = name; player._name = name; player.SendNetworkUpdateImmediate(); player.IPlayer.Name = name; permission.UpdateNickname(player.UserIDString, name); Teleport(player, player.transform.position); } /// /// Teleports the player to the specified position /// /// /// public void Teleport(BasePlayer player, Vector3 destination) { if (player.IsAlive() && !player.IsSpectating()) { try { // Dismount and remove parent, if applicable player.EnsureDismounted(); player.SetParent(null, true, true); // Prevent player from getting hurt //player.SetPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot, true); //player.UpdatePlayerCollider(true); //player.UpdatePlayerRigidbody(false); player.EnableServerFall(true); // Teleport the player to position player.MovePosition(destination); player.ClientRPCPlayer(null, player, "ForcePositionTo", destination); // Update network group if outside current group /*if (!player.net.sv.visibility.IsInside(player.net.group, destination)) { player.UpdateNetworkGroup(); player.SendNetworkUpdateImmediate(); player.ClearEntityQueue(); player.SendFullSnapshot(); }*/ } finally { // Restore player behavior //player.UpdatePlayerCollider(true); //player.UpdatePlayerRigidbody(true); player.EnableServerFall(false); } } } /// /// Teleports the player to the target player /// /// /// public void Teleport(BasePlayer player, BasePlayer target) => Teleport(player, Position(target)); /// /// Teleports the player to the specified position /// /// /// /// /// public void Teleport(BasePlayer player, float x, float y, float z) => Teleport(player, new Vector3(x, y, z)); /// /// Unbans the player by user ID /// public void Unban(ulong id) { if (!IsBanned(id)) { return; } ServerUsers.Remove(id); ServerUsers.Save(); } /// /// Unbans the player by user ID /// public void Unban(string id) => Unban(Convert.ToUInt64(id)); /// /// Unbans the player /// public void Unban(BasePlayer player) => Unban(player.userID); #endregion Administration #region Location /// /// Returns the position of player as Vector3 /// /// /// public Vector3 Position(BasePlayer player) => player.transform.position; #endregion Location #region Player Finding /// /// Gets the player object using a name, Steam ID, or IP address /// /// /// public BasePlayer Find(string nameOrIdOrIp) { foreach (BasePlayer player in Players) { if (!nameOrIdOrIp.Equals(player.displayName, StringComparison.OrdinalIgnoreCase) && !nameOrIdOrIp.Equals(player.UserIDString) && !nameOrIdOrIp.Equals(player.net.connection.ipaddress)) { continue; } return player; } return null; } /// /// Gets the player object using a Steam ID /// /// /// public BasePlayer FindById(string id) { foreach (BasePlayer player in Players) { if (!id.Equals(player.UserIDString)) { continue; } return player; } return null; } /// /// Gets the player object using a Steam ID /// /// /// public BasePlayer FindById(ulong id) { foreach (BasePlayer player in Players) { if (!id.Equals(player.userID)) { continue; } return player; } return null; } /// /// Returns all connected players /// public ListHashSet Players => BasePlayer.activePlayerList; /// /// Returns all sleeping players /// public ListHashSet Sleepers => BasePlayer.sleepingPlayerList; #endregion Player Finding #region Chat and Commands /// /// Sends the specified message and prefix to the player /// /// /// /// /// public void Message(BasePlayer player, string message, string prefix, ulong userId = 0, params object[] args) { if (string.IsNullOrEmpty(message)) { return; } message = args.Length > 0 ? string.Format(Formatter.ToUnity(message), args) : Formatter.ToUnity(message); string formatted = prefix != null ? $"{prefix} {message}" : message; player.SendConsoleCommand("chat.add", 2, userId, formatted); } /// /// Sends the specified message to the player /// /// /// /// public void Message(BasePlayer player, string message, ulong userId = 0) => Message(player, message, null, userId); /// /// Replies to the player with the specified message and prefix /// /// /// /// /// public void Reply(BasePlayer player, string message, string prefix, ulong userId = 0, params object[] args) { Message(player, message, prefix, userId, args); } /// /// Replies to the player with the specified message /// /// /// /// public void Reply(BasePlayer player, string message, ulong userId = 0) => Message(player, message, null, userId); /// /// Runs the specified player command /// /// /// /// public void Command(BasePlayer player, string command, params object[] args) => player.SendConsoleCommand(command, args); #endregion Chat and Commands #region Item Handling /// /// Drops item by item ID from player's inventory /// /// /// public void DropItem(BasePlayer player, int itemId) { Vector3 position = player.transform.position; PlayerInventory inventory = Inventory(player); for (int s = 0; s < inventory.containerMain.capacity; s++) { global::Item i = inventory.containerMain.GetSlot(s); if (i.info.itemid == itemId) { i.Drop(position + new Vector3(0f, 1f, 0f) + position / 2f, (position + new Vector3(0f, 0.2f, 0f)) * 8f); } } for (int s = 0; s < inventory.containerBelt.capacity; s++) { global::Item i = inventory.containerBelt.GetSlot(s); if (i.info.itemid == itemId) { i.Drop(position + new Vector3(0f, 1f, 0f) + position / 2f, (position + new Vector3(0f, 0.2f, 0f)) * 8f); } } for (int s = 0; s < inventory.containerWear.capacity; s++) { global::Item i = inventory.containerWear.GetSlot(s); if (i.info.itemid == itemId) { i.Drop(position + new Vector3(0f, 1f, 0f) + position / 2f, (position + new Vector3(0f, 0.2f, 0f)) * 8f); } } } /// /// Drops item from the player's inventory /// /// /// public void DropItem(BasePlayer player, global::Item item) { Vector3 position = player.transform.position; PlayerInventory inventory = Inventory(player); for (int s = 0; s < inventory.containerMain.capacity; s++) { global::Item i = inventory.containerMain.GetSlot(s); if (i == item) { i.Drop(position + new Vector3(0f, 1f, 0f) + position / 2f, (position + new Vector3(0f, 0.2f, 0f)) * 8f); } } for (int s = 0; s < inventory.containerBelt.capacity; s++) { global::Item i = inventory.containerBelt.GetSlot(s); if (i == item) { i.Drop(position + new Vector3(0f, 1f, 0f) + position / 2f, (position + new Vector3(0f, 0.2f, 0f)) * 8f); } } for (int s = 0; s < inventory.containerWear.capacity; s++) { global::Item i = inventory.containerWear.GetSlot(s); if (i == item) { i.Drop(position + new Vector3(0f, 1f, 0f) + position / 2f, (position + new Vector3(0f, 0.2f, 0f)) * 8f); } } } /// /// Gives quantity of an item to the player /// /// /// /// public void GiveItem(BasePlayer player, int itemId, int quantity = 1) => GiveItem(player, Item.GetItem(itemId), quantity); /// /// Gives quantity of an item to the player /// /// /// /// public void GiveItem(BasePlayer player, global::Item item, int quantity = 1) => player.inventory.GiveItem(ItemManager.CreateByItemID(item.info.itemid, quantity)); #endregion Item Handling #region Inventory Handling /// /// Gets the inventory of the player /// /// /// public PlayerInventory Inventory(BasePlayer player) => player.inventory; /// /// Clears the inventory of the player /// /// public void ClearInventory(BasePlayer player) => Inventory(player)?.Strip(); /// /// Resets the inventory of the player /// /// public void ResetInventory(BasePlayer player) { PlayerInventory inventory = Inventory(player); if (inventory != null) { inventory.DoDestroy(); inventory.ServerInit(player); } } #endregion Inventory Handling } }