Merge branch 'general-devel' of github.com:NyxStudios/TShock into general-devel
This commit is contained in:
commit
8ce3e4933e
17 changed files with 1058 additions and 799 deletions
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
This is the rolling changelog for TShock for Terraria. Use past tense when adding new entries; sign your name off when you add or change something. This should primarily be things like user changes, not necessarily codebase changes unless it's really relevant or large.
|
||||
|
||||
## Upcoming Changes
|
||||
|
||||
* Fixed character styles/gender not being saved properly on first login while SSC is on (@WhiteXZ)
|
||||
* Added a PlayerPermission hook fired whenever a permission check involving said player occurs (when the new TSPlayer.HasPermission method is called) (@Enerdy)
|
||||
|
||||
## TShock 4.3.12
|
||||
|
||||
* Fixed issues with TSPlayer.SetTeam not working (@WhiteXZ)
|
||||
|
|
@ -16,7 +21,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
|
|||
|
||||
## TShock 4.3.11
|
||||
|
||||
* This release is actuall 4.3.10, but was ticked extra due to a version issue on gen-dev prior to master push.
|
||||
* This release is actually 4.3.10, but was ticked extra due to a version issue on gen-dev prior to master push.
|
||||
|
||||
## TShock 4.3.10
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
foreach (var Permission in Permissions)
|
||||
{
|
||||
if (ply.Group.HasPermission(Permission))
|
||||
if (ply.HasPermission(Permission))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -795,7 +795,7 @@ namespace TShockAPI
|
|||
|
||||
if (Main.ServerSideCharacter)
|
||||
{
|
||||
if (group.HasPermission(Permissions.bypassssc))
|
||||
if (args.Player.HasPermission(Permissions.bypassssc))
|
||||
{
|
||||
args.Player.IgnoreActionsForClearingTrashCan = false;
|
||||
}
|
||||
|
|
@ -803,10 +803,10 @@ namespace TShockAPI
|
|||
}
|
||||
args.Player.LoginFailsBySsi = false;
|
||||
|
||||
if (group.HasPermission(Permissions.ignorestackhackdetection))
|
||||
if (args.Player.HasPermission(Permissions.ignorestackhackdetection))
|
||||
args.Player.IgnoreActionsForCheating = "none";
|
||||
|
||||
if (group.HasPermission(Permissions.usebanneditem))
|
||||
if (args.Player.HasPermission(Permissions.usebanneditem))
|
||||
args.Player.IgnoreActionsForDisabledArmor = "none";
|
||||
|
||||
args.Player.Group = group;
|
||||
|
|
@ -1381,7 +1381,7 @@ namespace TShockAPI
|
|||
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
|
||||
else
|
||||
{
|
||||
if (args.Player.RealPlayer && players[0].Group.HasPermission(Permissions.immunetoban))
|
||||
if (args.Player.RealPlayer && players[0].HasPermission(Permissions.immunetoban))
|
||||
{
|
||||
args.Player.SendErrorMessage("You can't ban {0}!", players[0].Name);
|
||||
return;
|
||||
|
|
@ -2237,7 +2237,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (args.Parameters.Count != 1 && args.Parameters.Count != 2)
|
||||
{
|
||||
if (args.Player.Group.HasPermission(Permissions.tpothers))
|
||||
if (args.Player.HasPermission(Permissions.tpothers))
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}tp <player> [player 2]", Specifier);
|
||||
else
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}tp <player>", Specifier);
|
||||
|
|
@ -2254,7 +2254,7 @@ namespace TShockAPI
|
|||
else
|
||||
{
|
||||
var target = players[0];
|
||||
if (!target.TPAllow && !args.Player.Group.HasPermission(Permissions.tpoverride))
|
||||
if (!target.TPAllow && !args.Player.HasPermission(Permissions.tpoverride))
|
||||
{
|
||||
args.Player.SendErrorMessage("{0} has disabled players from teleporting.", target.Name);
|
||||
return;
|
||||
|
|
@ -2262,14 +2262,14 @@ namespace TShockAPI
|
|||
if (args.Player.Teleport(target.TPlayer.position.X, target.TPlayer.position.Y))
|
||||
{
|
||||
args.Player.SendSuccessMessage("Teleported to {0}.", target.Name);
|
||||
if (!args.Player.Group.HasPermission(Permissions.tpsilent))
|
||||
if (!args.Player.HasPermission(Permissions.tpsilent))
|
||||
target.SendInfoMessage("{0} teleported to you.", args.Player.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!args.Player.Group.HasPermission(Permissions.tpothers))
|
||||
if (!args.Player.HasPermission(Permissions.tpothers))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have access to this command.");
|
||||
return;
|
||||
|
|
@ -2286,7 +2286,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (args.Parameters[0] == "*")
|
||||
{
|
||||
if (!args.Player.Group.HasPermission(Permissions.tpallothers))
|
||||
if (!args.Player.HasPermission(Permissions.tpallothers))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have access to this command.");
|
||||
return;
|
||||
|
|
@ -2295,22 +2295,22 @@ namespace TShockAPI
|
|||
var target = players2[0];
|
||||
foreach (var source in TShock.Players.Where(p => p != null && p != args.Player))
|
||||
{
|
||||
if (!target.TPAllow && !args.Player.Group.HasPermission(Permissions.tpoverride))
|
||||
if (!target.TPAllow && !args.Player.HasPermission(Permissions.tpoverride))
|
||||
continue;
|
||||
if (source.Teleport(target.TPlayer.position.X, target.TPlayer.position.Y))
|
||||
{
|
||||
if (args.Player != source)
|
||||
{
|
||||
if (args.Player.Group.HasPermission(Permissions.tpsilent))
|
||||
if (args.Player.HasPermission(Permissions.tpsilent))
|
||||
source.SendSuccessMessage("You were teleported to {0}.", target.Name);
|
||||
else
|
||||
source.SendSuccessMessage("{0} teleported you to {1}.", args.Player.Name, target.Name);
|
||||
}
|
||||
if (args.Player != target)
|
||||
{
|
||||
if (args.Player.Group.HasPermission(Permissions.tpsilent))
|
||||
if (args.Player.HasPermission(Permissions.tpsilent))
|
||||
target.SendInfoMessage("{0} was teleported to you.", source.Name);
|
||||
if (!args.Player.Group.HasPermission(Permissions.tpsilent))
|
||||
if (!args.Player.HasPermission(Permissions.tpsilent))
|
||||
target.SendInfoMessage("{0} teleported {1} to you.", args.Player.Name, source.Name);
|
||||
}
|
||||
}
|
||||
|
|
@ -2325,13 +2325,13 @@ namespace TShockAPI
|
|||
else
|
||||
{
|
||||
var source = players1[0];
|
||||
if (!source.TPAllow && !args.Player.Group.HasPermission(Permissions.tpoverride))
|
||||
if (!source.TPAllow && !args.Player.HasPermission(Permissions.tpoverride))
|
||||
{
|
||||
args.Player.SendErrorMessage("{0} has disabled players from teleporting.", source.Name);
|
||||
return;
|
||||
}
|
||||
var target = players2[0];
|
||||
if (!target.TPAllow && !args.Player.Group.HasPermission(Permissions.tpoverride))
|
||||
if (!target.TPAllow && !args.Player.HasPermission(Permissions.tpoverride))
|
||||
{
|
||||
args.Player.SendErrorMessage("{0} has disabled players from teleporting.", target.Name);
|
||||
return;
|
||||
|
|
@ -2341,16 +2341,16 @@ namespace TShockAPI
|
|||
{
|
||||
if (args.Player != source)
|
||||
{
|
||||
if (args.Player.Group.HasPermission(Permissions.tpsilent))
|
||||
if (args.Player.HasPermission(Permissions.tpsilent))
|
||||
source.SendSuccessMessage("You were teleported to {0}.", target.Name);
|
||||
else
|
||||
source.SendSuccessMessage("{0} teleported you to {1}.", args.Player.Name, target.Name);
|
||||
}
|
||||
if (args.Player != target)
|
||||
{
|
||||
if (args.Player.Group.HasPermission(Permissions.tpsilent))
|
||||
if (args.Player.HasPermission(Permissions.tpsilent))
|
||||
target.SendInfoMessage("{0} was teleported to you.", source.Name);
|
||||
if (!args.Player.Group.HasPermission(Permissions.tpsilent))
|
||||
if (!args.Player.HasPermission(Permissions.tpsilent))
|
||||
target.SendInfoMessage("{0} teleported {1} to you.", args.Player.Name, source.Name);
|
||||
}
|
||||
}
|
||||
|
|
@ -2362,7 +2362,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (args.Parameters.Count < 1)
|
||||
{
|
||||
if (args.Player.Group.HasPermission(Permissions.tpallothers))
|
||||
if (args.Player.HasPermission(Permissions.tpallothers))
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}tphere <player|*>", Specifier);
|
||||
else
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}tphere <player>", Specifier);
|
||||
|
|
@ -2375,7 +2375,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (playerName == "*")
|
||||
{
|
||||
if (!args.Player.Group.HasPermission(Permissions.tpallothers))
|
||||
if (!args.Player.HasPermission(Permissions.tpallothers))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to use this command.");
|
||||
return;
|
||||
|
|
@ -2500,7 +2500,7 @@ namespace TShockAPI
|
|||
|
||||
private static void Warp(CommandArgs args)
|
||||
{
|
||||
bool hasManageWarpPermission = args.Player.Group.HasPermission(Permissions.managewarp);
|
||||
bool hasManageWarpPermission = args.Player.HasPermission(Permissions.managewarp);
|
||||
if (args.Parameters.Count < 1)
|
||||
{
|
||||
if (hasManageWarpPermission)
|
||||
|
|
@ -2603,7 +2603,7 @@ namespace TShockAPI
|
|||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}warp hide [name] <true/false>", Specifier);
|
||||
#endregion
|
||||
}
|
||||
else if (args.Parameters[0].ToLower() == "send" && args.Player.Group.HasPermission(Permissions.tpothers))
|
||||
else if (args.Parameters[0].ToLower() == "send" && args.Player.HasPermission(Permissions.tpothers))
|
||||
{
|
||||
#region Warp send
|
||||
if (args.Parameters.Count < 3)
|
||||
|
|
@ -3852,7 +3852,7 @@ namespace TShockAPI
|
|||
{
|
||||
int.TryParse(args.Parameters[1], out damage);
|
||||
}
|
||||
if (!args.Player.Group.HasPermission(Permissions.kill))
|
||||
if (!args.Player.HasPermission(Permissions.kill))
|
||||
{
|
||||
damage = TShock.Utils.Clamp(damage, 15, 0);
|
||||
}
|
||||
|
|
@ -4349,7 +4349,7 @@ namespace TShockAPI
|
|||
}
|
||||
case "tp":
|
||||
{
|
||||
if (!args.Player.Group.HasPermission(Permissions.tp))
|
||||
if (!args.Player.HasPermission(Permissions.tp))
|
||||
{
|
||||
args.Player.SendErrorMessage("You don't have the necessary permission to do that.");
|
||||
break;
|
||||
|
|
@ -4397,7 +4397,7 @@ namespace TShockAPI
|
|||
"protect <name> <true/false> - Sets whether the tiles inside the region are protected or not.",
|
||||
"z <name> <#> - Sets the z-order of the region.",
|
||||
};
|
||||
if (args.Player.Group.HasPermission(Permissions.tp))
|
||||
if (args.Player.HasPermission(Permissions.tp))
|
||||
lines.Add("tp <region> - Teleports you to the given region's center.");
|
||||
|
||||
PaginationTools.SendPage(
|
||||
|
|
@ -4526,7 +4526,7 @@ namespace TShockAPI
|
|||
args.Player.SendErrorMessage("Invalid usage, proper usage: {0}who [-i] [pagenumber]", Specifier);
|
||||
return;
|
||||
}
|
||||
if (displayIdsRequested && !args.Player.Group.HasPermission(Permissions.seeids))
|
||||
if (displayIdsRequested && !args.Player.HasPermission(Permissions.seeids))
|
||||
{
|
||||
args.Player.SendErrorMessage("You don't have the required permission to list player ids.");
|
||||
return;
|
||||
|
|
@ -4658,7 +4658,7 @@ namespace TShockAPI
|
|||
{
|
||||
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
|
||||
}
|
||||
else if (players[0].Group.HasPermission(Permissions.mute))
|
||||
else if (players[0].HasPermission(Permissions.mute))
|
||||
{
|
||||
args.Player.SendErrorMessage("You cannot mute this player.");
|
||||
}
|
||||
|
|
@ -5497,7 +5497,7 @@ namespace TShockAPI
|
|||
TSPlayer playerToGod;
|
||||
if (args.Parameters.Count > 0)
|
||||
{
|
||||
if (!args.Player.Group.HasPermission(Permissions.godmodeother))
|
||||
if (!args.Player.HasPermission(Permissions.godmodeother))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to god mode another player!");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ namespace TShockAPI.DB
|
|||
playerData.extraSlot = reader.Get<int>("extraSlot");
|
||||
playerData.spawnX = reader.Get<int>("spawnX");
|
||||
playerData.spawnY = reader.Get<int>("spawnY");
|
||||
playerData.skinVariant = reader.Get<int>("skinVariant");
|
||||
playerData.skinVariant = reader.Get<int?>("skinVariant");
|
||||
playerData.hair = reader.Get<int?>("hair");
|
||||
playerData.hairDye = (byte)reader.Get<int>("hairDye");
|
||||
playerData.hairColor = TShock.Utils.DecodeColor(reader.Get<int?>("hairColor"));
|
||||
|
|
@ -162,13 +162,13 @@ namespace TShockAPI.DB
|
|||
|
||||
if (!player.IsLoggedIn)
|
||||
return false;
|
||||
|
||||
if ((player.tempGroup != null && player.tempGroup.HasPermission(Permissions.bypassssc)) || player.Group.HasPermission(Permissions.bypassssc))
|
||||
{
|
||||
TShock.Log.ConsoleInfo("Skipping SSC Backup for " + player.User.Name); // Debug code
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (player.HasPermission(Permissions.bypassssc))
|
||||
{
|
||||
TShock.Log.ConsoleInfo("Skipping SSC Backup for " + player.User.Name); // Debug code
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!GetPlayerData(player, player.User.ID).exists)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -192,32 +192,32 @@ namespace TShockAPI.DB
|
|||
return Name == other.Name;
|
||||
}
|
||||
|
||||
public bool HasPermissionToUseItem(TSPlayer ply)
|
||||
{
|
||||
if (ply == null)
|
||||
return false;
|
||||
public bool HasPermissionToUseItem(TSPlayer ply)
|
||||
{
|
||||
if (ply == null)
|
||||
return false;
|
||||
|
||||
if (ply.Group.HasPermission(Permissions.usebanneditem))
|
||||
return true;
|
||||
if (ply.HasPermission(Permissions.usebanneditem))
|
||||
return true;
|
||||
|
||||
var cur = ply.Group;
|
||||
var traversed = new List<Group>();
|
||||
while (cur != null)
|
||||
{
|
||||
if (AllowedGroups.Contains(cur.Name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (traversed.Contains(cur))
|
||||
{
|
||||
throw new InvalidOperationException("Infinite group parenting ({0})".SFormat(cur.Name));
|
||||
}
|
||||
traversed.Add(cur);
|
||||
cur = cur.Parent;
|
||||
}
|
||||
return false;
|
||||
// could add in the other permissions in this class instead of a giant if switch.
|
||||
}
|
||||
var cur = ply.Group;
|
||||
var traversed = new List<Group>();
|
||||
while (cur != null)
|
||||
{
|
||||
if (AllowedGroups.Contains(cur.Name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (traversed.Contains(cur))
|
||||
{
|
||||
throw new InvalidOperationException("Infinite group parenting ({0})".SFormat(cur.Name));
|
||||
}
|
||||
traversed.Add(cur);
|
||||
cur = cur.Parent;
|
||||
}
|
||||
return false;
|
||||
// could add in the other permissions in this class instead of a giant if switch.
|
||||
}
|
||||
|
||||
public void SetAllowedGroups(String groups)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ namespace TShockAPI.DB
|
|||
if (ply == null)
|
||||
return false;
|
||||
|
||||
if (ply.Group.HasPermission(Permissions.canusebannedprojectiles))
|
||||
if (ply.HasPermission(Permissions.canusebannedprojectiles))
|
||||
return true;
|
||||
|
||||
var cur = ply.Group;
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ namespace TShockAPI.DB
|
|||
|
||||
public bool CanBuild(int x, int y, TSPlayer ply)
|
||||
{
|
||||
if (!ply.Group.HasPermission(Permissions.canbuild))
|
||||
if (!ply.HasPermission(Permissions.canbuild))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ namespace TShockAPI.DB
|
|||
if (ply == null)
|
||||
return false;
|
||||
|
||||
if (ply.Group.HasPermission(Permissions.canusebannedtiles))
|
||||
if (ply.HasPermission(Permissions.canusebannedtiles))
|
||||
return true;
|
||||
|
||||
var cur = ply.Group;
|
||||
|
|
|
|||
|
|
@ -1305,7 +1305,7 @@ namespace TShockAPI
|
|||
args.Player.PlayerData.StoreSlot(slot, type, prefix, stack);
|
||||
}
|
||||
else if (Main.ServerSideCharacter && TShock.Config.DisableLoginBeforeJoin && !bypassTrashCanCheck &&
|
||||
args.Player.HasSentInventory && !args.Player.Group.HasPermission(Permissions.bypassssc))
|
||||
args.Player.HasSentInventory && !args.Player.HasPermission(Permissions.bypassssc))
|
||||
{
|
||||
// The player might have moved an item to their trash can before they performed a single login attempt yet.
|
||||
args.Player.IgnoreActionsForClearingTrashCan = true;
|
||||
|
|
@ -1329,7 +1329,7 @@ namespace TShockAPI
|
|||
if (OnPlayerHP(plr, cur, max) || cur <= 0 || max <= 0 || args.Player.IgnoreSSCPackets)
|
||||
return true;
|
||||
|
||||
if (max > TShock.Config.MaxHP && !args.Player.Group.HasPermission(Permissions.ignorehp))
|
||||
if (max > TShock.Config.MaxHP && !args.Player.HasPermission(Permissions.ignorehp))
|
||||
{
|
||||
args.Player.Disable("Maximum HP beyond limit", DisableFlags.WriteToLogAndConsole);
|
||||
return true;
|
||||
|
|
@ -1358,7 +1358,7 @@ namespace TShockAPI
|
|||
if (OnPlayerMana(plr, cur, max) || cur < 0 || max < 0 || args.Player.IgnoreSSCPackets)
|
||||
return true;
|
||||
|
||||
if (max > TShock.Config.MaxMP && !args.Player.Group.HasPermission(Permissions.ignoremp))
|
||||
if (max > TShock.Config.MaxMP && !args.Player.HasPermission(Permissions.ignoremp))
|
||||
{
|
||||
args.Player.Disable("Maximum MP beyond limit", DisableFlags.WriteToLogAndConsole);
|
||||
return true;
|
||||
|
|
@ -1476,17 +1476,17 @@ namespace TShockAPI
|
|||
|
||||
if (Main.ServerSideCharacter)
|
||||
{
|
||||
if (!group.HasPermission(Permissions.bypassssc))
|
||||
if (!args.Player.HasPermission(Permissions.bypassssc))
|
||||
{
|
||||
args.Player.PlayerData.RestoreCharacter(args.Player);
|
||||
}
|
||||
}
|
||||
args.Player.LoginFailsBySsi = false;
|
||||
|
||||
if (group.HasPermission(Permissions.ignorestackhackdetection))
|
||||
if (args.Player.HasPermission(Permissions.ignorestackhackdetection))
|
||||
args.Player.IgnoreActionsForCheating = "none";
|
||||
|
||||
if (group.HasPermission(Permissions.usebanneditem))
|
||||
if (args.Player.HasPermission(Permissions.usebanneditem))
|
||||
args.Player.IgnoreActionsForDisabledArmor = "none";
|
||||
|
||||
args.Player.Group = group;
|
||||
|
|
@ -1551,7 +1551,7 @@ namespace TShockAPI
|
|||
|
||||
if (Main.ServerSideCharacter)
|
||||
{
|
||||
if (group.HasPermission(Permissions.bypassssc))
|
||||
if (args.Player.HasPermission(Permissions.bypassssc))
|
||||
{
|
||||
args.Player.IgnoreActionsForClearingTrashCan = false;
|
||||
}
|
||||
|
|
@ -1559,10 +1559,10 @@ namespace TShockAPI
|
|||
}
|
||||
args.Player.LoginFailsBySsi = false;
|
||||
|
||||
if (group.HasPermission(Permissions.ignorestackhackdetection))
|
||||
if (args.Player.HasPermission(Permissions.ignorestackhackdetection))
|
||||
args.Player.IgnoreActionsForCheating = "none";
|
||||
|
||||
if (group.HasPermission(Permissions.usebanneditem))
|
||||
if (args.Player.HasPermission(Permissions.usebanneditem))
|
||||
args.Player.IgnoreActionsForDisabledArmor = "none";
|
||||
|
||||
args.Player.Group = group;
|
||||
|
|
@ -1614,13 +1614,13 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!args.Player.Group.HasPermission(Permissions.ignorestackhackdetection))
|
||||
if (!args.Player.HasPermission(Permissions.ignorestackhackdetection))
|
||||
{
|
||||
TShock.HackedInventory(args.Player);
|
||||
}
|
||||
|
||||
if (TShock.Utils.ActivePlayers() + 1 > TShock.Config.MaxSlots &&
|
||||
!args.Player.Group.HasPermission(Permissions.reservedslot))
|
||||
!args.Player.HasPermission(Permissions.reservedslot))
|
||||
{
|
||||
TShock.Utils.ForceKick(args.Player, TShock.Config.ServerFullReason, true);
|
||||
return true;
|
||||
|
|
@ -1681,7 +1681,7 @@ namespace TShockAPI
|
|||
isTrapdoor = true;
|
||||
}
|
||||
|
||||
if (args.Player.Group.HasPermission(Permissions.allowclientsideworldedit) && !isTrapdoor)
|
||||
if (args.Player.HasPermission(Permissions.allowclientsideworldedit) && !isTrapdoor)
|
||||
return false;
|
||||
|
||||
if (OnSendTileSquare(size, tileX, tileY))
|
||||
|
|
@ -2133,7 +2133,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if ((action == EditAction.PlaceTile || action == EditAction.PlaceWall) && !args.Player.Group.HasPermission(Permissions.ignoreplacetiledetection))
|
||||
if ((action == EditAction.PlaceTile || action == EditAction.PlaceWall) && !args.Player.HasPermission(Permissions.ignoreplacetiledetection))
|
||||
{
|
||||
args.Player.TilePlaceThreshold++;
|
||||
var coords = new Vector2(tileX, tileY);
|
||||
|
|
@ -2142,7 +2142,7 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
if ((action == EditAction.KillTile || action == EditAction.KillTileNoItem || action == EditAction.KillWall) && Main.tileSolid[Main.tile[tileX, tileY].type] &&
|
||||
!args.Player.Group.HasPermission(Permissions.ignorekilltiledetection))
|
||||
!args.Player.HasPermission(Permissions.ignorekilltiledetection))
|
||||
{
|
||||
args.Player.TileKillThreshold++;
|
||||
var coords = new Vector2(tileX, tileY);
|
||||
|
|
@ -2235,7 +2235,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!args.Player.Group.HasPermission(Permissions.ignoreplacetiledetection))
|
||||
if (!args.Player.HasPermission(Permissions.ignoreplacetiledetection))
|
||||
{
|
||||
args.Player.TilePlaceThreshold++;
|
||||
var coords = new Vector2(x, y);
|
||||
|
|
@ -2437,7 +2437,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!args.Player.Group.HasPermission(Permissions.ignorenoclipdetection) &&
|
||||
if (!args.Player.HasPermission(Permissions.ignorenoclipdetection) &&
|
||||
TSCheckNoclip(pos, args.TPlayer.width, args.TPlayer.height) && !TShock.Config.IgnoreNoClip
|
||||
&& !args.TPlayer.tongued)
|
||||
{
|
||||
|
|
@ -2617,7 +2617,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (dmg > TShock.Config.MaxProjDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap))
|
||||
if (dmg > TShock.Config.MaxProjDamage && !args.Player.HasPermission(Permissions.ignoredamagecap))
|
||||
{
|
||||
args.Player.Disable(String.Format("Projectile damage is higher than {0}.", TShock.Config.MaxProjDamage), DisableFlags.WriteToLogAndConsole);
|
||||
args.Player.RemoveProjectile(ident, owner);
|
||||
|
|
@ -2631,7 +2631,7 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
bool hasPermission = !TShock.CheckProjectilePermission(args.Player, index, type);
|
||||
if (!TShock.Config.IgnoreProjUpdate && !hasPermission && !args.Player.Group.HasPermission(Permissions.ignoreprojectiledetection))
|
||||
if (!TShock.Config.IgnoreProjUpdate && !hasPermission && !args.Player.HasPermission(Permissions.ignoreprojectiledetection))
|
||||
{
|
||||
if (type == ProjectileID.BlowupSmokeMoonlord
|
||||
|| type == ProjectileID.PhantasmalEye
|
||||
|
|
@ -2668,7 +2668,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!args.Player.Group.HasPermission(Permissions.ignoreprojectiledetection))
|
||||
if (!args.Player.HasPermission(Permissions.ignoreprojectiledetection))
|
||||
{
|
||||
if (type == ProjectileID.CrystalShard && TShock.Config.ProjIgnoreShrapnel) // Ignore crystal shards
|
||||
{
|
||||
|
|
@ -2831,7 +2831,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!args.Player.Group.HasPermission(Permissions.ignoreliquidsetdetection))
|
||||
if (!args.Player.HasPermission(Permissions.ignoreliquidsetdetection))
|
||||
{
|
||||
args.Player.TileLiquidThreshold++;
|
||||
}
|
||||
|
|
@ -3149,7 +3149,7 @@ namespace TShockAPI
|
|||
if (OnUpdateNPCHome(id, x, y, homeless))
|
||||
return true;
|
||||
|
||||
if (!args.Player.Group.HasPermission(Permissions.movenpc))
|
||||
if (!args.Player.HasPermission(Permissions.movenpc))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to relocate NPCs.");
|
||||
args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY,
|
||||
|
|
@ -3281,7 +3281,7 @@ namespace TShockAPI
|
|||
|
||||
Item item = new Item();
|
||||
item.netDefaults(type);
|
||||
if ((stacks > item.maxStack || stacks <= 0) || (TShock.Itembans.ItemIsBanned(item.name, args.Player) && !args.Player.Group.HasPermission(Permissions.allowdroppingbanneditems)))
|
||||
if ((stacks > item.maxStack || stacks <= 0) || (TShock.Itembans.ItemIsBanned(item.name, args.Player) && !args.Player.HasPermission(Permissions.allowdroppingbanneditems)))
|
||||
{
|
||||
args.Player.SendData(PacketTypes.ItemDrop, "", id);
|
||||
return true;
|
||||
|
|
@ -3338,7 +3338,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (dmg > TShock.Config.MaxDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap) && id != args.Player.Index)
|
||||
if (dmg > TShock.Config.MaxDamage && !args.Player.HasPermission(Permissions.ignoredamagecap) && id != args.Player.Index)
|
||||
{
|
||||
if (TShock.Config.KickOnDamageThresholdBroken)
|
||||
{
|
||||
|
|
@ -3404,7 +3404,7 @@ namespace TShockAPI
|
|||
if (Main.npc[id] == null)
|
||||
return true;
|
||||
|
||||
if (dmg > TShock.Config.MaxDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap))
|
||||
if (dmg > TShock.Config.MaxDamage && !args.Player.HasPermission(Permissions.ignoredamagecap))
|
||||
{
|
||||
if (TShock.Config.KickOnDamageThresholdBroken)
|
||||
{
|
||||
|
|
@ -3425,7 +3425,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (Main.npc[id].townNPC && !args.Player.Group.HasPermission(Permissions.hurttownnpc))
|
||||
if (Main.npc[id].townNPC && !args.Player.HasPermission(Permissions.hurttownnpc))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to hurt this NPC.");
|
||||
args.Player.SendData(PacketTypes.NpcUpdate, "", id);
|
||||
|
|
@ -3588,12 +3588,12 @@ namespace TShockAPI
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (spawnboss && !args.Player.Group.HasPermission(Permissions.summonboss))
|
||||
if (spawnboss && !args.Player.HasPermission(Permissions.summonboss))
|
||||
{
|
||||
args.Player.SendErrorMessage("You don't have permission to summon a boss.");
|
||||
return true;
|
||||
}
|
||||
if (invasion && !args.Player.Group.HasPermission(Permissions.startinvasion))
|
||||
if (invasion && !args.Player.HasPermission(Permissions.startinvasion))
|
||||
{
|
||||
args.Player.SendErrorMessage("You don't have permission to start an invasion.");
|
||||
return true;
|
||||
|
|
@ -3670,7 +3670,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!args.Player.Group.HasPermission(Permissions.ignorepaintdetection))
|
||||
if (!args.Player.HasPermission(Permissions.ignorepaintdetection))
|
||||
{
|
||||
args.Player.PaintThreshold++;
|
||||
}
|
||||
|
|
@ -3714,7 +3714,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!args.Player.Group.HasPermission(Permissions.ignorepaintdetection))
|
||||
if (!args.Player.HasPermission(Permissions.ignorepaintdetection))
|
||||
{
|
||||
args.Player.PaintThreshold++;
|
||||
}
|
||||
|
|
@ -3753,7 +3753,7 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
//Rod of Discord teleport (usually (may be used by modded clients to teleport))
|
||||
if (type == 0 && !args.Player.Group.HasPermission(Permissions.rod))
|
||||
if (type == 0 && !args.Player.HasPermission(Permissions.rod))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to teleport.");
|
||||
args.Player.Teleport(args.TPlayer.position.X, args.TPlayer.position.Y);
|
||||
|
|
@ -3774,7 +3774,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!args.Player.Group.HasPermission(Permissions.wormhole))
|
||||
if (!args.Player.HasPermission(Permissions.wormhole))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to teleport.");
|
||||
args.Player.Teleport(args.TPlayer.position.X, args.TPlayer.position.Y);
|
||||
|
|
|
|||
|
|
@ -22,56 +22,59 @@ using System.Collections.Generic;
|
|||
|
||||
namespace TShockAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// A class used to group multiple users' permissions and settings.
|
||||
/// </summary>
|
||||
public class Group
|
||||
{
|
||||
// NOTE: Using a const still suffers from needing to recompile to change the default
|
||||
// ideally we would use a static but this means it can't be used for the default parameter :(
|
||||
/// <summary>
|
||||
/// Default chat color.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Default chat color.
|
||||
/// </summary>
|
||||
public const string defaultChatColor = "255,255,255";
|
||||
|
||||
/// <summary>
|
||||
/// List of permissions available to the group.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// List of permissions available to the group.
|
||||
/// </summary>
|
||||
public readonly List<string> permissions = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// List of permissions that the group is explicitly barred from.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// List of permissions that the group is explicitly barred from.
|
||||
/// </summary>
|
||||
public readonly List<string> negatedpermissions = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// The group's name.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The group's name.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The group that this group inherits permissions from.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The group that this group inherits permissions from.
|
||||
/// </summary>
|
||||
public Group Parent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The chat prefix for this group.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The chat prefix for this group.
|
||||
/// </summary>
|
||||
public string Prefix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The chat suffix for this group.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The chat suffix for this group.
|
||||
/// </summary>
|
||||
public string Suffix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the parent, not particularly sure why this is here.
|
||||
/// We can use group.Parent.Name and not have this second reference.
|
||||
/// This was added for rest, so a discussion with Shank is necessary.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The name of the parent, not particularly sure why this is here.
|
||||
/// We can use group.Parent.Name and not have this second reference.
|
||||
/// This was added for rest, so a discussion with Shank is necessary.
|
||||
/// </summary>
|
||||
public string ParentName { get { return (null == Parent) ? "" : Parent.Name; } }
|
||||
|
||||
/// <summary>
|
||||
/// The chat color of the group.
|
||||
/// Returns "255,255,255", sets "255,255,255"
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The chat color of the group.
|
||||
/// Returns "255,255,255", sets "255,255,255"
|
||||
/// </summary>
|
||||
public string ChatColor
|
||||
{
|
||||
get { return string.Format("{0},{1},{2}", R.ToString("D3"), G.ToString("D3"), B.ToString("D3")); }
|
||||
|
|
@ -95,9 +98,9 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The permissions of the user in string form.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The permissions of the user in string form.
|
||||
/// </summary>
|
||||
public string Permissions
|
||||
{
|
||||
get
|
||||
|
|
@ -115,9 +118,9 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The permissions of this group and all that it inherits from.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The permissions of this group and all that it inherits from.
|
||||
/// </summary>
|
||||
public virtual List<string> TotalPermissions
|
||||
{
|
||||
get
|
||||
|
|
@ -148,12 +151,31 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The group's chat color red byte.
|
||||
/// </summary>
|
||||
public byte R = 255;
|
||||
/// <summary>
|
||||
/// The group's chat color green byte.
|
||||
/// </summary>
|
||||
public byte G = 255;
|
||||
/// <summary>
|
||||
/// The group's chat color blue byte.
|
||||
/// </summary>
|
||||
public byte B = 255;
|
||||
|
||||
public static Group DefaultGroup = null;
|
||||
/// <summary>
|
||||
/// The default group attributed to unregistered users.
|
||||
/// </summary>
|
||||
public static Group DefaultGroup = null;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the group class.
|
||||
/// </summary>
|
||||
/// <param name="groupname">The name of the group.</param>
|
||||
/// <param name="parentgroup">The parent group, if any.</param>
|
||||
/// <param name="chatcolor">The chat color, in "RRR,GGG,BBB" format.</param>
|
||||
/// <param name="permissions">The list of permissions associated with this group, separated by commas.</param>
|
||||
public Group(string groupname, Group parentgroup = null, string chatcolor = "255,255,255", string permissions = null)
|
||||
{
|
||||
Name = groupname;
|
||||
|
|
@ -162,21 +184,21 @@ namespace TShockAPI
|
|||
Permissions = permissions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if a group has a specified permission.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission to check.</param>
|
||||
/// <returns>Returns true if the user has that permission.</returns>
|
||||
/// <summary>
|
||||
/// Checks to see if a group has a specified permission.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission to check.</param>
|
||||
/// <returns>True if the group has that permission.</returns>
|
||||
public virtual bool HasPermission(string permission)
|
||||
{
|
||||
bool negated = false;
|
||||
{
|
||||
bool negated = false;
|
||||
if (String.IsNullOrEmpty(permission) || (RealHasPermission(permission, ref negated) && !negated))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (negated)
|
||||
return false;
|
||||
if (negated)
|
||||
return false;
|
||||
|
||||
string[] nodes = permission.Split('.');
|
||||
for (int i = nodes.Length - 1; i >= 0; i--)
|
||||
|
|
@ -189,37 +211,37 @@ namespace TShockAPI
|
|||
}
|
||||
return false;
|
||||
}
|
||||
private bool RealHasPermission(string permission, ref bool negated)
|
||||
{
|
||||
negated = false;
|
||||
if (string.IsNullOrEmpty(permission))
|
||||
return true;
|
||||
private bool RealHasPermission(string permission, ref bool negated)
|
||||
{
|
||||
negated = false;
|
||||
if (string.IsNullOrEmpty(permission))
|
||||
return true;
|
||||
|
||||
var cur = this;
|
||||
var traversed = new List<Group>();
|
||||
while (cur != null)
|
||||
{
|
||||
if (cur.negatedpermissions.Contains(permission))
|
||||
{
|
||||
negated = true;
|
||||
return false;
|
||||
}
|
||||
if (cur.permissions.Contains(permission))
|
||||
return true;
|
||||
if (traversed.Contains(cur))
|
||||
{
|
||||
throw new InvalidOperationException("Infinite group parenting ({0})".SFormat(cur.Name));
|
||||
}
|
||||
traversed.Add(cur);
|
||||
cur = cur.Parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
var cur = this;
|
||||
var traversed = new List<Group>();
|
||||
while (cur != null)
|
||||
{
|
||||
if (cur.negatedpermissions.Contains(permission))
|
||||
{
|
||||
negated = true;
|
||||
return false;
|
||||
}
|
||||
if (cur.permissions.Contains(permission))
|
||||
return true;
|
||||
if (traversed.Contains(cur))
|
||||
{
|
||||
throw new InvalidOperationException("Infinite group parenting ({0})".SFormat(cur.Name));
|
||||
}
|
||||
traversed.Add(cur);
|
||||
cur = cur.Parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a permission to the list of negated permissions.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission to negate.</param>
|
||||
/// <summary>
|
||||
/// Adds a permission to the list of negated permissions.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission to negate.</param>
|
||||
public void NegatePermission(string permission)
|
||||
{
|
||||
// Avoid duplicates
|
||||
|
|
@ -230,10 +252,10 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a permission to the list of permissions.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission to add.</param>
|
||||
/// <summary>
|
||||
/// Adds a permission to the list of permissions.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission to add.</param>
|
||||
public void AddPermission(string permission)
|
||||
{
|
||||
if (permission.StartsWith("!"))
|
||||
|
|
@ -249,11 +271,11 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the permission list and sets it to the list provided,
|
||||
/// will parse "!permssion" and add it to the negated permissions.
|
||||
/// </summary>
|
||||
/// <param name="permission"></param>
|
||||
/// <summary>
|
||||
/// Clears the permission list and sets it to the list provided,
|
||||
/// will parse "!permssion" and add it to the negated permissions.
|
||||
/// </summary>
|
||||
/// <param name="permission">The new list of permissions to associate with the group.</param>
|
||||
public void SetPermission(List<string> permission)
|
||||
{
|
||||
permissions.Clear();
|
||||
|
|
@ -261,11 +283,11 @@ namespace TShockAPI
|
|||
permission.ForEach(p => AddPermission(p));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will remove a permission from the respective list,
|
||||
/// where "!permission" will remove a negated permission.
|
||||
/// </summary>
|
||||
/// <param name="permission"></param>
|
||||
/// <summary>
|
||||
/// Will remove a permission from the respective list,
|
||||
/// where "!permission" will remove a negated permission.
|
||||
/// </summary>
|
||||
/// <param name="permission"></param>
|
||||
public void RemovePermission(string permission)
|
||||
{
|
||||
if (permission.StartsWith("!"))
|
||||
|
|
@ -277,9 +299,9 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns all fields of this instance to another.
|
||||
/// </summary>
|
||||
/// <param name="otherGroup">The other instance.</param>
|
||||
/// Assigns all fields of this instance to another.
|
||||
/// </summary>
|
||||
/// <param name="otherGroup">The other instance.</param>
|
||||
public void AssignTo(Group otherGroup)
|
||||
{
|
||||
otherGroup.Name = Name;
|
||||
|
|
@ -292,35 +314,44 @@ namespace TShockAPI
|
|||
otherGroup.Permissions = Permissions;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class is the SuperAdminGroup, which has access to everything.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// This class is the SuperAdminGroup, which has access to everything.
|
||||
/// </summary>
|
||||
public class SuperAdminGroup : Group
|
||||
{
|
||||
/// <summary>
|
||||
/// The superadmin class has every permission, represented by '*'.
|
||||
/// </summary>
|
||||
public override List<string> TotalPermissions
|
||||
{
|
||||
get { return new List<string> { "*" }; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SuperAdminGroup class with the configured parameters.
|
||||
/// Those can be changed in the config file.
|
||||
/// </summary>
|
||||
public SuperAdminGroup()
|
||||
: base("superadmin")
|
||||
{
|
||||
R = (byte) TShock.Config.SuperAdminChatRGB[0];
|
||||
G = (byte) TShock.Config.SuperAdminChatRGB[1];
|
||||
B = (byte) TShock.Config.SuperAdminChatRGB[2];
|
||||
R = (byte)TShock.Config.SuperAdminChatRGB[0];
|
||||
G = (byte)TShock.Config.SuperAdminChatRGB[1];
|
||||
B = (byte)TShock.Config.SuperAdminChatRGB[2];
|
||||
Prefix = TShock.Config.SuperAdminChatPrefix;
|
||||
Suffix = TShock.Config.SuperAdminChatSuffix;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override to allow access to everything.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission</param>
|
||||
/// <returns>True</returns>
|
||||
/// <summary>
|
||||
/// Override to allow access to everything.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission</param>
|
||||
/// <returns>True</returns>
|
||||
public override bool HasPermission(string permission)
|
||||
{
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -21,66 +21,221 @@ using System.ComponentModel;
|
|||
|
||||
namespace TShockAPI.Hooks
|
||||
{
|
||||
/// <summary>
|
||||
/// EventArgs used for the <see cref="PlayerHooks.PlayerPostLogin"/> event.
|
||||
/// </summary>
|
||||
public class PlayerPostLoginEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The player who fired the event.
|
||||
/// </summary>
|
||||
public TSPlayer Player { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the PlayerPostLoginEventArgs class.
|
||||
/// </summary>
|
||||
/// <param name="ply">The player who fired the event.</param>
|
||||
public PlayerPostLoginEventArgs(TSPlayer ply)
|
||||
{
|
||||
Player = ply;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EventArgs used for the <see cref="PlayerHooks.PlayerPreLogin"/> event.
|
||||
/// </summary>
|
||||
public class PlayerPreLoginEventArgs : HandledEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The player who fired the event.
|
||||
/// </summary>
|
||||
public TSPlayer Player { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The player's login name.
|
||||
/// </summary>
|
||||
public string LoginName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The player's raw password.
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EventArgs used for the <see cref="PlayerHooks.PlayerLogout"/> event.
|
||||
/// </summary>
|
||||
public class PlayerLogoutEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The player who fired the event.
|
||||
/// </summary>
|
||||
public TSPlayer Player { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the PlayerLogoutEventArgs class.
|
||||
/// </summary>
|
||||
/// <param name="player">The player who fired the event.</param>
|
||||
public PlayerLogoutEventArgs(TSPlayer player)
|
||||
{
|
||||
Player = player;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EventArgs used for the <see cref="PlayerHooks.PlayerCommand"/> event.
|
||||
/// </summary>
|
||||
public class PlayerCommandEventArgs : HandledEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The player who fired the event.
|
||||
/// </summary>
|
||||
public TSPlayer Player { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The command's name that follows the <see cref="Commands.Specifier"/>.
|
||||
/// </summary>
|
||||
public string CommandName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The command's full text.
|
||||
/// </summary>
|
||||
public string CommandText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The command's parameters extracted from <see cref="CommandText"/>.
|
||||
/// </summary>
|
||||
public List<string> Parameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The full list of server commands.
|
||||
/// </summary>
|
||||
public IEnumerable<Command> CommandList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The prefix used to send the command (either <see cref="Commands.Specifier"/> or <see cref="Commands.SilentSpecifier"/>).
|
||||
/// </summary>
|
||||
public string CommandPrefix { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EventArgs used for the <see cref="PlayerHooks.PlayerChat"/> event.
|
||||
/// </summary>
|
||||
public class PlayerChatEventArgs : HandledEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The player who fired the event.
|
||||
/// </summary>
|
||||
public TSPlayer Player { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The raw chat text as received by the server.
|
||||
/// </summary>
|
||||
public string RawText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="RawText"/> string after being formatted by TShock as specified in the config file.
|
||||
/// </summary>
|
||||
public string TShockFormattedText { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EventArgs used for the <see cref="PlayerHooks.PlayerPermission"/> event.
|
||||
/// </summary>
|
||||
public class PlayerPermissionEventArgs : HandledEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The player who fired the event.
|
||||
/// </summary>
|
||||
public TSPlayer Player { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The permission being checked.
|
||||
/// </summary>
|
||||
public string Permission { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the PlayerPermissionEventArgs class.
|
||||
/// </summary>
|
||||
/// <param name="player">The player who fired the event.</param>
|
||||
/// <param name="permission">The permission being checked.</param>
|
||||
public PlayerPermissionEventArgs(TSPlayer player, string permission)
|
||||
{
|
||||
Player = player;
|
||||
Permission = permission;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A collection of events fired by players that can be hooked to.
|
||||
/// </summary>
|
||||
public static class PlayerHooks
|
||||
{
|
||||
/// <summary>
|
||||
/// The delegate of the <see cref="PlayerPostLogin"/> event.
|
||||
/// </summary>
|
||||
/// <param name="e">The EventArgs for this event.</param>
|
||||
public delegate void PlayerPostLoginD(PlayerPostLoginEventArgs e);
|
||||
/// <summary>
|
||||
/// Fired by players after they've successfully logged in to a user account.
|
||||
/// </summary>
|
||||
public static event PlayerPostLoginD PlayerPostLogin;
|
||||
|
||||
/// <summary>
|
||||
/// The delegate of the <see cref="PlayerPreLogin"/> event.
|
||||
/// </summary>
|
||||
/// <param name="e">The EventArgs for this event.</param>
|
||||
public delegate void PlayerPreLoginD(PlayerPreLoginEventArgs e);
|
||||
/// <summary>
|
||||
/// Fired by players when sending login credentials to the server.
|
||||
/// </summary>
|
||||
public static event PlayerPreLoginD PlayerPreLogin;
|
||||
|
||||
/// <summary>
|
||||
/// The delegate of the <see cref="PlayerLogout"/> event.
|
||||
/// </summary>
|
||||
/// <param name="e">The EventArgs for this event.</param>
|
||||
public delegate void PlayerLogoutD(PlayerLogoutEventArgs e);
|
||||
/// <summary>
|
||||
/// Fired by players upon logging out from a user account.
|
||||
/// </summary>
|
||||
public static event PlayerLogoutD PlayerLogout;
|
||||
|
||||
/// <summary>
|
||||
/// The delegate of the <see cref="PlayerCommand"/> event.
|
||||
/// </summary>
|
||||
/// <param name="e">The EventArgs for this event.</param>
|
||||
public delegate void PlayerCommandD(PlayerCommandEventArgs e);
|
||||
/// <summary>
|
||||
/// Fired by players when using a command.
|
||||
/// </summary>
|
||||
public static event PlayerCommandD PlayerCommand;
|
||||
|
||||
/// <summary>
|
||||
/// The delegate of the <see cref="PlayerChat"/> event.
|
||||
/// </summary>
|
||||
/// <param name="e">The EventArgs for this event.</param>
|
||||
public delegate void PlayerChatD(PlayerChatEventArgs e);
|
||||
/// <summary>
|
||||
/// Fired by players when they send a chat message packet to the server
|
||||
/// and before it is transmitted to the rest of the players.
|
||||
/// </summary>
|
||||
public static event PlayerChatD PlayerChat;
|
||||
|
||||
/// <summary>
|
||||
/// The delegate of the <see cref="PlayerPermission"/> event.
|
||||
/// </summary>
|
||||
/// <param name="e">The EventArgs for this event.</param>
|
||||
public delegate void PlayerPermissionD(PlayerPermissionEventArgs e);
|
||||
/// <summary>
|
||||
/// Fired by players every time a permission check involving them occurs.
|
||||
/// </summary>
|
||||
public static event PlayerPermissionD PlayerPermission;
|
||||
|
||||
/// <summary>
|
||||
/// Fires the <see cref="PlayerPostLogin"/> event.
|
||||
/// </summary>
|
||||
/// <param name="ply">The player firing the event.</param>
|
||||
public static void OnPlayerPostLogin(TSPlayer ply)
|
||||
{
|
||||
if (PlayerPostLogin == null)
|
||||
|
|
@ -92,6 +247,16 @@ namespace TShockAPI.Hooks
|
|||
PlayerPostLogin(args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires the <see cref="PlayerCommand"/> event.
|
||||
/// </summary>
|
||||
/// <param name="player">The player firing the event.</param>
|
||||
/// <param name="cmdName">The command name.</param>
|
||||
/// <param name="cmdText">The raw command text.</param>
|
||||
/// <param name="args">The command args extracted from the command text.</param>
|
||||
/// <param name="commands">The list of commands.</param>
|
||||
/// <param name="cmdPrefix">The command specifier used.</param>
|
||||
/// <returns>True if the event has been handled.</returns>
|
||||
public static bool OnPlayerCommand(TSPlayer player, string cmdName, string cmdText, List<string> args, ref IEnumerable<Command> commands, string cmdPrefix)
|
||||
{
|
||||
if (PlayerCommand == null)
|
||||
|
|
@ -111,6 +276,13 @@ namespace TShockAPI.Hooks
|
|||
return playerCommandEventArgs.Handled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires the <see cref="PlayerPreLogin"/> event.
|
||||
/// </summary>
|
||||
/// <param name="ply">The player firing the event.</param>
|
||||
/// <param name="name">The user name.</param>
|
||||
/// <param name="pass">The password.</param>
|
||||
/// <returns>True if the event has been handled.</returns>
|
||||
public static bool OnPlayerPreLogin(TSPlayer ply, string name, string pass)
|
||||
{
|
||||
if (PlayerPreLogin == null)
|
||||
|
|
@ -121,6 +293,10 @@ namespace TShockAPI.Hooks
|
|||
return args.Handled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires the <see cref="PlayerLogout"/> event.
|
||||
/// </summary>
|
||||
/// <param name="ply">The player firing the event.</param>
|
||||
public static void OnPlayerLogout(TSPlayer ply)
|
||||
{
|
||||
if (PlayerLogout == null)
|
||||
|
|
@ -130,6 +306,12 @@ namespace TShockAPI.Hooks
|
|||
PlayerLogout(args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires the <see cref="PlayerChat"/> event.
|
||||
/// </summary>
|
||||
/// <param name="ply">The player firing the event.</param>
|
||||
/// <param name="rawtext">The raw chat text sent by the player.</param>
|
||||
/// <param name="tshockText">The chat text after being formatted.</param>
|
||||
public static void OnPlayerChat(TSPlayer ply, string rawtext, ref string tshockText)
|
||||
{
|
||||
if (PlayerChat == null)
|
||||
|
|
@ -139,5 +321,20 @@ namespace TShockAPI.Hooks
|
|||
PlayerChat(args);
|
||||
tshockText = args.TShockFormattedText;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires the <see cref="PlayerPermission"/> event.
|
||||
/// </summary>
|
||||
/// <param name="player">The player firing the event.</param>
|
||||
/// <returns>True if the event has been handled.</returns>
|
||||
public static bool OnPlayerPermission(TSPlayer player, string permission)
|
||||
{
|
||||
if (PlayerPermission == null)
|
||||
return false;
|
||||
|
||||
var args = new PlayerPermissionEventArgs(player, permission);
|
||||
PlayerPermission(args);
|
||||
return args.Handled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
411
TShockAPI/PlayerData.cs
Normal file
411
TShockAPI/PlayerData.cs
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
using Terraria;
|
||||
using TShockAPI;
|
||||
|
||||
public class PlayerData
|
||||
{
|
||||
public NetItem[] inventory = new NetItem[NetItem.MaxInventory];
|
||||
public int health = TShock.ServerSideCharacterConfig.StartingHealth;
|
||||
public int maxHealth = TShock.ServerSideCharacterConfig.StartingHealth;
|
||||
public int mana = TShock.ServerSideCharacterConfig.StartingMana;
|
||||
public int maxMana = TShock.ServerSideCharacterConfig.StartingMana;
|
||||
public bool exists;
|
||||
public int spawnX = -1;
|
||||
public int spawnY = -1;
|
||||
public int? extraSlot;
|
||||
public int? skinVariant;
|
||||
public int? hair;
|
||||
public byte hairDye;
|
||||
public Color? hairColor;
|
||||
public Color? pantsColor;
|
||||
public Color? shirtColor;
|
||||
public Color? underShirtColor;
|
||||
public Color? shoeColor;
|
||||
public Color? skinColor;
|
||||
public Color? eyeColor;
|
||||
public bool[] hideVisuals;
|
||||
public int questsCompleted;
|
||||
|
||||
public PlayerData(TSPlayer player)
|
||||
{
|
||||
for (int i = 0; i < NetItem.MaxInventory; i++)
|
||||
{
|
||||
this.inventory[i] = new NetItem();
|
||||
}
|
||||
|
||||
for (int i = 0; i < TShock.ServerSideCharacterConfig.StartingInventory.Count; i++)
|
||||
{
|
||||
var item = TShock.ServerSideCharacterConfig.StartingInventory[i];
|
||||
StoreSlot(i, item.NetId, item.PrefixId, item.Stack);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores an item at the specific storage slot
|
||||
/// </summary>
|
||||
/// <param name="slot"></param>
|
||||
/// <param name="netID"></param>
|
||||
/// <param name="prefix"></param>
|
||||
/// <param name="stack"></param>
|
||||
public void StoreSlot(int slot, int netID, byte prefix, int stack)
|
||||
{
|
||||
if (slot > (this.inventory.Length - 1)) //if the slot is out of range then dont save
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.inventory[slot] = new NetItem(netID, stack, prefix);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a characters data to this object
|
||||
/// </summary>
|
||||
/// <param name="player"></param>
|
||||
public void CopyCharacter(TSPlayer player)
|
||||
{
|
||||
this.health = player.TPlayer.statLife > 0 ? player.TPlayer.statLife : 1;
|
||||
this.maxHealth = player.TPlayer.statLifeMax;
|
||||
this.mana = player.TPlayer.statMana;
|
||||
this.maxMana = player.TPlayer.statManaMax;
|
||||
if (player.sX > 0 && player.sY > 0)
|
||||
{
|
||||
this.spawnX = player.sX;
|
||||
this.spawnY = player.sY;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.spawnX = player.TPlayer.SpawnX;
|
||||
this.spawnY = player.TPlayer.SpawnY;
|
||||
}
|
||||
extraSlot = player.TPlayer.extraAccessory ? 1 : 0;
|
||||
this.skinVariant = player.TPlayer.skinVariant;
|
||||
this.hair = player.TPlayer.hair;
|
||||
this.hairDye = player.TPlayer.hairDye;
|
||||
this.hairColor = player.TPlayer.hairColor;
|
||||
this.pantsColor = player.TPlayer.pantsColor;
|
||||
this.shirtColor = player.TPlayer.shirtColor;
|
||||
this.underShirtColor = player.TPlayer.underShirtColor;
|
||||
this.shoeColor = player.TPlayer.shoeColor;
|
||||
this.hideVisuals = player.TPlayer.hideVisual;
|
||||
this.skinColor = player.TPlayer.skinColor;
|
||||
this.eyeColor = player.TPlayer.eyeColor;
|
||||
this.questsCompleted = player.TPlayer.anglerQuestsFinished;
|
||||
|
||||
Item[] inventory = player.TPlayer.inventory;
|
||||
Item[] armor = player.TPlayer.armor;
|
||||
Item[] dye = player.TPlayer.dye;
|
||||
Item[] miscEqups = player.TPlayer.miscEquips;
|
||||
Item[] miscDyes = player.TPlayer.miscDyes;
|
||||
Item[] piggy = player.TPlayer.bank.item;
|
||||
Item[] safe = player.TPlayer.bank2.item;
|
||||
Item trash = player.TPlayer.trashItem;
|
||||
|
||||
for (int i = 0; i < NetItem.MaxInventory; i++)
|
||||
{
|
||||
if (i < NetItem.InventorySlots)
|
||||
{
|
||||
//0-58
|
||||
this.inventory[i] = (NetItem)inventory[i];
|
||||
}
|
||||
else if (i < NetItem.InventorySlots + NetItem.ArmorSlots)
|
||||
{
|
||||
//59-78
|
||||
var index = i - NetItem.InventorySlots;
|
||||
this.inventory[i] = (NetItem)armor[index];
|
||||
}
|
||||
else if (i < NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots)
|
||||
{
|
||||
//79-88
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots);
|
||||
this.inventory[i] = (NetItem)dye[index];
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots)
|
||||
{
|
||||
//89-93
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots);
|
||||
this.inventory[i] = (NetItem)miscEqups[index];
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots
|
||||
+ NetItem.MiscDyeSlots)
|
||||
{
|
||||
//93-98
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots);
|
||||
this.inventory[i] = (NetItem)miscDyes[index];
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots +
|
||||
NetItem.MiscDyeSlots + NetItem.PiggySlots)
|
||||
{
|
||||
//98-138
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots + NetItem.MiscDyeSlots);
|
||||
this.inventory[i] = (NetItem)piggy[index];
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots +
|
||||
NetItem.MiscDyeSlots + NetItem.PiggySlots + NetItem.SafeSlots)
|
||||
{
|
||||
//138-178
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots + NetItem.MiscDyeSlots + NetItem.PiggySlots);
|
||||
this.inventory[i] = (NetItem)safe[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
//179
|
||||
this.inventory[i] = (NetItem)trash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores a player's character to the state stored in the database
|
||||
/// </summary>
|
||||
/// <param name="player"></param>
|
||||
public void RestoreCharacter(TSPlayer player)
|
||||
{
|
||||
// Start ignoring SSC-related packets! This is critical so that we don't send or receive dirty data!
|
||||
player.IgnoreSSCPackets = true;
|
||||
|
||||
player.TPlayer.statLife = this.health;
|
||||
player.TPlayer.statLifeMax = this.maxHealth;
|
||||
player.TPlayer.statMana = this.maxMana;
|
||||
player.TPlayer.statManaMax = this.maxMana;
|
||||
player.TPlayer.SpawnX = this.spawnX;
|
||||
player.TPlayer.SpawnY = this.spawnY;
|
||||
player.sX = this.spawnX;
|
||||
player.sY = this.spawnY;
|
||||
player.TPlayer.hairDye = this.hairDye;
|
||||
player.TPlayer.anglerQuestsFinished = this.questsCompleted;
|
||||
|
||||
if (extraSlot != null)
|
||||
player.TPlayer.extraAccessory = extraSlot.Value == 1 ? true : false;
|
||||
if (this.skinVariant != null)
|
||||
player.TPlayer.skinVariant = this.skinVariant.Value;
|
||||
if (this.hair != null)
|
||||
player.TPlayer.hair = this.hair.Value;
|
||||
if (this.hairColor != null)
|
||||
player.TPlayer.hairColor = this.hairColor.Value;
|
||||
if (this.pantsColor != null)
|
||||
player.TPlayer.pantsColor = this.pantsColor.Value;
|
||||
if (this.shirtColor != null)
|
||||
player.TPlayer.shirtColor = this.shirtColor.Value;
|
||||
if (this.underShirtColor != null)
|
||||
player.TPlayer.underShirtColor = this.underShirtColor.Value;
|
||||
if (this.shoeColor != null)
|
||||
player.TPlayer.shoeColor = this.shoeColor.Value;
|
||||
if (this.skinColor != null)
|
||||
player.TPlayer.skinColor = this.skinColor.Value;
|
||||
if (this.eyeColor != null)
|
||||
player.TPlayer.eyeColor = this.eyeColor.Value;
|
||||
|
||||
if (this.hideVisuals != null)
|
||||
player.TPlayer.hideVisual = this.hideVisuals;
|
||||
else
|
||||
player.TPlayer.hideVisual = new bool[player.TPlayer.hideVisual.Length];
|
||||
|
||||
for (int i = 0; i < NetItem.MaxInventory; i++)
|
||||
{
|
||||
if (i < NetItem.InventorySlots)
|
||||
{
|
||||
//0-58
|
||||
player.TPlayer.inventory[i].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.inventory[i].netID != 0)
|
||||
{
|
||||
player.TPlayer.inventory[i].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.inventory[i].prefix = this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i < NetItem.InventorySlots + NetItem.ArmorSlots)
|
||||
{
|
||||
//59-78
|
||||
var index = i - NetItem.InventorySlots;
|
||||
player.TPlayer.armor[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.armor[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.armor[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.armor[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i < NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots)
|
||||
{
|
||||
//79-88
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots);
|
||||
player.TPlayer.dye[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.dye[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.dye[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.dye[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots)
|
||||
{
|
||||
//89-93
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots);
|
||||
player.TPlayer.miscEquips[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.miscEquips[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.miscEquips[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.miscEquips[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots
|
||||
+ NetItem.MiscDyeSlots)
|
||||
{
|
||||
//93-98
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots);
|
||||
player.TPlayer.miscDyes[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.miscDyes[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.miscDyes[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.miscDyes[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots +
|
||||
NetItem.MiscDyeSlots + NetItem.PiggySlots)
|
||||
{
|
||||
//98-138
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots + NetItem.MiscDyeSlots);
|
||||
player.TPlayer.bank.item[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.bank.item[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.bank.item[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.bank.item[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots +
|
||||
NetItem.MiscDyeSlots + NetItem.PiggySlots + NetItem.SafeSlots)
|
||||
{
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots + NetItem.MiscDyeSlots + NetItem.PiggySlots);
|
||||
player.TPlayer.bank2.item[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.bank2.item[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.bank2.item[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.bank2.item[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.TPlayer.trashItem.netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.trashItem.netID != 0)
|
||||
{
|
||||
player.TPlayer.trashItem.stack = this.inventory[i].Stack;
|
||||
player.TPlayer.trashItem.prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float slot = 0f;
|
||||
for (int k = 0; k < NetItem.InventorySlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].inventory[k].name, player.Index, slot, (float)Main.player[player.Index].inventory[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.ArmorSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[k].name, player.Index, slot, (float)Main.player[player.Index].armor[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.DyeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[k].name, player.Index, slot, (float)Main.player[player.Index].dye[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.MiscEquipSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].miscEquips[k].name, player.Index, slot, (float)Main.player[player.Index].miscEquips[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.MiscDyeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].miscDyes[k].name, player.Index, slot, (float)Main.player[player.Index].miscDyes[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.PiggySlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].bank.item[k].name, player.Index, slot, (float)Main.player[player.Index].bank.item[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.SafeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].bank2.item[k].name, player.Index, slot, (float)Main.player[player.Index].bank2.item[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].trashItem.name, player.Index, slot, (float)Main.player[player.Index].trashItem.prefix);
|
||||
|
||||
NetMessage.SendData(4, -1, -1, player.Name, player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(42, -1, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(16, -1, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
|
||||
slot = 0f;
|
||||
for (int k = 0; k < NetItem.InventorySlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].inventory[k].name, player.Index, slot, (float)Main.player[player.Index].inventory[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.ArmorSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[k].name, player.Index, slot, (float)Main.player[player.Index].armor[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.DyeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[k].name, player.Index, slot, (float)Main.player[player.Index].dye[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.MiscEquipSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].miscEquips[k].name, player.Index, slot, (float)Main.player[player.Index].miscEquips[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.MiscDyeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].miscDyes[k].name, player.Index, slot, (float)Main.player[player.Index].miscDyes[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.PiggySlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].bank.item[k].name, player.Index, slot, (float)Main.player[player.Index].bank.item[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.SafeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].bank2.item[k].name, player.Index, slot, (float)Main.player[player.Index].bank2.item[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].trashItem.name, player.Index, slot, (float)Main.player[player.Index].trashItem.prefix);
|
||||
|
||||
NetMessage.SendData(4, player.Index, -1, player.Name, player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(42, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(16, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
|
||||
for (int k = 0; k < 22; k++)
|
||||
{
|
||||
player.TPlayer.buffType[k] = 0;
|
||||
}
|
||||
NetMessage.SendData(50, -1, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(50, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(76, -1, -1, "", player.Index);
|
||||
|
||||
NetMessage.SendData(39, player.Index, -1, "", 400);
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ using System.Timers;
|
|||
using Terraria;
|
||||
using Terraria.ID;
|
||||
using TShockAPI.DB;
|
||||
using TShockAPI.Hooks;
|
||||
using TShockAPI.Net;
|
||||
using Timer = System.Timers.Timer;
|
||||
|
||||
|
|
@ -430,11 +431,11 @@ namespace TShockAPI
|
|||
}
|
||||
try
|
||||
{
|
||||
if ((tempGroup != null && tempGroup.HasPermission(Permissions.bypassssc)) || Group.HasPermission(Permissions.bypassssc))
|
||||
{
|
||||
TShock.Log.ConsoleInfo("Skipping SSC Backup for " + User.Name); // Debug Code
|
||||
return true;
|
||||
}
|
||||
if (HasPermission(Permissions.bypassssc))
|
||||
{
|
||||
TShock.Log.ConsoleInfo("Skipping SSC Backup for " + User.Name); // Debug Code
|
||||
return true;
|
||||
}
|
||||
PlayerData.CopyCharacter(this);
|
||||
TShock.CharacterDB.InsertPlayerData(this);
|
||||
return true;
|
||||
|
|
@ -875,22 +876,22 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calling new StackTrace() is incredibly expensive, and must be disabled
|
||||
* in release builds. Use a conditional call instead.
|
||||
*/
|
||||
LogStackFrame();
|
||||
/*
|
||||
* Calling new StackTrace() is incredibly expensive, and must be disabled
|
||||
* in release builds. Use a conditional call instead.
|
||||
*/
|
||||
LogStackFrame();
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void LogStackFrame()
|
||||
{
|
||||
var trace = new StackTrace();
|
||||
StackFrame frame = null;
|
||||
frame = trace.GetFrame(1);
|
||||
if (frame != null && frame.GetMethod().DeclaringType != null)
|
||||
TShock.Log.Debug(frame.GetMethod().DeclaringType.Name + " called Disable().");
|
||||
}
|
||||
[Conditional("DEBUG")]
|
||||
private void LogStackFrame()
|
||||
{
|
||||
var trace = new StackTrace();
|
||||
StackFrame frame = null;
|
||||
frame = trace.GetFrame(1);
|
||||
if (frame != null && frame.GetMethod().DeclaringType != null)
|
||||
TShock.Log.Debug(frame.GetMethod().DeclaringType.Name + " called Disable().");
|
||||
}
|
||||
|
||||
public virtual void Whoopie(object time)
|
||||
{
|
||||
|
|
@ -954,6 +955,22 @@ namespace TShockAPI
|
|||
|
||||
AwaitingResponse.Add(name, callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if a player or its associated group/temporary group has a specified permission.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission to check.</param>
|
||||
/// <returns>True if the player has that permission.</returns>
|
||||
public bool HasPermission(string permission)
|
||||
{
|
||||
if (PlayerHooks.OnPlayerPermission(this, permission))
|
||||
return true;
|
||||
|
||||
if (tempGroup != null)
|
||||
return tempGroup.HasPermission(permission);
|
||||
else
|
||||
return Group.HasPermission(permission);
|
||||
}
|
||||
}
|
||||
|
||||
public class TSRestPlayer : TSPlayer
|
||||
|
|
@ -1001,568 +1018,4 @@ namespace TShockAPI
|
|||
return this.CommandOutput;
|
||||
}
|
||||
}
|
||||
|
||||
public class TSServerPlayer : TSPlayer
|
||||
{
|
||||
public static string AccountName = "ServerConsole";
|
||||
|
||||
public TSServerPlayer()
|
||||
: base("Server")
|
||||
{
|
||||
Group = new SuperAdminGroup();
|
||||
User = new User{Name = AccountName};
|
||||
}
|
||||
|
||||
public override void SendErrorMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendInfoMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendSuccessMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendWarningMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendMessage(string msg, Color color)
|
||||
{
|
||||
SendMessage(msg, color.R, color.G, color.B);
|
||||
}
|
||||
|
||||
public override void SendMessage(string msg, byte red, byte green, byte blue)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
|
||||
public void SetFullMoon()
|
||||
{
|
||||
Main.dayTime = false;
|
||||
Main.moonPhase = 0;
|
||||
Main.time = 0.0;
|
||||
TSPlayer.All.SendData(PacketTypes.WorldInfo);
|
||||
}
|
||||
|
||||
public void SetBloodMoon(bool bloodMoon)
|
||||
{
|
||||
if (bloodMoon)
|
||||
{
|
||||
Main.dayTime = false;
|
||||
Main.bloodMoon = true;
|
||||
Main.time = 0.0;
|
||||
}
|
||||
else
|
||||
Main.bloodMoon = false;
|
||||
TSPlayer.All.SendData(PacketTypes.WorldInfo);
|
||||
}
|
||||
|
||||
public void SetFrostMoon(bool snowMoon)
|
||||
{
|
||||
if (snowMoon)
|
||||
{
|
||||
Main.dayTime = false;
|
||||
Main.snowMoon = true;
|
||||
Main.time = 0.0;
|
||||
}
|
||||
else
|
||||
Main.snowMoon = false;
|
||||
TSPlayer.All.SendData(PacketTypes.WorldInfo);
|
||||
}
|
||||
|
||||
public void SetPumpkinMoon(bool pumpkinMoon)
|
||||
{
|
||||
if (pumpkinMoon)
|
||||
{
|
||||
Main.dayTime = false;
|
||||
Main.pumpkinMoon = true;
|
||||
Main.time = 0.0;
|
||||
}
|
||||
else
|
||||
Main.pumpkinMoon = false;
|
||||
TSPlayer.All.SendData(PacketTypes.WorldInfo);
|
||||
}
|
||||
|
||||
public void SetEclipse(bool eclipse)
|
||||
{
|
||||
if (eclipse)
|
||||
{
|
||||
Main.dayTime = Main.eclipse = true;
|
||||
Main.time = 0.0;
|
||||
}
|
||||
else
|
||||
Main.eclipse = false;
|
||||
TSPlayer.All.SendData(PacketTypes.WorldInfo);
|
||||
}
|
||||
|
||||
public void SetTime(bool dayTime, double time)
|
||||
{
|
||||
Main.dayTime = dayTime;
|
||||
Main.time = time;
|
||||
TSPlayer.All.SendData(PacketTypes.TimeSet, "", dayTime ? 1 : 0, (int)time, Main.sunModY, Main.moonModY);
|
||||
}
|
||||
|
||||
public void SpawnNPC(int type, string name, int amount, int startTileX, int startTileY, int tileXRange = 100,
|
||||
int tileYRange = 50)
|
||||
{
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
int spawnTileX;
|
||||
int spawnTileY;
|
||||
TShock.Utils.GetRandomClearTileWithInRange(startTileX, startTileY, tileXRange, tileYRange, out spawnTileX,
|
||||
out spawnTileY);
|
||||
int npcid = NPC.NewNPC(spawnTileX*16, spawnTileY*16, type, 0);
|
||||
// This is for special slimes
|
||||
Main.npc[npcid].SetDefaults(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void StrikeNPC(int npcid, int damage, float knockBack, int hitDirection)
|
||||
{
|
||||
// Main.rand is thread static.
|
||||
if (Main.rand == null)
|
||||
Main.rand = new Random();
|
||||
|
||||
Main.npc[npcid].StrikeNPC(damage, knockBack, hitDirection);
|
||||
NetMessage.SendData((int) PacketTypes.NpcStrike, -1, -1, "", npcid, damage, knockBack, hitDirection);
|
||||
}
|
||||
|
||||
public void RevertTiles(Dictionary<Vector2, Tile> tiles)
|
||||
{
|
||||
// Update Main.Tile first so that when tile sqaure is sent it is correct
|
||||
foreach (KeyValuePair<Vector2, Tile> entry in tiles)
|
||||
{
|
||||
Main.tile[(int) entry.Key.X, (int) entry.Key.Y] = entry.Value;
|
||||
}
|
||||
// Send all players updated tile sqaures
|
||||
foreach (Vector2 coords in tiles.Keys)
|
||||
{
|
||||
All.SendTileSquare((int) coords.X, (int) coords.Y, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerData
|
||||
{
|
||||
public NetItem[] inventory = new NetItem[NetItem.MaxInventory];
|
||||
public int health = TShock.ServerSideCharacterConfig.StartingHealth;
|
||||
public int maxHealth = TShock.ServerSideCharacterConfig.StartingHealth;
|
||||
public int mana = TShock.ServerSideCharacterConfig.StartingMana;
|
||||
public int maxMana = TShock.ServerSideCharacterConfig.StartingMana;
|
||||
public bool exists;
|
||||
public int spawnX= -1;
|
||||
public int spawnY= -1;
|
||||
public int? extraSlot;
|
||||
public int? skinVariant;
|
||||
public int? hair;
|
||||
public byte hairDye;
|
||||
public Color? hairColor;
|
||||
public Color? pantsColor;
|
||||
public Color? shirtColor;
|
||||
public Color? underShirtColor;
|
||||
public Color? shoeColor;
|
||||
public Color? skinColor;
|
||||
public Color? eyeColor;
|
||||
public bool[] hideVisuals;
|
||||
public int questsCompleted;
|
||||
|
||||
public PlayerData(TSPlayer player)
|
||||
{
|
||||
for (int i = 0; i < NetItem.MaxInventory; i++)
|
||||
{
|
||||
this.inventory[i] = new NetItem();
|
||||
}
|
||||
|
||||
for (int i = 0; i < TShock.ServerSideCharacterConfig.StartingInventory.Count; i++)
|
||||
{
|
||||
var item = TShock.ServerSideCharacterConfig.StartingInventory[i];
|
||||
StoreSlot(i, item.NetId, item.PrefixId, item.Stack);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores an item at the specific storage slot
|
||||
/// </summary>
|
||||
/// <param name="slot"></param>
|
||||
/// <param name="netID"></param>
|
||||
/// <param name="prefix"></param>
|
||||
/// <param name="stack"></param>
|
||||
public void StoreSlot(int slot, int netID, byte prefix, int stack)
|
||||
{
|
||||
if (slot > (this.inventory.Length - 1)) //if the slot is out of range then dont save
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.inventory[slot] = new NetItem(netID, stack, prefix);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a characters data to this object
|
||||
/// </summary>
|
||||
/// <param name="player"></param>
|
||||
public void CopyCharacter(TSPlayer player)
|
||||
{
|
||||
this.health = player.TPlayer.statLife > 0 ? player.TPlayer.statLife : 1;
|
||||
this.maxHealth = player.TPlayer.statLifeMax;
|
||||
this.mana = player.TPlayer.statMana;
|
||||
this.maxMana = player.TPlayer.statManaMax;
|
||||
if (player.sX > 0 && player.sY > 0)
|
||||
{
|
||||
this.spawnX = player.sX;
|
||||
this.spawnY = player.sY;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.spawnX = player.TPlayer.SpawnX;
|
||||
this.spawnY = player.TPlayer.SpawnY;
|
||||
}
|
||||
extraSlot = player.TPlayer.extraAccessory ? 1 : 0;
|
||||
this.skinVariant = player.TPlayer.skinVariant;
|
||||
this.hair = player.TPlayer.hair;
|
||||
this.hairDye = player.TPlayer.hairDye;
|
||||
this.hairColor = player.TPlayer.hairColor;
|
||||
this.pantsColor = player.TPlayer.pantsColor;
|
||||
this.shirtColor = player.TPlayer.shirtColor;
|
||||
this.underShirtColor = player.TPlayer.underShirtColor;
|
||||
this.shoeColor = player.TPlayer.shoeColor;
|
||||
this.hideVisuals = player.TPlayer.hideVisual;
|
||||
this.skinColor = player.TPlayer.skinColor;
|
||||
this.eyeColor = player.TPlayer.eyeColor;
|
||||
this.questsCompleted = player.TPlayer.anglerQuestsFinished;
|
||||
|
||||
Item[] inventory = player.TPlayer.inventory;
|
||||
Item[] armor = player.TPlayer.armor;
|
||||
Item[] dye = player.TPlayer.dye;
|
||||
Item[] miscEqups = player.TPlayer.miscEquips;
|
||||
Item[] miscDyes = player.TPlayer.miscDyes;
|
||||
Item[] piggy = player.TPlayer.bank.item;
|
||||
Item[] safe = player.TPlayer.bank2.item;
|
||||
Item trash = player.TPlayer.trashItem;
|
||||
|
||||
for (int i = 0; i < NetItem.MaxInventory; i++)
|
||||
{
|
||||
if (i < NetItem.InventorySlots)
|
||||
{
|
||||
//0-58
|
||||
this.inventory[i] = (NetItem)inventory[i];
|
||||
}
|
||||
else if (i < NetItem.InventorySlots + NetItem.ArmorSlots)
|
||||
{
|
||||
//59-78
|
||||
var index = i - NetItem.InventorySlots;
|
||||
this.inventory[i] = (NetItem)armor[index];
|
||||
}
|
||||
else if (i < NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots)
|
||||
{
|
||||
//79-88
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots);
|
||||
this.inventory[i] = (NetItem)dye[index];
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots)
|
||||
{
|
||||
//89-93
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots);
|
||||
this.inventory[i] = (NetItem)miscEqups[index];
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots
|
||||
+ NetItem.MiscDyeSlots)
|
||||
{
|
||||
//93-98
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots);
|
||||
this.inventory[i] = (NetItem)miscDyes[index];
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots +
|
||||
NetItem.MiscDyeSlots + NetItem.PiggySlots)
|
||||
{
|
||||
//98-138
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots + NetItem.MiscDyeSlots);
|
||||
this.inventory[i] = (NetItem)piggy[index];
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots +
|
||||
NetItem.MiscDyeSlots + NetItem.PiggySlots + NetItem.SafeSlots)
|
||||
{
|
||||
//138-178
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots + NetItem.MiscDyeSlots + NetItem.PiggySlots);
|
||||
this.inventory[i] = (NetItem)safe[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
//179
|
||||
this.inventory[i] = (NetItem)trash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores a player's character to the state stored in the database
|
||||
/// </summary>
|
||||
/// <param name="player"></param>
|
||||
public void RestoreCharacter(TSPlayer player)
|
||||
{
|
||||
// Start ignoring SSC-related packets! This is critical so that we don't send or receive dirty data!
|
||||
player.IgnoreSSCPackets = true;
|
||||
|
||||
player.TPlayer.statLife = this.health;
|
||||
player.TPlayer.statLifeMax = this.maxHealth;
|
||||
player.TPlayer.statMana = this.maxMana;
|
||||
player.TPlayer.statManaMax = this.maxMana;
|
||||
player.TPlayer.SpawnX = this.spawnX;
|
||||
player.TPlayer.SpawnY = this.spawnY;
|
||||
player.sX = this.spawnX;
|
||||
player.sY = this.spawnY;
|
||||
player.TPlayer.hairDye = this.hairDye;
|
||||
player.TPlayer.anglerQuestsFinished = this.questsCompleted;
|
||||
|
||||
if (extraSlot != null)
|
||||
player.TPlayer.extraAccessory = extraSlot.Value == 1 ? true : false;
|
||||
if (this.skinVariant != null)
|
||||
player.TPlayer.skinVariant = this.skinVariant.Value;
|
||||
if (this.hair != null)
|
||||
player.TPlayer.hair = this.hair.Value;
|
||||
if (this.hairColor != null)
|
||||
player.TPlayer.hairColor = this.hairColor.Value;
|
||||
if (this.pantsColor != null)
|
||||
player.TPlayer.pantsColor = this.pantsColor.Value;
|
||||
if (this.shirtColor != null)
|
||||
player.TPlayer.shirtColor = this.shirtColor.Value;
|
||||
if (this.underShirtColor != null)
|
||||
player.TPlayer.underShirtColor = this.underShirtColor.Value;
|
||||
if (this.shoeColor != null)
|
||||
player.TPlayer.shoeColor = this.shoeColor.Value;
|
||||
if (this.skinColor != null)
|
||||
player.TPlayer.skinColor = this.skinColor.Value;
|
||||
if (this.eyeColor != null)
|
||||
player.TPlayer.eyeColor = this.eyeColor.Value;
|
||||
|
||||
if (this.hideVisuals != null)
|
||||
player.TPlayer.hideVisual = this.hideVisuals;
|
||||
else
|
||||
player.TPlayer.hideVisual = new bool[player.TPlayer.hideVisual.Length];
|
||||
|
||||
for (int i = 0; i < NetItem.MaxInventory; i++)
|
||||
{
|
||||
if (i < NetItem.InventorySlots)
|
||||
{
|
||||
//0-58
|
||||
player.TPlayer.inventory[i].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.inventory[i].netID != 0)
|
||||
{
|
||||
player.TPlayer.inventory[i].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.inventory[i].prefix = this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i < NetItem.InventorySlots + NetItem.ArmorSlots)
|
||||
{
|
||||
//59-78
|
||||
var index = i - NetItem.InventorySlots;
|
||||
player.TPlayer.armor[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.armor[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.armor[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.armor[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i < NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots)
|
||||
{
|
||||
//79-88
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots);
|
||||
player.TPlayer.dye[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.dye[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.dye[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.dye[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots)
|
||||
{
|
||||
//89-93
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots);
|
||||
player.TPlayer.miscEquips[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.miscEquips[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.miscEquips[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.miscEquips[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots
|
||||
+ NetItem.MiscDyeSlots)
|
||||
{
|
||||
//93-98
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots);
|
||||
player.TPlayer.miscDyes[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.miscDyes[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.miscDyes[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.miscDyes[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots +
|
||||
NetItem.MiscDyeSlots + NetItem.PiggySlots)
|
||||
{
|
||||
//98-138
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots + NetItem.MiscDyeSlots);
|
||||
player.TPlayer.bank.item[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.bank.item[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.bank.item[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.bank.item[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else if (i <
|
||||
NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots + NetItem.MiscEquipSlots +
|
||||
NetItem.MiscDyeSlots + NetItem.PiggySlots + NetItem.SafeSlots)
|
||||
{
|
||||
var index = i - (NetItem.InventorySlots + NetItem.ArmorSlots + NetItem.DyeSlots
|
||||
+ NetItem.MiscEquipSlots + NetItem.MiscDyeSlots + NetItem.PiggySlots);
|
||||
player.TPlayer.bank2.item[index].netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.bank2.item[index].netID != 0)
|
||||
{
|
||||
player.TPlayer.bank2.item[index].stack = this.inventory[i].Stack;
|
||||
player.TPlayer.bank2.item[index].prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.TPlayer.trashItem.netDefaults(this.inventory[i].NetId);
|
||||
|
||||
if (player.TPlayer.trashItem.netID != 0)
|
||||
{
|
||||
player.TPlayer.trashItem.stack = this.inventory[i].Stack;
|
||||
player.TPlayer.trashItem.prefix = (byte)this.inventory[i].PrefixId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float slot = 0f;
|
||||
for (int k = 0; k < NetItem.InventorySlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].inventory[k].name, player.Index, slot, (float)Main.player[player.Index].inventory[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.ArmorSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[k].name, player.Index, slot, (float)Main.player[player.Index].armor[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.DyeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[k].name, player.Index, slot, (float)Main.player[player.Index].dye[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.MiscEquipSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].miscEquips[k].name, player.Index, slot, (float)Main.player[player.Index].miscEquips[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.MiscDyeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].miscDyes[k].name, player.Index, slot, (float)Main.player[player.Index].miscDyes[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.PiggySlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].bank.item[k].name, player.Index, slot, (float)Main.player[player.Index].bank.item[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.SafeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].bank2.item[k].name, player.Index, slot, (float)Main.player[player.Index].bank2.item[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].trashItem.name, player.Index, slot, (float)Main.player[player.Index].trashItem.prefix);
|
||||
|
||||
NetMessage.SendData(4, -1, -1, player.Name, player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(42, -1, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(16, -1, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
|
||||
slot = 0f;
|
||||
for (int k = 0; k < NetItem.InventorySlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].inventory[k].name, player.Index, slot, (float)Main.player[player.Index].inventory[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.ArmorSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[k].name, player.Index, slot, (float)Main.player[player.Index].armor[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.DyeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[k].name, player.Index, slot, (float)Main.player[player.Index].dye[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.MiscEquipSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].miscEquips[k].name, player.Index, slot, (float)Main.player[player.Index].miscEquips[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.MiscDyeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].miscDyes[k].name, player.Index, slot, (float)Main.player[player.Index].miscDyes[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.PiggySlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].bank.item[k].name, player.Index, slot, (float)Main.player[player.Index].bank.item[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
for (int k = 0; k < NetItem.SafeSlots; k++)
|
||||
{
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].bank2.item[k].name, player.Index, slot, (float)Main.player[player.Index].bank2.item[k].prefix);
|
||||
slot++;
|
||||
}
|
||||
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].trashItem.name, player.Index, slot, (float)Main.player[player.Index].trashItem.prefix);
|
||||
|
||||
NetMessage.SendData(4, player.Index, -1, player.Name, player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(42, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(16, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
|
||||
for (int k = 0; k < 22; k++)
|
||||
{
|
||||
player.TPlayer.buffType[k] = 0;
|
||||
}
|
||||
NetMessage.SendData(50, -1, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(50, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(76, -1, -1, "", player.Index);
|
||||
|
||||
NetMessage.SendData(39, player.Index, -1, "", 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
160
TShockAPI/TSServerPlayer.cs
Normal file
160
TShockAPI/TSServerPlayer.cs
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Terraria;
|
||||
using TShockAPI;
|
||||
using TShockAPI.DB;
|
||||
|
||||
public class TSServerPlayer : TSPlayer
|
||||
{
|
||||
public static string AccountName = "ServerConsole";
|
||||
|
||||
public TSServerPlayer()
|
||||
: base("Server")
|
||||
{
|
||||
Group = new SuperAdminGroup();
|
||||
User = new User { Name = AccountName };
|
||||
}
|
||||
|
||||
public override void SendErrorMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendInfoMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendSuccessMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendWarningMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendMessage(string msg, Color color)
|
||||
{
|
||||
SendMessage(msg, color.R, color.G, color.B);
|
||||
}
|
||||
|
||||
public override void SendMessage(string msg, byte red, byte green, byte blue)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
}
|
||||
|
||||
public void SetFullMoon()
|
||||
{
|
||||
Main.dayTime = false;
|
||||
Main.moonPhase = 0;
|
||||
Main.time = 0.0;
|
||||
TSPlayer.All.SendData(PacketTypes.WorldInfo);
|
||||
}
|
||||
|
||||
public void SetBloodMoon(bool bloodMoon)
|
||||
{
|
||||
if (bloodMoon)
|
||||
{
|
||||
Main.dayTime = false;
|
||||
Main.bloodMoon = true;
|
||||
Main.time = 0.0;
|
||||
}
|
||||
else
|
||||
Main.bloodMoon = false;
|
||||
TSPlayer.All.SendData(PacketTypes.WorldInfo);
|
||||
}
|
||||
|
||||
public void SetFrostMoon(bool snowMoon)
|
||||
{
|
||||
if (snowMoon)
|
||||
{
|
||||
Main.dayTime = false;
|
||||
Main.snowMoon = true;
|
||||
Main.time = 0.0;
|
||||
}
|
||||
else
|
||||
Main.snowMoon = false;
|
||||
TSPlayer.All.SendData(PacketTypes.WorldInfo);
|
||||
}
|
||||
|
||||
public void SetPumpkinMoon(bool pumpkinMoon)
|
||||
{
|
||||
if (pumpkinMoon)
|
||||
{
|
||||
Main.dayTime = false;
|
||||
Main.pumpkinMoon = true;
|
||||
Main.time = 0.0;
|
||||
}
|
||||
else
|
||||
Main.pumpkinMoon = false;
|
||||
TSPlayer.All.SendData(PacketTypes.WorldInfo);
|
||||
}
|
||||
|
||||
public void SetEclipse(bool eclipse)
|
||||
{
|
||||
if (eclipse)
|
||||
{
|
||||
Main.dayTime = Main.eclipse = true;
|
||||
Main.time = 0.0;
|
||||
}
|
||||
else
|
||||
Main.eclipse = false;
|
||||
TSPlayer.All.SendData(PacketTypes.WorldInfo);
|
||||
}
|
||||
|
||||
public void SetTime(bool dayTime, double time)
|
||||
{
|
||||
Main.dayTime = dayTime;
|
||||
Main.time = time;
|
||||
TSPlayer.All.SendData(PacketTypes.TimeSet, "", dayTime ? 1 : 0, (int)time, Main.sunModY, Main.moonModY);
|
||||
}
|
||||
|
||||
public void SpawnNPC(int type, string name, int amount, int startTileX, int startTileY, int tileXRange = 100,
|
||||
int tileYRange = 50)
|
||||
{
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
int spawnTileX;
|
||||
int spawnTileY;
|
||||
TShock.Utils.GetRandomClearTileWithInRange(startTileX, startTileY, tileXRange, tileYRange, out spawnTileX,
|
||||
out spawnTileY);
|
||||
int npcid = NPC.NewNPC(spawnTileX * 16, spawnTileY * 16, type, 0);
|
||||
// This is for special slimes
|
||||
Main.npc[npcid].SetDefaults(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void StrikeNPC(int npcid, int damage, float knockBack, int hitDirection)
|
||||
{
|
||||
// Main.rand is thread static.
|
||||
if (Main.rand == null)
|
||||
Main.rand = new Random();
|
||||
|
||||
Main.npc[npcid].StrikeNPC(damage, knockBack, hitDirection);
|
||||
NetMessage.SendData((int)PacketTypes.NpcStrike, -1, -1, "", npcid, damage, knockBack, hitDirection);
|
||||
}
|
||||
|
||||
public void RevertTiles(Dictionary<Vector2, Tile> tiles)
|
||||
{
|
||||
// Update Main.Tile first so that when tile sqaure is sent it is correct
|
||||
foreach (KeyValuePair<Vector2, Tile> entry in tiles)
|
||||
{
|
||||
Main.tile[(int)entry.Key.X, (int)entry.Key.Y] = entry.Value;
|
||||
}
|
||||
// Send all players updated tile sqaures
|
||||
foreach (Vector2 coords in tiles.Keys)
|
||||
{
|
||||
All.SendTileSquare((int)coords.X, (int)coords.Y, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -989,7 +989,7 @@ namespace TShockAPI
|
|||
string check = "none";
|
||||
foreach (Item item in player.TPlayer.inventory)
|
||||
{
|
||||
if (!player.Group.HasPermission(Permissions.ignorestackhackdetection) && (item.stack > item.maxStack || item.stack < 0) &&
|
||||
if (!player.HasPermission(Permissions.ignorestackhackdetection) && (item.stack > item.maxStack || item.stack < 0) &&
|
||||
item.type != 0)
|
||||
{
|
||||
check = "Remove item " + item.name + " (" + item.stack + ") exceeds max stack of " + item.maxStack;
|
||||
|
|
@ -1334,7 +1334,7 @@ namespace TShockAPI
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!tsplr.Group.HasPermission(Permissions.canchat))
|
||||
if (!tsplr.HasPermission(Permissions.canchat))
|
||||
{
|
||||
args.Handled = true;
|
||||
}
|
||||
|
|
@ -1652,7 +1652,7 @@ namespace TShockAPI
|
|||
/// <returns>bool - True if the player should not be able to modify a tile.</returns>
|
||||
public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY, short tileType, GetDataHandlers.EditAction actionType)
|
||||
{
|
||||
if (!player.Group.HasPermission(Permissions.canbuild))
|
||||
if (!player.HasPermission(Permissions.canbuild))
|
||||
{
|
||||
if (TShock.Config.AllowIce && actionType != GetDataHandlers.EditAction.PlaceTile)
|
||||
{
|
||||
|
|
@ -1687,7 +1687,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!player.Group.HasPermission(Permissions.editregion) && !Regions.CanBuild(tileX, tileY, player) &&
|
||||
if (!player.HasPermission(Permissions.editregion) && !Regions.CanBuild(tileX, tileY, player) &&
|
||||
Regions.InArea(tileX, tileY))
|
||||
{
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000)
|
||||
|
|
@ -1700,7 +1700,7 @@ namespace TShockAPI
|
|||
|
||||
if (Config.DisableBuild)
|
||||
{
|
||||
if (!player.Group.HasPermission(Permissions.antibuild))
|
||||
if (!player.HasPermission(Permissions.antibuild))
|
||||
{
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.WPm) > 2000)
|
||||
{
|
||||
|
|
@ -1713,7 +1713,7 @@ namespace TShockAPI
|
|||
|
||||
if (Config.SpawnProtection)
|
||||
{
|
||||
if (!player.Group.HasPermission(Permissions.editspawn))
|
||||
if (!player.HasPermission(Permissions.editspawn))
|
||||
{
|
||||
if (CheckSpawn(tileX, tileY))
|
||||
{
|
||||
|
|
@ -1737,8 +1737,8 @@ namespace TShockAPI
|
|||
/// <returns>bool - True if the player should not be able to modify the tile.</returns>
|
||||
public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY, bool paint = false)
|
||||
{
|
||||
if ((!paint && !player.Group.HasPermission(Permissions.canbuild)) ||
|
||||
(paint && !player.Group.HasPermission(Permissions.canpaint)))
|
||||
if ((!paint && !player.HasPermission(Permissions.canbuild)) ||
|
||||
(paint && !player.HasPermission(Permissions.canpaint)))
|
||||
{
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000)
|
||||
{
|
||||
|
|
@ -1755,7 +1755,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!player.Group.HasPermission(Permissions.editregion) && !Regions.CanBuild(tileX, tileY, player) &&
|
||||
if (!player.HasPermission(Permissions.editregion) && !Regions.CanBuild(tileX, tileY, player) &&
|
||||
Regions.InArea(tileX, tileY))
|
||||
{
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000)
|
||||
|
|
@ -1768,7 +1768,7 @@ namespace TShockAPI
|
|||
|
||||
if (Config.DisableBuild)
|
||||
{
|
||||
if (!player.Group.HasPermission(Permissions.antibuild))
|
||||
if (!player.HasPermission(Permissions.antibuild))
|
||||
{
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.WPm) > 2000)
|
||||
{
|
||||
|
|
@ -1781,7 +1781,7 @@ namespace TShockAPI
|
|||
|
||||
if (Config.SpawnProtection)
|
||||
{
|
||||
if (!player.Group.HasPermission(Permissions.editspawn))
|
||||
if (!player.HasPermission(Permissions.editspawn))
|
||||
{
|
||||
if (CheckSpawn(tileX, tileY))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@
|
|||
<Compile Include="Hooks\RegionHooks.cs" />
|
||||
<Compile Include="ILog.cs" />
|
||||
<Compile Include="NetItem.cs" />
|
||||
<Compile Include="PlayerData.cs" />
|
||||
<Compile Include="SqlLog.cs" />
|
||||
<Compile Include="TextLog.cs" />
|
||||
<Compile Include="PaginationTools.cs" />
|
||||
|
|
@ -137,6 +138,7 @@
|
|||
<Compile Include="Rest\SecureRest.cs" />
|
||||
<Compile Include="ServerSideCharacters\ServerSideConfig.cs" />
|
||||
<Compile Include="StatTracker.cs" />
|
||||
<Compile Include="TSServerPlayer.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="TShock.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
|
@ -193,7 +195,7 @@
|
|||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" BuildVersion_BuildAction="Both" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_StartDate="2011/6/17" BuildVersion_IncrementBeforeBuild="False" />
|
||||
<UserProperties BuildVersion_IncrementBeforeBuild="False" BuildVersion_StartDate="2011/6/17" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_BuildAction="Both" BuildVersion_UpdateFileVersion="True" BuildVersion_UpdateAssemblyVersion="True" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ namespace TShockAPI
|
|||
NotifyAdministrator(TSPlayer.Server, changes);
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
{
|
||||
if (player != null && player.Active && player.Group.HasPermission(Permissions.maintenance))
|
||||
if (player != null && player.Active && player.HasPermission(Permissions.maintenance))
|
||||
{
|
||||
NotifyAdministrator(player, changes);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ namespace TShockAPI
|
|||
TSPlayer.Server.SendMessage(log, color);
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
{
|
||||
if (player != null && player != excludedPlayer && player.Active && player.Group.HasPermission(Permissions.logs) &&
|
||||
if (player != null && player != excludedPlayer && player.Active && player.HasPermission(Permissions.logs) &&
|
||||
player.DisplayLogs && TShock.Config.DisableSpewLogs == false)
|
||||
player.SendMessage(log, color);
|
||||
}
|
||||
|
|
@ -610,7 +610,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (!player.ConnectionAlive)
|
||||
return true;
|
||||
if (force || !player.Group.HasPermission(Permissions.immunetokick))
|
||||
if (force || !player.HasPermission(Permissions.immunetokick))
|
||||
{
|
||||
string playerName = player.Name;
|
||||
player.SilentKickInProgress = silent;
|
||||
|
|
@ -642,7 +642,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (!player.ConnectionAlive)
|
||||
return true;
|
||||
if (force || !player.Group.HasPermission(Permissions.immunetoban))
|
||||
if (force || !player.HasPermission(Permissions.immunetoban))
|
||||
{
|
||||
string ip = player.IP;
|
||||
string uuid = player.UUID;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue