Merge remote-tracking branch 'origin/general-devel' into otapi3

This commit is contained in:
Lucas Nicodemus 2022-02-16 18:44:33 -08:00
commit 78169c87cb
11 changed files with 117 additions and 71 deletions

2
.github/FUNDING.yml vendored
View file

@ -1,2 +1,2 @@
# These are supported funding model platforms # These are supported funding model platforms
github: [DeathCradle, hakusaro, Stealownz, QuiCM] github: [SignatureBeef, hakusaro, Stealownz, QuiCM]

View file

@ -14,9 +14,11 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
## Upcoming changes ## Upcoming changes
* Added hook `GetDataHandlers.OnReleaseNpc` to handling ReleaseNPC packet and a bouncer to stops unregistered and logged out players on SSC servers from releasing critters NPC. The bouncer has additional filter to stops players who tried to release different critter using crafted packet, e.g. using bunny item to release golden bunny. (@tru321) * Added hook `GetDataHandlers.OnReleaseNpc` to handling ReleaseNPC packet and a bouncer to stops unregistered and logged out players on SSC servers from releasing critters NPC. The bouncer has additional filter to stops players who tried to release different critter using crafted packet, e.g. using bunny item to release golden bunny. (@tru321)
* Added filter in `GetDataHandlers.HandleCatchNpc` that stops unregistered and logged out players on SSC servers to catch critters. (@tru321) * Added filter in `GetDataHandlers.HandleCatchNpc` that stops unregistered and logged out players on SSC servers to catch critters. (@tru321)
## Upcoming changes
* Fixed rejection check inside of `HandlePaintTile` to account for the Paint Sprayer (or Architect Gizmo Pack) being inside your inventory, rather than on an accessory slot. (@drunderscore) * Fixed rejection check inside of `HandlePaintTile` to account for the Paint Sprayer (or Architect Gizmo Pack) being inside your inventory, rather than on an accessory slot. (@drunderscore)
* Added the lanterns night event to the `/worldevent` command. (@0x3fcf1bbd)
* Marked `TSPlayer.SendTileSquare` as deprecated, and created `TSPlayer.SendTileSquareCentered` that sends a tile square centered around the passed coordinates. (@0x3fcf1bbd)
* Added coordinates clamping to `TSPlayer.SendTileRect` so as to avoid OOBs. (@0x3fcf1bbd)
* Removed extraneous space causing build commands in README to fail. (@EtherTyper)
## TShock 4.5.12 ## TShock 4.5.12
* Fixed the ability to spawn Zenith projectile with non-original items. (@AgaSpace) * Fixed the ability to spawn Zenith projectile with non-original items. (@AgaSpace)

View file

@ -405,7 +405,7 @@ namespace TShockAPI
((action == EditAction.PlaceWall || action == EditAction.ReplaceWall) && editData >= Main.maxWallTypes)) ((action == EditAction.PlaceWall || action == EditAction.ReplaceWall) && editData >= Main.maxWallTypes))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from editData out of bounds {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from editData out of bounds {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -420,7 +420,7 @@ namespace TShockAPI
if (args.Player.Dead && TShock.Config.Settings.PreventDeadModification) if (args.Player.Dead && TShock.Config.Settings.PreventDeadModification)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (pdm) {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (pdm) {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -434,7 +434,7 @@ namespace TShockAPI
if (TShock.TileBans.TileIsBanned(editData, args.Player)) if (TShock.TileBans.TileIsBanned(editData, args.Player))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (tb) {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (tb) {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Player.SendErrorMessage("You do not have permission to place this tile."); args.Player.SendErrorMessage("You do not have permission to place this tile.");
args.Handled = true; args.Handled = true;
return; return;
@ -457,7 +457,7 @@ namespace TShockAPI
{ {
TShock.Log.ConsoleError("Bouncer / OnTileEdit rejected from (placestyle) {0} {1} {2} placeStyle: {3} expectedStyle: {4}", TShock.Log.ConsoleError("Bouncer / OnTileEdit rejected from (placestyle) {0} {1} {2} placeStyle: {3} expectedStyle: {4}",
args.Player.Name, action, editData, requestedPlaceStyle, actualItemPlaceStyle); args.Player.Name, action, editData, requestedPlaceStyle, actualItemPlaceStyle);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -468,7 +468,7 @@ namespace TShockAPI
{ {
TShock.Log.ConsoleError("Bouncer / OnTileEdit rejected from (placestyle) {0} {1} {2} placeStyle: {3} expectedStyle: {4}", TShock.Log.ConsoleError("Bouncer / OnTileEdit rejected from (placestyle) {0} {1} {2} placeStyle: {3} expectedStyle: {4}",
args.Player.Name, action, editData, requestedPlaceStyle, correctedPlaceStyle); args.Player.Name, action, editData, requestedPlaceStyle, correctedPlaceStyle);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -483,7 +483,7 @@ namespace TShockAPI
if (Main.tileAxe[tile.type] && ((args.Player.TPlayer.mount.Type != 8 && selectedItem.axe == 0) && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0)) if (Main.tileAxe[tile.type] && ((args.Player.TPlayer.mount.Type != 8 && selectedItem.axe == 0) && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (axe) {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (axe) {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -491,7 +491,7 @@ namespace TShockAPI
else if (Main.tileHammer[tile.type] && ((args.Player.TPlayer.mount.Type != 8 && selectedItem.hammer == 0) && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0)) else if (Main.tileHammer[tile.type] && ((args.Player.TPlayer.mount.Type != 8 && selectedItem.hammer == 0) && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (hammer) {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (hammer) {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -502,7 +502,7 @@ namespace TShockAPI
&& !Main.tileAxe[tile.type] && !Main.tileHammer[tile.type] && tile.wall == 0 && args.Player.TPlayer.mount.Type != 8 && selectedItem.pick == 0 && selectedItem.type != ItemID.GravediggerShovel && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0) && !Main.tileAxe[tile.type] && !Main.tileHammer[tile.type] && tile.wall == 0 && args.Player.TPlayer.mount.Type != 8 && selectedItem.pick == 0 && selectedItem.type != ItemID.GravediggerShovel && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (pick) {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (pick) {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -513,7 +513,7 @@ namespace TShockAPI
if (selectedItem.hammer == 0 && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0 && selectedItem.createWall == 0) if (selectedItem.hammer == 0 && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0 && selectedItem.createWall == 0)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (hammer2) {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (hammer2) {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -532,7 +532,7 @@ namespace TShockAPI
!p.Killed && Math.Abs((int)(Main.projectile[p.Index].position.X / 16f) - tileX) <= Math.Abs(Main.projectile[p.Index].velocity.X))) !p.Killed && Math.Abs((int)(Main.projectile[p.Index].position.X / 16f) - tileX) <= Math.Abs(Main.projectile[p.Index].velocity.X)))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (inconceivable rope coil) {0} {1} {2} selectedItem:{3} itemCreateTile:{4}", args.Player.Name, action, editData, selectedItem.netID, selectedItem.createTile); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (inconceivable rope coil) {0} {1} {2} selectedItem:{3} itemCreateTile:{4}", args.Player.Name, action, editData, selectedItem.netID, selectedItem.createTile);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -543,7 +543,7 @@ namespace TShockAPI
requestedPlaceStyle > GetMaxPlaceStyle(editData)) requestedPlaceStyle > GetMaxPlaceStyle(editData))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (ms1) {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (ms1) {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -552,7 +552,7 @@ namespace TShockAPI
if (selectedItem.netID == ItemID.IceRod && editData != TileID.MagicalIceBlock) if (selectedItem.netID == ItemID.IceRod && editData != TileID.MagicalIceBlock)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from using ice rod but not placing ice block {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from using ice rod but not placing ice block {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
} }
/// If they aren't selecting the item which creates the tile, they're hacking. /// If they aren't selecting the item which creates the tile, they're hacking.
@ -562,7 +562,7 @@ namespace TShockAPI
if (selectedItem.netID != ItemID.IceRod && selectedItem.netID != ItemID.DirtBomb && selectedItem.netID != ItemID.StickyBomb) if (selectedItem.netID != ItemID.IceRod && selectedItem.netID != ItemID.DirtBomb && selectedItem.netID != ItemID.StickyBomb)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from tile placement not matching selected item createTile {0} {1} {2} selectedItemID:{3} createTile:{4}", args.Player.Name, action, editData, selectedItem.netID, selectedItem.createTile); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from tile placement not matching selected item createTile {0} {1} {2} selectedItemID:{3} createTile:{4}", args.Player.Name, action, editData, selectedItem.netID, selectedItem.createTile);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -571,7 +571,7 @@ namespace TShockAPI
if ((action == EditAction.PlaceWall || action == EditAction.ReplaceWall) && editData != selectedItem.createWall) if ((action == EditAction.PlaceWall || action == EditAction.ReplaceWall) && editData != selectedItem.createWall)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from wall placement not matching selected item createWall {0} {1} {2} selectedItemID:{3} createWall:{4}", args.Player.Name, action, editData, selectedItem.netID, selectedItem.createWall); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from wall placement not matching selected item createWall {0} {1} {2} selectedItemID:{3} createWall:{4}", args.Player.Name, action, editData, selectedItem.netID, selectedItem.createWall);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -581,7 +581,7 @@ namespace TShockAPI
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (chestcap) {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (chestcap) {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendErrorMessage("The world's chest limit has been reached - unable to place more."); args.Player.SendErrorMessage("The world's chest limit has been reached - unable to place more.");
args.Player.SendTileSquare(tileX, tileY, 3); args.Player.SendTileSquareCentered(tileX, tileY, 3);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -599,7 +599,7 @@ namespace TShockAPI
&& selectedItem.type != ItemID.WireKite) && selectedItem.type != ItemID.WireKite)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from place wire from {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from place wire from {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -613,7 +613,7 @@ namespace TShockAPI
&& selectedItem.type != ItemID.MulticolorWrench) && selectedItem.type != ItemID.MulticolorWrench)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from wire cutter from {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from wire cutter from {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -624,7 +624,7 @@ namespace TShockAPI
if (selectedItem.type != ItemID.Actuator && !args.Player.TPlayer.autoActuator) if (selectedItem.type != ItemID.Actuator && !args.Player.TPlayer.autoActuator)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from actuator/presserator from {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from actuator/presserator from {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -634,7 +634,7 @@ namespace TShockAPI
if (action == EditAction.KillWall || action == EditAction.ReplaceWall) if (action == EditAction.KillWall || action == EditAction.ReplaceWall)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from sts allow cut from {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from sts allow cut from {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -645,7 +645,7 @@ namespace TShockAPI
if (args.Player.IsBeingDisabled()) if (args.Player.IsBeingDisabled())
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from disable from {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from disable from {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -684,7 +684,7 @@ namespace TShockAPI
} }
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from explosives/fuses from {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from explosives/fuses from {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -698,7 +698,7 @@ namespace TShockAPI
else else
{ {
args.Player.Disable("Reached TileKill threshold.", DisableFlags.WriteToLogAndConsole); args.Player.Disable("Reached TileKill threshold.", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
} }
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from tile kill threshold from {0}, (value: {1})", args.Player.Name, args.Player.TileKillThreshold); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from tile kill threshold from {0}, (value: {1})", args.Player.Name, args.Player.TileKillThreshold);
@ -716,7 +716,7 @@ namespace TShockAPI
else else
{ {
args.Player.Disable("Reached TilePlace threshold.", DisableFlags.WriteToLogAndConsole); args.Player.Disable("Reached TilePlace threshold.", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
} }
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from tile place threshold from {0}, (value: {1})", args.Player.Name, args.Player.TilePlaceThreshold); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from tile place threshold from {0}, (value: {1})", args.Player.Name, args.Player.TilePlaceThreshold);
@ -728,7 +728,7 @@ namespace TShockAPI
if (args.Player.IsBouncerThrottled()) if (args.Player.IsBouncerThrottled())
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from throttled from {0} {1} {2}", args.Player.Name, action, editData); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from throttled from {0} {1} {2}", args.Player.Name, action, editData);
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -762,7 +762,7 @@ namespace TShockAPI
{ {
TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from weird confusing flow control from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from weird confusing flow control from {0}", args.Player.Name);
TShock.Log.ConsoleDebug("If you're seeing this message and you know what that player did, please report it to TShock for further investigation."); TShock.Log.ConsoleDebug("If you're seeing this message and you know what that player did, please report it to TShock for further investigation.");
args.Player.SendTileSquare(tileX, tileY, 4); args.Player.SendTileSquareCentered(tileX, tileY, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1317,7 +1317,7 @@ namespace TShockAPI
if (args.Player.IsBeingDisabled()) if (args.Player.IsBeingDisabled())
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from disabled from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from disabled from {0}", args.Player.Name);
args.Player.SendTileSquare(tileX, tileY, 3); args.Player.SendTileSquareCentered(tileX, tileY, 3);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1325,7 +1325,7 @@ namespace TShockAPI
if (args.Player.SelectedItem.placeStyle != style) if (args.Player.SelectedItem.placeStyle != style)
{ {
TShock.Log.ConsoleError(string.Format("Bouncer / OnPlaceChest / rejected from invalid place style from {0}", args.Player.Name)); TShock.Log.ConsoleError(string.Format("Bouncer / OnPlaceChest / rejected from invalid place style from {0}", args.Player.Name));
args.Player.SendTileSquare(tileX, tileY, 3); args.Player.SendTileSquareCentered(tileX, tileY, 3);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1337,7 +1337,7 @@ namespace TShockAPI
&& (!TShock.Utils.HasWorldReachedMaxChests() && Main.tile[tileX, tileY].type != TileID.Dirt)) //Chest && (!TShock.Utils.HasWorldReachedMaxChests() && Main.tile[tileX, tileY].type != TileID.Dirt)) //Chest
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from weird check from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from weird check from {0}", args.Player.Name);
args.Player.SendTileSquare(tileX, tileY, 3); args.Player.SendTileSquareCentered(tileX, tileY, 3);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1349,7 +1349,7 @@ namespace TShockAPI
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from weird placement check from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from weird placement check from {0}", args.Player.Name);
//Prevent a dresser from being placed on a teleporter, as this can cause client and server crashes. //Prevent a dresser from being placed on a teleporter, as this can cause client and server crashes.
args.Player.SendTileSquare(tileX, tileY, 3); args.Player.SendTileSquareCentered(tileX, tileY, 3);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1358,7 +1358,7 @@ namespace TShockAPI
if (!args.Player.HasBuildPermission(tileX, tileY)) if (!args.Player.HasBuildPermission(tileX, tileY))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from invalid permission from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from invalid permission from {0}", args.Player.Name);
args.Player.SendTileSquare(tileX, tileY, 3); args.Player.SendTileSquareCentered(tileX, tileY, 3);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1366,7 +1366,7 @@ namespace TShockAPI
if (!args.Player.IsInRange(tileX, tileY)) if (!args.Player.IsInRange(tileX, tileY))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from range check from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from range check from {0}", args.Player.Name);
args.Player.SendTileSquare(tileX, tileY, 3); args.Player.SendTileSquareCentered(tileX, tileY, 3);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1451,7 +1451,7 @@ namespace TShockAPI
if (args.Player.IsBeingDisabled()) if (args.Player.IsBeingDisabled())
{ {
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected disabled from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected disabled from {0}", args.Player.Name);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1465,7 +1465,7 @@ namespace TShockAPI
else else
{ {
args.Player.Disable("Reached TileLiquid threshold.", DisableFlags.WriteToLogAndConsole); args.Player.Disable("Reached TileLiquid threshold.", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
} }
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected from liquid threshold from {0} {1}/{2}", args.Player.Name, args.Player.TileLiquidThreshold, TShock.Config.Settings.TileLiquidThreshold); TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected from liquid threshold from {0} {1}/{2}", args.Player.Name, args.Player.TileLiquidThreshold, TShock.Config.Settings.TileLiquidThreshold);
@ -1538,7 +1538,7 @@ namespace TShockAPI
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 1 from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 1 from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.SendErrorMessage("You do not have permission to perform this action.");
args.Player.Disable("Spreading lava without holding a lava bucket", DisableFlags.WriteToLogAndConsole); args.Player.Disable("Spreading lava without holding a lava bucket", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1548,7 +1548,7 @@ namespace TShockAPI
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected lava bucket from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected lava bucket from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.SendErrorMessage("You do not have permission to perform this action.");
args.Player.Disable("Using banned lava bucket without permissions", DisableFlags.WriteToLogAndConsole); args.Player.Disable("Using banned lava bucket without permissions", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1558,7 +1558,7 @@ namespace TShockAPI
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 2 from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 2 from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.SendErrorMessage("You do not have permission to perform this action.");
args.Player.Disable("Spreading water without holding a water bucket", DisableFlags.WriteToLogAndConsole); args.Player.Disable("Spreading water without holding a water bucket", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1568,7 +1568,7 @@ namespace TShockAPI
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 3 from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 3 from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.SendErrorMessage("You do not have permission to perform this action.");
args.Player.Disable("Using banned water bucket without permissions", DisableFlags.WriteToLogAndConsole); args.Player.Disable("Using banned water bucket without permissions", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1578,7 +1578,7 @@ namespace TShockAPI
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 4 from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 4 from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.SendErrorMessage("You do not have permission to perform this action.");
args.Player.Disable("Spreading honey without holding a honey bucket", DisableFlags.WriteToLogAndConsole); args.Player.Disable("Spreading honey without holding a honey bucket", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1588,7 +1588,7 @@ namespace TShockAPI
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 5 from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 5 from {0}", args.Player.Name);
args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.SendErrorMessage("You do not have permission to perform this action.");
args.Player.Disable("Using banned honey bucket without permissions", DisableFlags.WriteToLogAndConsole); args.Player.Disable("Using banned honey bucket without permissions", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1597,7 +1597,7 @@ namespace TShockAPI
if (!args.Player.HasBuildPermission(tileX, tileY)) if (!args.Player.HasBuildPermission(tileX, tileY))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected build permission from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected build permission from {0}", args.Player.Name);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1605,7 +1605,7 @@ namespace TShockAPI
if (!wasThereABombNearby && !args.Player.IsInRange(tileX, tileY, 16)) if (!wasThereABombNearby && !args.Player.IsInRange(tileX, tileY, 16))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected range checks from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected range checks from {0}", args.Player.Name);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1613,7 +1613,7 @@ namespace TShockAPI
if (args.Player.IsBouncerThrottled()) if (args.Player.IsBouncerThrottled())
{ {
TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected throttle from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected throttle from {0}", args.Player.Name);
args.Player.SendTileSquare(tileX, tileY, 1); args.Player.SendTileSquareCentered(tileX, tileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1925,7 +1925,7 @@ namespace TShockAPI
if (type == TileID.FakeContainers && (style == 52 || style == 53)) if (type == TileID.FakeContainers && (style == 52 || style == 53))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected fake containers from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected fake containers from {0}", args.Player.Name);
args.Player.SendTileSquare(x, y, 4); args.Player.SendTileSquareCentered(x, y, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1934,7 +1934,7 @@ namespace TShockAPI
if (TShock.TileBans.TileIsBanned(type, args.Player)) if (TShock.TileBans.TileIsBanned(type, args.Player))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected banned tiles from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected banned tiles from {0}", args.Player.Name);
args.Player.SendTileSquare(x, y, 1); args.Player.SendTileSquareCentered(x, y, 1);
args.Player.SendErrorMessage("You do not have permission to place this tile."); args.Player.SendErrorMessage("You do not have permission to place this tile.");
args.Handled = true; args.Handled = true;
return; return;
@ -1943,7 +1943,7 @@ namespace TShockAPI
if (args.Player.Dead && TShock.Config.Settings.PreventDeadModification) if (args.Player.Dead && TShock.Config.Settings.PreventDeadModification)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected dead people don't do things from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected dead people don't do things from {0}", args.Player.Name);
args.Player.SendTileSquare(x, y, 4); args.Player.SendTileSquareCentered(x, y, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1951,7 +1951,7 @@ namespace TShockAPI
if (args.Player.IsBeingDisabled()) if (args.Player.IsBeingDisabled())
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected disabled from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected disabled from {0}", args.Player.Name);
args.Player.SendTileSquare(x, y, 4); args.Player.SendTileSquareCentered(x, y, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1962,7 +1962,7 @@ namespace TShockAPI
if (type != args.Player.TPlayer.inventory[args.Player.TPlayer.selectedItem].createTile) if (type != args.Player.TPlayer.inventory[args.Player.TPlayer.selectedItem].createTile)
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected awkward tile creation/selection from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected awkward tile creation/selection from {0}", args.Player.Name);
args.Player.SendTileSquare(x, y, 4); args.Player.SendTileSquareCentered(x, y, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1986,7 +1986,7 @@ namespace TShockAPI
&& !args.Player.HasBuildPermission(i, j)) && !args.Player.HasBuildPermission(i, j))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected mad loop from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected mad loop from {0}", args.Player.Name);
args.Player.SendTileSquare(i, j, 4); args.Player.SendTileSquareCentered(i, j, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -2002,7 +2002,7 @@ namespace TShockAPI
&& !args.Player.IsInRange(x, y)) && !args.Player.IsInRange(x, y))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected range checks from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected range checks from {0}", args.Player.Name);
args.Player.SendTileSquare(x, y, 4); args.Player.SendTileSquareCentered(x, y, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -2011,7 +2011,7 @@ namespace TShockAPI
{ {
TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected tile place threshold from {0} {1}/{2}", args.Player.Name, args.Player.TilePlaceThreshold, TShock.Config.Settings.TilePlaceThreshold); TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected tile place threshold from {0} {1}/{2}", args.Player.Name, args.Player.TilePlaceThreshold, TShock.Config.Settings.TilePlaceThreshold);
args.Player.Disable("Reached TilePlace threshold.", DisableFlags.WriteToLogAndConsole); args.Player.Disable("Reached TilePlace threshold.", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(x, y, 4); args.Player.SendTileSquareCentered(x, y, 4);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -2409,7 +2409,7 @@ namespace TShockAPI
if ((args.Player.SelectedItem.type != args.ItemID && args.Player.ItemInHand.type != args.ItemID)) if ((args.Player.SelectedItem.type != args.ItemID && args.Player.ItemInHand.type != args.ItemID))
{ {
TShock.Log.ConsoleDebug("Bouncer / OnFoodPlatterTryPlacing rejected item not placed by hand from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnFoodPlatterTryPlacing rejected item not placed by hand from {0}", args.Player.Name);
args.Player.SendTileSquare(args.TileX, args.TileY, 1); args.Player.SendTileSquareCentered(args.TileX, args.TileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -2419,7 +2419,7 @@ namespace TShockAPI
Item item = new Item(); Item item = new Item();
item.netDefaults(args.ItemID); item.netDefaults(args.ItemID);
args.Player.GiveItemCheck(args.ItemID, item.Name, args.Stack, args.Prefix); args.Player.GiveItemCheck(args.ItemID, item.Name, args.Stack, args.Prefix);
args.Player.SendTileSquare(args.TileX, args.TileY, 1); args.Player.SendTileSquareCentered(args.TileX, args.TileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -2430,7 +2430,7 @@ namespace TShockAPI
Item item = new Item(); Item item = new Item();
item.netDefaults(args.ItemID); item.netDefaults(args.ItemID);
args.Player.GiveItemCheck(args.ItemID, item.Name, args.Stack, args.Prefix); args.Player.GiveItemCheck(args.ItemID, item.Name, args.Stack, args.Prefix);
args.Player.SendTileSquare(args.TileX, args.TileY, 1); args.Player.SendTileSquareCentered(args.TileX, args.TileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -2438,7 +2438,7 @@ namespace TShockAPI
if (!args.Player.IsInRange(args.TileX, args.TileY, range: 13)) // To my knowledge, max legit tile reach with accessories. if (!args.Player.IsInRange(args.TileX, args.TileY, range: 13)) // To my knowledge, max legit tile reach with accessories.
{ {
TShock.Log.ConsoleDebug("Bouncer / OnFoodPlatterTryPlacing rejected range checks from {0}", args.Player.Name); TShock.Log.ConsoleDebug("Bouncer / OnFoodPlatterTryPlacing rejected range checks from {0}", args.Player.Name);
args.Player.SendTileSquare(args.TileX, args.TileY, 1); args.Player.SendTileSquareCentered(args.TileX, args.TileY, 1);
args.Handled = true; args.Handled = true;
return; return;
} }

View file

@ -2059,7 +2059,8 @@ namespace TShockAPI
"eclipse", "eclipse",
"invasion", "invasion",
"sandstorm", "sandstorm",
"rain" "rain",
"lanternsnight"
}; };
static readonly List<string> _validInvasions = new List<string>() static readonly List<string> _validInvasions = new List<string>()
{ {
@ -2158,6 +2159,16 @@ namespace TShockAPI
Rain(args); Rain(args);
return; return;
case "lanternsnight":
case "lanterns":
if (!args.Player.HasPermission(Permissions.managelanternsnightevent))
{
FailedPermissionCheck();
return;
}
LanternsNight(args);
return;
default: default:
args.Player.SendErrorMessage("Invalid event type! Valid event types: {0}", String.Join(", ", _validEvents)); args.Player.SendErrorMessage("Invalid event type! Valid event types: {0}", String.Join(", ", _validEvents));
return; return;
@ -2373,6 +2384,20 @@ namespace TShockAPI
} }
} }
private static void LanternsNight(CommandArgs args)
{
LanternNight.ToggleManualLanterns();
string msg = $" st{(LanternNight.LanternsUp ? "art" : "opp")}ed a lantern night.";
if (args.Silent)
{
args.Player.SendInfoMessage("You" + msg);
}
else
{
TSPlayer.All.SendInfoMessage(args.Player.Name + msg);
}
}
private static void ClearAnglerQuests(CommandArgs args) private static void ClearAnglerQuests(CommandArgs args)
{ {
if (args.Parameters.Count > 0) if (args.Parameters.Count > 0)
@ -4873,7 +4898,7 @@ namespace TShockAPI
try try
{ {
args.Player.SendTileSquare(boundaryPoint.X, boundaryPoint.Y, 1); args.Player.SendTileSquareCentered(boundaryPoint.X, boundaryPoint.Y, 1);
} }
finally finally
{ {
@ -4887,7 +4912,7 @@ namespace TShockAPI
{ {
foreach (Point boundaryPoint in Utils.Instance.EnumerateRegionBoundaries(regionArea)) foreach (Point boundaryPoint in Utils.Instance.EnumerateRegionBoundaries(regionArea))
if ((boundaryPoint.X + boundaryPoint.Y & 1) == 0) if ((boundaryPoint.X + boundaryPoint.Y & 1) == 0)
args.Player.SendTileSquare(boundaryPoint.X, boundaryPoint.Y, 1); args.Player.SendTileSquareCentered(boundaryPoint.X, boundaryPoint.Y, 1);
Debug.Assert(boundaryHideTimer != null); Debug.Assert(boundaryHideTimer != null);
boundaryHideTimer.Dispose(); boundaryHideTimer.Dispose();
@ -5644,7 +5669,7 @@ namespace TShockAPI
private static void SyncLocalArea(CommandArgs args) private static void SyncLocalArea(CommandArgs args)
{ {
args.Player.SendTileSquare((int) args.Player.TileX, (int) args.Player.TileY, 32); args.Player.SendTileSquareCentered(args.Player.TileX, args.Player.TileY, 32);
args.Player.SendWarningMessage("Sync'd!"); args.Player.SendWarningMessage("Sync'd!");
return; return;
} }
@ -6650,7 +6675,7 @@ namespace TShockAPI
} }
if (args.Parameters.Count == 1) if (args.Parameters.Count == 1)
{ {
args.Player.SendTileSquare(x - 2, y - 20, 25); args.Player.SendTileSquareCentered(x - 2, y - 20, 25);
args.Player.SendSuccessMessage("Tried to grow a " + name + "."); args.Player.SendSuccessMessage("Tried to grow a " + name + ".");
} }
} }

View file

@ -3894,7 +3894,7 @@ namespace TShockAPI
if (TShock.TileBans.TileIsBanned((short)TileID.LogicSensor, args.Player)) if (TShock.TileBans.TileIsBanned((short)TileID.LogicSensor, args.Player))
{ {
args.Player.SendTileSquare(x, y, 1); args.Player.SendTileSquareCentered(x, y, 1);
args.Player.SendErrorMessage("You do not have permission to place Logic Sensors."); args.Player.SendErrorMessage("You do not have permission to place Logic Sensors.");
return true; return true;
} }

View file

@ -198,7 +198,7 @@ namespace TShockAPI
{ {
if (args.Player.TPlayer.autoActuator && DataModel.ItemIsBanned("Actuator", args.Player)) if (args.Player.TPlayer.autoActuator && DataModel.ItemIsBanned("Actuator", args.Player))
{ {
args.Player.SendTileSquare(args.X, args.Y, 1); args.Player.SendTileSquareCentered(args.X, args.Y, 1);
args.Player.SendErrorMessage("You do not have permission to place actuators."); args.Player.SendErrorMessage("You do not have permission to place actuators.");
args.Handled = true; args.Handled = true;
return; return;
@ -206,7 +206,7 @@ namespace TShockAPI
if (DataModel.ItemIsBanned(EnglishLanguage.GetItemNameById(args.Player.SelectedItem.netID), args.Player)) if (DataModel.ItemIsBanned(EnglishLanguage.GetItemNameById(args.Player.SelectedItem.netID), args.Player))
{ {
args.Player.SendTileSquare(args.X, args.Y, 4); args.Player.SendTileSquareCentered(args.X, args.Y, 4);
args.Handled = true; args.Handled = true;
return; return;
} }

View file

@ -307,6 +307,9 @@ namespace TShockAPI
[Description("User can use the 'rain' subcommand of the 'worldevent' command")] [Description("User can use the 'rain' subcommand of the 'worldevent' command")]
public static readonly string managerainevent = "tshock.world.events.rain"; public static readonly string managerainevent = "tshock.world.events.rain";
[Description("User can use the 'lanternsnight' subcommand of the 'worldevent' command")]
public static readonly string managelanternsnightevent = "tshock.world.events.lanternsnight";
[Description("User can change expert state.")] [Description("User can change expert state.")]
public static readonly string toggleexpert = "tshock.world.toggleexpert"; public static readonly string toggleexpert = "tshock.world.toggleexpert";

View file

@ -171,7 +171,7 @@ namespace TShockAPI
} }
// Revert all tile changes and handle the event // Revert all tile changes and handle the event
player.SendTileSquare(e.X, e.Y, 4); player.SendTileSquareCentered(e.X, e.Y, 4);
e.Handled = true; e.Handled = true;
} }
@ -190,7 +190,7 @@ namespace TShockAPI
player.AwaitingTempPoint = 0; player.AwaitingTempPoint = 0;
// Revert all tile changes and handle the event // Revert all tile changes and handle the event
player.SendTileSquare(e.X, e.Y, 4); player.SendTileSquareCentered(e.X, e.Y, 4);
e.Handled = true; e.Handled = true;
} }

View file

@ -1226,7 +1226,7 @@ namespace TShockAPI
y = 992; y = 992;
} }
SendTileSquare((int)(x / 16), (int)(y / 16), 15); SendTileSquareCentered((int)(x / 16), (int)(y / 16), 15);
TPlayer.Teleport(new Vector2(x, y), style); TPlayer.Teleport(new Vector2(x, y), style);
NetMessage.SendData((int)PacketTypes.Teleport, -1, -1, NetworkText.Empty, 0, TPlayer.whoAmI, x, y, style); NetMessage.SendData((int)PacketTypes.Teleport, -1, -1, NetworkText.Empty, 0, TPlayer.whoAmI, x, y, style);
return true; return true;
@ -1308,11 +1308,27 @@ namespace TShockAPI
/// <param name="y">The y coordinate to send.</param> /// <param name="y">The y coordinate to send.</param>
/// <param name="size">The size square set of tiles to send.</param> /// <param name="size">The size square set of tiles to send.</param>
/// <returns>true if the tile square was sent successfully, else false</returns> /// <returns>true if the tile square was sent successfully, else false</returns>
[Obsolete("This method may not send tiles the way you would expect it to. The (x,y) coordinates are the top left corner of the tile square, switch to " + nameof(SendTileSquareCentered) + " if you wish for the coordindates to be the center of the square.")]
public virtual bool SendTileSquare(int x, int y, int size = 10) public virtual bool SendTileSquare(int x, int y, int size = 10)
{ {
return SendTileRect((short)x, (short)y, (byte)size, (byte)size); return SendTileRect((short)x, (short)y, (byte)size, (byte)size);
} }
/// <summary>
/// Sends a tile square at a center location with a given size.
/// Typically used to revert changes by Bouncer through sending the
/// "old" version of modified data back to a client.
/// Prevents desync issues.
/// </summary>
/// <param name="x">The x coordinates of the center of the square.</param>
/// <param name="y">The y coordinates of the center of the square.</param>
/// <param name="size">The size square set of tiles to send.</param>
/// <returns>true if the tile square was sent successfully, else false</returns>
public virtual bool SendTileSquareCentered(int x, int y, byte size = 10)
{
return SendTileRect((short)(x - (size / 2)), (short)(y - (size / 2)), size, size);
}
/// <summary> /// <summary>
/// Sends a rectangle of tiles at a location with the given length and width. /// Sends a rectangle of tiles at a location with the given length and width.
/// </summary> /// </summary>
@ -1347,7 +1363,7 @@ namespace TShockAPI
public bool GiveItemCheck(int type, string name, int stack, int prefix = 0) public bool GiveItemCheck(int type, string name, int stack, int prefix = 0)
{ {
if ((TShock.ItemBans.DataModel.ItemIsBanned(name) && TShock.Config.Settings.PreventBannedItemSpawn) && if ((TShock.ItemBans.DataModel.ItemIsBanned(name) && TShock.Config.Settings.PreventBannedItemSpawn) &&
(TShock.ItemBans.DataModel.ItemIsBanned(name, this) || !TShock.Config.Settings.AllowAllowedGroupsToSpawnBannedItems)) (TShock.ItemBans.DataModel.ItemIsBanned(name, this) || !TShock.Config.Settings.AllowAllowedGroupsToSpawnBannedItems))
return false; return false;
GiveItem(type, stack, prefix); GiveItem(type, stack, prefix);

View file

@ -189,7 +189,7 @@ namespace TShockAPI
// Send all players updated tile squares // Send all players updated tile squares
foreach (Vector2 coords in tiles.Keys) foreach (Vector2 coords in tiles.Keys)
{ {
All.SendTileSquare((int)coords.X, (int)coords.Y, 3); All.SendTileSquareCentered((int)coords.X, (int)coords.Y, 3);
} }
} }