diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index a7f069c3..d3ec277a 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -231,6 +231,7 @@ namespace TShockAPI add(Permissions.whisper, Reply, "reply", "r"); add(Permissions.annoy, Annoy, "annoy"); add(Permissions.kill, Kill, "kill"); + add(Permissions.godmode, ToggleGodMode, "godmode"); add(Permissions.butcher, Butcher, "butcher"); add(Permissions.item, Give, "give", "g"); add(Permissions.clearitems, ClearItems, "clear", "clearitems"); @@ -3924,6 +3925,51 @@ namespace TShockAPI args.Player.SendSuccessMessage("Tried to grow a " + name + "."); } + private static void ToggleGodMode(CommandArgs args) + { + TSPlayer playerToGod; + if (args.Parameters.Count > 0) + { + string plStr = String.Join(" ", args.Parameters); + var players = TShock.Utils.FindPlayer(plStr); + if (players.Count == 0) + { + args.Player.SendErrorMessage("Invalid player!"); + return; + } + else if (players.Count > 1) + { + TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); + return; + } + else + { + playerToGod = players[0]; + } + } + else if (!args.Player.RealPlayer) + { + args.Player.SendErrorMessage("You cant god mode a non player!"); + return; + } + else + { + playerToGod = args.Player; + } + + playerToGod.GodMode = !playerToGod.GodMode; + + if (playerToGod == args.Player) + { + args.Player.SendSuccessMessage(string.Format("You are {0} in god mode.", args.Player.GodMode ? "now" : "no longer")); + } + else + { + args.Player.SendSuccessMessage(string.Format("{0} is {1} in god mode.", playerToGod.Name, playerToGod.GodMode ? "now" : "no longer")); + playerToGod.SendSuccessMessage(string.Format("You are {0} in god mode.", playerToGod.GodMode ? "now" : "no longer")); + } + } + #endregion Cheat Comamnds } } diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs index 396f376e..971fdc20 100644 --- a/TShockAPI/ConfigFile.cs +++ b/TShockAPI/ConfigFile.cs @@ -276,6 +276,7 @@ namespace TShockAPI [Description("The number of reserved slots past your max server slot that can be joined by reserved players")] public int ReservedSlots = 20; [Description("The number of reserved slots past your max server slot that can be joined by reserved players")] public bool LogRest = false; + /// /// Reads a configuration file from a given path /// diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 18b58064..a8a2d1db 100755 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -1322,7 +1322,7 @@ namespace TShockAPI args.Player.PlayerData.maxHealth = max; } - if (args.Player.Group.HasPermission(Permissions.godmode) && (cur < max)) + if (args.Player.GodMode && (cur < max)) { args.Player.Heal(args.TPlayer.statLifeMax); } @@ -2947,6 +2947,11 @@ namespace TShockAPI if (TShock.Players[id] == null) return true; + if (TShock.Players[id].GodMode) + { + TShock.Players[id].Heal(args.TPlayer.statLifeMax); + } + if (dmg > TShock.Config.MaxDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap) && id != args.Player.Index) { args.Player.Disable(String.Format("Player damage exceeded {0}.", TShock.Config.MaxDamage)); @@ -2983,11 +2988,6 @@ namespace TShockAPI return true; } - if (args.Player.Group.HasPermission(Permissions.godmode)) - { - args.Player.Heal(args.TPlayer.statLifeMax); - } - return false; } diff --git a/TShockAPI/Group.cs b/TShockAPI/Group.cs index 08a2aa9b..7aa25b6f 100644 --- a/TShockAPI/Group.cs +++ b/TShockAPI/Group.cs @@ -175,24 +175,30 @@ namespace TShockAPI /// The permission to check. /// Returns true if the user has that permission. public virtual bool HasPermission(string permission) - { - if (String.IsNullOrEmpty(permission) || RealHasPermission(permission)) + { + bool negated = false; + if (String.IsNullOrEmpty(permission) || (RealHasPermission(permission, ref negated) && !negated)) { return true; } + + if (negated) + return false; + string[] nodes = permission.Split('.'); for (int i = nodes.Length - 1; i >= 0; i--) { nodes[i] = "*"; - if (RealHasPermission(String.Join(".", nodes, 0, i + 1))) + if (RealHasPermission(String.Join(".", nodes, 0, i + 1), ref negated)) { - return true; + return !negated; } } return false; } - private bool RealHasPermission(string permission) + private bool RealHasPermission(string permission, ref bool negated) { + negated = false; if (string.IsNullOrEmpty(permission)) return true; @@ -200,9 +206,12 @@ namespace TShockAPI var traversed = new List(); while (cur != null) { - if (cur.negatedpermissions.Contains(permission)) - return false; - if (cur.permissions.Contains(permission)) + if (cur.negatedpermissions.Contains(permission)) + { + negated = true; + return false; + } + if (cur.permissions.Contains(permission)) return true; if (traversed.Contains(cur)) { diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs index 0f55cd5d..8d55a56e 100644 --- a/TShockAPI/Permissions.cs +++ b/TShockAPI/Permissions.cs @@ -286,6 +286,9 @@ namespace TShockAPI [Description("Player recovers health as damage is taken. Can be one shotted.")] public static readonly string godmode = "tshock.godmode"; + [Description("Player can chat")] + public static readonly string canchat = "tshock.canchat"; + /// /// Lists all commands associated with a given permission /// diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 1a1b2627..cc444d51 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -282,6 +282,11 @@ namespace TShockAPI /// public bool LoginHarassed = false; + /// + /// Player cant die, unless onehit + /// + public bool GodMode = false; + /// /// Whether the player is a real, human, player on the server. /// diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 5e9c2aa7..b07d8960 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -921,21 +921,31 @@ namespace TShockAPI Log.Error(ex.ToString()); } } - else if (!tsplr.mute && !TShock.Config.EnableChatAboveHeads) + else { - Utils.Broadcast( - String.Format(Config.ChatFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix, args.Text), - tsplr.Group.R, tsplr.Group.G, tsplr.Group.B); - args.Handled = true; - } else if (!tsplr.mute && TShock.Config.EnableChatAboveHeads) - { - Utils.Broadcast(args.Who, String.Format(Config.ChatAboveHeadsFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix, args.Text), tsplr.Group.R, tsplr.Group.G, tsplr.Group.B); - args.Handled = true; - } - else if (tsplr.mute) - { - tsplr.SendErrorMessage("You are muted!"); - args.Handled = true; + if (!tsplr.Group.HasPermission(Permissions.canchat)) + { + args.Handled = true; + } + else if (tsplr.mute) + { + tsplr.SendErrorMessage("You are muted!"); + args.Handled = true; + } + else if (!TShock.Config.EnableChatAboveHeads) + { + Utils.Broadcast( + String.Format(Config.ChatFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix, args.Text), + tsplr.Group.R, tsplr.Group.G, tsplr.Group.B); + args.Handled = true; + } + else + { + Utils.Broadcast(args.Who, + String.Format(Config.ChatAboveHeadsFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix, + args.Text), tsplr.Group.R, tsplr.Group.G, tsplr.Group.B); + args.Handled = true; + } } } diff --git a/TerrariaServerBins/TerrariaServer.exe b/TerrariaServerBins/TerrariaServer.exe index 69db2363..6dfceb15 100644 Binary files a/TerrariaServerBins/TerrariaServer.exe and b/TerrariaServerBins/TerrariaServer.exe differ