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