C#:
using System;
using System.Collections.Generic;
using Rust;
using UnityEngine;
using Oxide.Core;
using System.Linq;
using Oxide.Game.Rust.Cui;
using ProtoBuf;
namespace Oxide.Plugins
{
[Info("Godmode", "Wulf/lukespragg/edits by Shady", "3.2.2", ResourceId = 673)]
[Description("Allows players with permission to become invincible/invulnerable")]
class Godmode : RustPlugin
{
// Do NOT edit this file, instead edit Godmode.json in oxide/config and Godmode.en.json in the oxide/lang directory,
// or create a new language file for another language using the 'en' file as a default
//p.s, from Shady: to whoever ever reads my source code, fuck you, i'll hardcode as much as i want, whenever i want, wherever i want
//nobody has time to run a server and worry about every little tiny detail when they're the sole developer and manager/owner
//also, i wouldn't care even if there was more time.fuck you.//with love.written on a good day.#region Initialization
const string permAllowed = "godmode.allowed";
public static Godmode ins;
void Init()
{
ins = this;
LoadDefaultConfig();
LoadDefaultMessages();
LoadSavedData();
if (BasePlayer.activePlayerList != null && BasePlayer.activePlayerList.Count > 0) UpdateHooks(AnyConnectedGod());
else UpdateHooks(false);
permission.RegisterPermission(permAllowed, this);
for (int i = 0; i < BasePlayer.activePlayerList.Count; i++)
{
var p = BasePlayer.activePlayerList[i];
if (p != null && p.IsConnected && IsGodU(p.userID))
GodGUI(p);
}
}
bool? lastHookState;
void UpdateHooks(bool state)
{
if (lastHookState.HasValue && ((bool)lastHookState) == state) return;
if (state)
{
// Subscribe(nameof(OnEntityTakeDamage));
// Subscribe(nameof(CanLootEntity));
Subscribe(nameof(OnRunPlayerMetabolism));
// Subscribe(nameof(CanBeWounded));
}
else
{
//Unsubscribe(nameof(OnEntityTakeDamage));
// Unsubscribe(nameof(CanLootEntity));
Unsubscribe(nameof(OnRunPlayerMetabolism));
// Unsubscribe(nameof(CanBeWounded));
}
}
void LoadSavedData()
{
storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Title);
foreach (var god in storedData.Gods) gods[god.GetUserId()] = god;
}
void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Title, storedData);
#endregion
#region Configuration
bool canBeHurt;
bool canBeLooted;
bool canEarnXp;
bool canHurtPlayers;
bool canLootPlayers;
bool infiniteRun;
bool informOnAttack;
bool prefixEnabled;
string prefixFormat;
protected override void LoadDefaultConfig()
{
Config["CanBeHurt"] = canBeHurt = GetConfig("CanBeHurt", false);
Config["CanBeLooted"] = canBeLooted = GetConfig("CanBeLooted", false);
Config["CanEarnXp"] = canEarnXp = GetConfig("CanEarnXp", true);
Config["CanHurtPlayers"] = canHurtPlayers = GetConfig("CanHurtPlayers", true);
Config["CanLootPlayers"] = canLootPlayers = GetConfig("CanLootPlayers", true);
Config["InfiniteRun"] = infiniteRun = GetConfig("InfiniteRun", true);
Config["InformOnAttack"] = informOnAttack = GetConfig("InformOnAttack", true);
Config["PrefixEnabled"] = prefixEnabled = GetConfig("PrefixEnabled", true);
Config["PrefixFormat"] = prefixFormat = GetConfig("PrefixFormat", "[God]");
SaveConfig();
}
#endregion
#region Localization
void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Disabled"] = "You have disabled godmode",
["DisabledBy"] = "Your godmode has been disabled by {0}",
["DisabledFor"] = "You have disabled godmode for {0}",
["Enabled"] = "You have enabled godmode",
["EnabledBy"] = "Your godmode has been enabled by {0}",
["EnabledFor"] = "You have enabled godmode for {0}",
["Godlist"] = "Players with godmode enabled:",
["GodlistNone"] = "No players have godmode enabled",
["InformAttacker"] = "{0} is in godmode and can't take any damage",
["InformVictim"] = "{0} just tried to deal damage to you",
["NoLooting"] = "You are not allowed to loot a player with godmode",
["NotAllowed"] = "Sorry, you can't use '{0}' right now",
["PlayerNotFound"] = "No players were found with that name"
}, this);
}
#endregion
class StoredData
{
// [JsonProperty(Required = Required.AllowNull, DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore)]
public readonly HashSet<PlayerInfo> Gods = new HashSet<PlayerInfo>();
}
class PlayerInfo
{
public string UserId;
public string Name;
public PlayerInfo()
{
}
public PlayerInfo(BasePlayer player)
{
if (player == null) return;
UserId = player.UserIDString;
Name = player.displayName;
}
public ulong GetUserId()
{
ulong userId;
return !ulong.TryParse(UserId, out userId) ? 0 : userId;
}
}
StoredData storedData;
readonly Dictionary<ulong, PlayerInfo> gods = new Dictionary<ulong, PlayerInfo>();
readonly Dictionary<BasePlayer, long> playerInformHistory = new Dictionary<BasePlayer, long>();
readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
bool IsGod(string id) => GetPlayerInfo(id) != null;
bool IsGodU(ulong id) => GetPlayerInfo(id) != null;
void Unload()
{
SaveData();
string guid;
for (int i = 0; i < BasePlayer.activePlayerList.Count; i++)
{
var p = BasePlayer.activePlayerList[i];
if (p != null && p.IsConnected && _guiInfo.TryGetValue(p.userID, out guid))
CuiHelper.DestroyUi(p, guid);
}
}
void OnPlayerConnected(BasePlayer player)
{
if (player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot))
{
timer.Once(2, () => OnPlayerConnected(player));
return;
}
if (!IsGod(player.UserIDString)) return;
ModifyMetabolism(player, true);
}
[ChatCommand("god")]
void God(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player.UserIDString, permAllowed))
{
Reply(player, Lang("NotAllowed", player.UserIDString, command));
return;
}
if (args.Length == 0)
{
if (IsGod(player.UserIDString))
{
DisableGodmode(player);
Reply(player, Lang("Disabled", player.UserIDString));
}
else
{
EnableGodmode(player);
Reply(player, Lang("Enabled", player.UserIDString));
}
return;
}
var target = covalence.Players?.FindPlayer(args[0]) ?? null;
if (target == null)
{
Reply(player, Lang("PlayerNotFound", player.UserIDString));
return;
}
else ToggleGodmode(player, target?.Object as BasePlayer);
}
[ChatCommand("gods")]
void Godlist(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player.UserIDString, permAllowed))
{
Reply(player, Lang("NotAllowed", player.UserIDString, command));
return;
}
Reply(player, Lang("GodList", player.UserIDString));
if (gods.Count == 0)
Reply(player, Lang("GodListNone", player.UserIDString));
else
foreach (var god in gods) Reply(player, $"{god.Value.Name} [{god.Value.UserId}]");
}
object CanBeWounded(BasePlayer player) => !canBeHurt && IsGod(player.UserIDString) ? (object)false : null;
object OnEntityTakeDamage(BaseEntity entity, HitInfo info)
{
if (entity == null || info == null) return null;
var player = entity as BasePlayer;
if (player == null) return null;
var attacker = info.Initiator as BasePlayer;
if (!player) return null;
if (!canBeHurt && IsGod(player.UserIDString))
{
NullifyDamage(ref info);
if (informOnAttack) InformPlayers(player, attacker);
return true;
}
if (attacker == null) return null;
if (!canHurtPlayers && IsGod(attacker.UserIDString))
{
NullifyDamage(ref info);
return true;
}
return null;
}
object CanLootPlayer(BasePlayer target, BasePlayer player)
{
if (player == null || target == null) return null;
if (IsGod(target.UserIDString) && !HasPermission(player.UserIDString, permAllowed)) return false;
return null;
}
void DisableGodmode(BasePlayer player)
{
if (player == null) return;
string gui;
if (_guiInfo.TryGetValue(player.userID, out gui))
CuiHelper.DestroyUi(player, gui);
storedData.Gods.RemoveWhere(info => info.GetUserId() == player.userID);
gods.Remove(player.userID);
ModifyMetabolism(player, false);
if (!AnyConnectedGod()) UpdateHooks(false);
}
bool AnyConnectedGod() { return gods?.Any(p => (BasePlayer.activePlayerList?.Any(x => x != null && x.IsConnected && x?.userID == p.Key) ?? false)) ?? false; }
void EnableGodmode(BasePlayer player)
{
var info = new PlayerInfo(player);
storedData.Gods.Add(info);
gods[player.userID] = info;
ModifyMetabolism(player, true);
UpdateHooks(true);
GodGUI(player);
}
static void ModifyMetabolism(BasePlayer player, bool isGod)
{
if (isGod)
{
player.health = 100;
player.metabolism.bleeding.max = 0;
player.metabolism.bleeding.value = 0;
//player.metabolism.calories.min = 500;
//player.metabolism.calories.value = 500;
player.metabolism.dirtyness.max = 0;
player.metabolism.dirtyness.value = 0;
player.metabolism.heartrate.min = 0.5f;
player.metabolism.heartrate.max = 0.5f;
player.metabolism.heartrate.value = 0.5f;
// player.metabolism.hydration.min = 250;
// player.metabolism.hydration.value = 250;
player.metabolism.oxygen.min = 1;
player.metabolism.oxygen.value = 1;
player.metabolism.poison.max = 0;
player.metabolism.poison.value = 0;
player.metabolism.radiation_level.max = 0;
player.metabolism.radiation_level.value = 0;
player.metabolism.radiation_poison.max = 0;
player.metabolism.radiation_poison.value = 0;
player.metabolism.temperature.min = 32;
player.metabolism.temperature.max = 32;
player.metabolism.temperature.value = 32;
player.metabolism.wetness.max = 0;
player.metabolism.wetness.value = 0;
}
else
{
player.metabolism.bleeding.min = 0;
player.metabolism.bleeding.max = 1;
player.metabolism.calories.min = 0;
player.metabolism.calories.max = 500;
player.metabolism.comfort.min = 0;
player.metabolism.comfort.max = 1;
player.metabolism.dirtyness.min = 0;
player.metabolism.dirtyness.max = 100;
player.metabolism.heartrate.min = 0;
player.metabolism.heartrate.max = 1;
player.metabolism.hydration.min = 0;
player.metabolism.hydration.max = 250;
player.metabolism.oxygen.min = 0;
player.metabolism.oxygen.max = 1;
player.metabolism.poison.min = 0;
player.metabolism.poison.max = 100;
player.metabolism.radiation_level.min = 0;
player.metabolism.radiation_level.max = 100;
player.metabolism.radiation_poison.min = 0;
player.metabolism.radiation_poison.max = 500;
player.metabolism.temperature.min = -100;
player.metabolism.temperature.max = 100;
player.metabolism.wetness.min = 0;
player.metabolism.wetness.max = 1;
}
player.metabolism.SendChangesToClient();
}
object OnRunPlayerMetabolism(PlayerMetabolism metabolism, BaseCombatEntity ownerEntity)
{
var player = ownerEntity as BasePlayer;
if (player == null) return null;
if (!IsGod(player.UserIDString)) return null;
if (infiniteRun) player.SetPlayerFlag(BasePlayer.PlayerFlags.NoSprint, false);
return true;
}
void InformPlayers(BasePlayer victim, BasePlayer attacker)
{
if (!victim || !attacker) return;
if (victim == attacker) return;
if (!playerInformHistory.ContainsKey(attacker)) playerInformHistory.Add(attacker, 0);
if (!playerInformHistory.ContainsKey(victim)) playerInformHistory.Add(victim, 0);
if (GetTimestamp() - playerInformHistory[attacker] > 15)
{
Reply(victim, Lang("InformVictim", victim.UserIDString, attacker.displayName));
playerInformHistory[victim] = GetTimestamp();
}
if (GetTimestamp() - playerInformHistory[victim] > 15)
{
Reply(attacker, Lang("InformAttacker", attacker.UserIDString, victim.displayName));
playerInformHistory[victim] = GetTimestamp();
}
}
static void NullifyDamage(ref HitInfo info)
{
info.damageTypes = new DamageTypeList();
info.HitMaterial = 0;
info.PointStart = Vector3.zero;
}
void ToggleGodmode(BasePlayer player, BasePlayer target)
{
if (IsGod(target.UserIDString))
{
DisableGodmode(target);
Reply(player, Lang("DisabledFor", player.UserIDString, target.displayName));
Reply(target, Lang("DisabledBy", target.UserIDString, player.displayName));
}
else
{
EnableGodmode(target);
Reply(player, Lang("EnabledFor", player.UserIDString, target.displayName));
Reply(target, Lang("EnabledBy", target.UserIDString, player.displayName));
}
}
#region GUI Indicator
private readonly Dictionary<ulong, string> _guiInfo = new Dictionary<ulong, string>();
private void GodGUI(BasePlayer basePlayer)
{
if (!basePlayer || !basePlayer.IsConnected)
{
return;
}
string gui;
if (_guiInfo.TryGetValue(basePlayer.userID, out gui))
CuiHelper.DestroyUi(basePlayer, gui);
var elements = new CuiElementContainer();
_guiInfo[basePlayer.userID] = CuiHelper.GetGuid();
elements.Add(new CuiElement
{
Name = _guiInfo[basePlayer.userID],
Components =
{
new CuiRawImageComponent
{
Color = "1 1 1 0.6",
Url = "https://cdn.prismrust.com/Godmode.png"
},
new CuiRectTransformComponent
{
AnchorMin = "0.275 0.017",
AnchorMax = "0.32 0.08"
}
}
});
CuiHelper.AddUi(basePlayer, elements);
}
#endregion GUI Indicator
#region Helpers
T GetConfig<T>(string name, T value) => Config[name] == null ? value : (T)Convert.ChangeType(Config[name], typeof(T));
string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);
void Reply(BasePlayer player, string message, string args = null) => PrintToChat(player, $"{message}", args);
long GetTimestamp() => Convert.ToInt64((DateTime.UtcNow.Subtract(epoch)).TotalSeconds);
bool HasPermission(string id, string perm) => permission.UserHasPermission(id, perm);
bool IsAdmin(string userId) => permission.UserHasGroup(userId, "admin");
PlayerInfo GetPlayerInfo(string userID)
{
if (string.IsNullOrEmpty(userID)) return null;
ulong uID;
PlayerInfo info;
if (ulong.TryParse(userID, out uID) && gods.TryGetValue(uID, out info)) return info;
return null;
}
PlayerInfo GetPlayerInfo(ulong userID)
{
if (userID == 0) return null;
PlayerInfo info;
gods.TryGetValue(userID, out info);
return info;
}
#endregion
}
}