C#:
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("DCProtect", "FireStorm78", "1.0.6")]
[Description("Prevents players from looting other players that have disconnected for a specified time.")]
class DCProtect : RustPlugin
{
#region Initialization
List<string> PlayerList = new List<string>();
void Init()
{
LoadDefaultConfig();
}
#endregion
#region Configuration
int DC_DelayInSeconds;
int Start_DelayInSeconds;
bool PreventLooting;
bool PreventDamage;
protected override void LoadDefaultConfig()
{
Config["DC_DelayInSeconds"] = DC_DelayInSeconds = GetConfig("DC_DelayInSeconds", 300);
Config["Start_DelayInSeconds"] = Start_DelayInSeconds = GetConfig("Start_DelayInSeconds", 300);
Config["PreventLooting"] = PreventLooting = GetConfig("PreventLooting", true);
Config["PreventDamage"] = PreventDamage = GetConfig("PreventDamage", true);
SaveConfig();
}
#endregion
#region Localization
protected override void LoadDefaultMessages()
{
string Usage = "<size=30><color=blue>DC Protect</color></size> v{0}\nby {1}\n\n";
Usage += "NOTE: All commands are meant for testing by a moderator or administrator.\n\n";
Usage += "Usage Syntax:\n";
Usage += "/DCP add - Manually add the player you are looking at to the protection list.\n";
Usage += "/DCP remove - Manually remove the player you are looking at from the protection list.\n";
Usage += "/DCP list - List all current protected players by SteamID.\n";
Usage += "/DCP time - Show the number of seconds since the server has started.\n";
lang.RegisterMessages(new Dictionary<string, string>
{
["NotAllowed"] = "This player has just disconnected.They are protected for '{0}' seconds.This action has been logged.",
["ServerStart"] = "The server just started.All players are protected for '{0}' seconds.This action has been logged.",
["InvalidCommand"] = "[DCP] That is an invalid command.",
["ManualAdd"]= "[DCP] You are looking at player {0}|{1}.Manually adding protection.",
["ManualRemove"] = "[DCP] You are looking at player {0}|{1}.Manually removing protection.",
["ListTitle"] = "[DCP] Current Protected Player List",
["TimerComplete"] = "Timer Complete.Removing Player: {0}|{1}.",
["PlayerDisconnected"] = "Player Disconnected.Adding Player {0}|{1} to protection list.",
["LogViolation_DC_Loot"] = "Player {0}|{1} tried to loot {2}|{3} after they disconnected...tisk tisk.",
["LogViolation_ServerStart_Loot"] = "Player {0}|{1} tried to loot {2}|{3} after the server started...tisk tisk.",
["LogViolation_DC_Damage"] = "Player {0}|{1} tried to damage {2}|{3} after they disconnected...tisk tisk.",
["LogViolation_ServerStart_Damage"] = "Player {0}|{1} tried to damage {2}|{3} after the server started...tisk tisk.",
["Usage"] = Usage
}, this);
}
#endregion
#region Helpers
T GetConfig<T>(string name, T defaultValue) => Config[name] == null ? defaultValue : (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);
private bool IsAdmin(BasePlayer player)
{
if (player == null) return false;
if (player?.net?.connection == null) return true;
return player.net.connection.authLevel > 0;
}
#endregion
[ChatCommand("DCP")]
private void cmdDCP(BasePlayer player, string command, string[] args)
{
if (args.Length > 0)
{
switch (args[0].ToLower())
{
case "add":
cmdDCP_Add(player, command, args.Skip(1).ToArray());
break;
case "remove":
cmdDCP_Remove(player, command, args.Skip(1).ToArray());
break;
case "list":
cmdDCP_List(player, command, args.Skip(1).ToArray());
break;
case "time":
PrintToChat(player, Time.realtimeSinceStartup.ToString());
break;
default:
PrintToChat(player, Lang("InvalidCommand", player.UserIDString));
PrintToChat(player, Lang("Usage", player.UserIDString, this.Version, this.Author));
break;
}
}
else
{
PrintToChat(player, Lang("Usage", player.UserIDString, this.Version, this.Author));
}
}
private void cmdDCP_Add(BasePlayer player, string command, string[] args)
{
if (IsAdmin(player))
{
RaycastHit hit;
if (Physics.Raycast(player.eyes.HeadRay(), out hit, 10f))
{
BaseEntity closestEntity = hit.GetEntity();
if (closestEntity is BasePlayer)
{
BasePlayer target = (BasePlayer) closestEntity;
PrintToChat(player, Lang("ManualAdd", player.UserIDString, target.displayName, target.UserIDString));
PlayerList.Add(target.UserIDString);
timer.Once(DC_DelayInSeconds, () =>
{
PrintWarning(Lang("TimerComplete", null, target.UserIDString, target.displayName));
PlayerList.Remove(target.UserIDString);
});
}
}
}
}
private void cmdDCP_Remove(BasePlayer player, string command, string[] args)
{
if (IsAdmin(player))
{
RaycastHit hit;
if (Physics.Raycast(player.eyes.HeadRay(), out hit, 10f))
{
BaseEntity closestEntity = hit.GetEntity();
if (closestEntity is BasePlayer)
{
BasePlayer target = (BasePlayer)closestEntity;
PrintToChat(player, Lang("ManualRemove", player.UserIDString, target.displayName, target.UserIDString));
PlayerList.Remove(target.UserIDString);
}
}
}
}
private void cmdDCP_List(BasePlayer player, string command, string[] args)
{
if (IsAdmin(player))
{
PrintToChat(player, Lang("ListTitle", player.UserIDString));
foreach (string item in PlayerList)
{
SendReply(player, item);
}
}
}
void OnPlayerDisconnected(BasePlayer player, string reason)
{
PrintWarning(Lang("PlayerDisconnected", null, player.UserIDString, player.displayName));
PlayerList.Add(player.UserIDString);
timer.Once(DC_DelayInSeconds, () =>
{
PrintWarning(Lang("TimerComplete", null, player.UserIDString, player.displayName));
PlayerList.Remove(player.UserIDString);
});
}
bool CanLootPlayer(BasePlayer target, BasePlayer looter)
{
if (PreventLooting && target.userID != looter.userID)
{
if (Time.realtimeSinceStartup < Start_DelayInSeconds)
{
PrintWarning(Lang("LogViolation_ServerStart_Loot", null, looter.UserIDString, looter.displayName, target.UserIDString, target.displayName));
PrintToChat(looter, Lang("ServerStart", looter.UserIDString, Start_DelayInSeconds));
return false;
}
else if (PlayerList.Contains(target.UserIDString))
{
PrintWarning(Lang("LogViolation_DC_Loot", null, looter.UserIDString, looter.displayName, target.UserIDString, target.displayName));
PrintToChat(looter, Lang("NotAllowed", looter.UserIDString, DC_DelayInSeconds));
return false;
}
}
return true;
}
object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
{
if (PreventDamage && entity is BasePlayer && (entity as BasePlayer).IsSleeping())
{
if (info.Initiator == null) return null;
if (info.Initiator is BasePlayer)
{
BasePlayer attacker = info.Initiator as BasePlayer;
BasePlayer target = entity as BasePlayer;
if (Time.realtimeSinceStartup < Start_DelayInSeconds)
{
PrintWarning(Lang("LogViolation_ServerStart_Damage", null, attacker.UserIDString, attacker.displayName, target.UserIDString, target.displayName));
PrintToChat(attacker, Lang("ServerStart", attacker.UserIDString, Start_DelayInSeconds));
return false;
}
else if (PlayerList.Contains(target.UserIDString))
{
PrintWarning(Lang("LogViolation_DC_Damage", null, attacker.UserIDString, attacker.displayName, target.UserIDString, target.displayName));
PrintToChat(attacker, Lang("NotAllowed", attacker.UserIDString, DC_DelayInSeconds));
return false;
}
}
else
{
BaseEntity attacker = info.Initiator;
BasePlayer target = entity as BasePlayer;
if (Time.realtimeSinceStartup < Start_DelayInSeconds)
{
PrintWarning(Lang("LogViolation_ServerStart_Damage", null, "0", attacker.name, target.UserIDString, target.displayName));
return false;
}
else if (PlayerList.Contains(target.UserIDString))
{
PrintWarning(Lang("LogViolation_DC_Damage", null, "0", attacker.name, target.UserIDString, target.displayName));
return false;
}
}
}
return null;
}
}
}