diff --git a/CHANGELOG.md b/CHANGELOG.md index 92a4b9195..eb2270ddf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin ## Upcoming Changes * API: Fixed chat line breaks when using chat tags and long strings of text (@ProfessorXZ) +* API: Added ItemForceIntoChest hook (@WhiteXZ) * The setdungeon command correctly uses tshock.world.setdungeon as its permission (@OnsenManju) * Fixed clients being able to "Catch" and remove NPCs (@ProfessorXZ) * Fixed clients being able to remove other players' portals (@ProfessorXZ) @@ -14,6 +15,11 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Fixed a bug involving Item Frames which allowed players to duplicate items (@ProfessorXZ) * Fixed an issue allowing clients to teleport NPCs to arbitrary locations (@ProfessorXZ) * Fixed a bug where players would get teleported to their previous location after dismounting the Unicorn Mount (@ProfessorXZ) +* Players can no longer quick stack items into region protected chests (@ProfessorXZ) +* Rope placement is no longer blocked by range checks (@ProfessorXZ) +* The Drill Containment Unit breaks blocks properly now (@ProfessorXZ) +* Fixed Expert mode coin duplication (@ProfessorXZ) +* Players are no longer able to place liquids using LoadNetModule packet (@ProfessorXZ) ## TShock 4.3.17 diff --git a/TShockAPI/DB/RegionManager.cs b/TShockAPI/DB/RegionManager.cs index d63da396d..8e3b46d33 100755 --- a/TShockAPI/DB/RegionManager.cs +++ b/TShockAPI/DB/RegionManager.cs @@ -759,7 +759,7 @@ public bool HasPermissionToBuildInRegion(TSPlayer ply) return false; } - return AllowedIDs.Contains(ply.User.ID) || AllowedGroups.Contains(ply.Group.Name) || Owner == ply.User.Name; + return ply.HasPermission(Permissions.editregion) || AllowedIDs.Contains(ply.User.ID) || AllowedGroups.Contains(ply.Group.Name) || Owner == ply.User.Name; } /// diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs old mode 100755 new mode 100644 index 9a4a273ca..2e5e43baf --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -362,7 +362,7 @@ public class TileKillEventArgs : HandledEventArgs public int TileY { get; set; } } /// - /// TileKill - When a tile is removed fromt he world + /// TileKill - When a tile is removed from the world /// public static HandlerList TileKill; @@ -1259,6 +1259,8 @@ public static void InitGetDataHandler() { PacketTypes.KillPortal, HandleKillPortal }, { PacketTypes.PlaceTileEntity, HandlePlaceTileEntity }, { PacketTypes.PlaceItemFrame, HandlePlaceItemFrame }, + { PacketTypes.SyncExtraValue, HandleSyncExtraValue }, + { PacketTypes.LoadNetModule, HandleLoadNetModule }, { PacketTypes.ToggleParty, HandleToggleParty } }; } @@ -2013,7 +2015,7 @@ private static bool HandleTile(GetDataHandlerArgs args) return true; } // If the tile is a pickaxe tile and they aren't selecting a pickaxe, they're hacking. - else if ((!Main.tileAxe[tile.type] && !Main.tileHammer[tile.type]) && tile.wall == 0 && (selectedItem.pick == 0 && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0)) + else if ((!Main.tileAxe[tile.type] && !Main.tileHammer[tile.type]) && tile.wall == 0 && ((args.TPlayer.mount.Type != 8 && selectedItem.pick == 0) && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0)) { args.Player.SendTileSquare(tileX, tileY, 4); return true; @@ -2021,7 +2023,7 @@ private static bool HandleTile(GetDataHandlerArgs args) } else if (action == EditAction.KillWall) { - // If they aren't selecting an hammer, they could be hacking. + // If they aren't selecting a hammer, they could be hacking. if (selectedItem.hammer == 0 && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0 && selectedItem.createWall == 0) { @@ -2144,10 +2146,10 @@ private static bool HandleTile(GetDataHandlerArgs args) // Ignore rope placement range if ((editData != TileID.Rope - || editData != TileID.SilkRope - || editData != TileID.VineRope - || editData != TileID.WebRope - || action != EditAction.PlaceTile) + && editData != TileID.SilkRope + && editData != TileID.VineRope + && editData != TileID.WebRope + && action == EditAction.PlaceTile) && TShock.CheckRangePermission(args.Player, tileX, tileY)) { args.Player.SendTileSquare(tileX, tileY, 4); @@ -4203,6 +4205,36 @@ private static bool HandlePlaceItemFrame(GetDataHandlerArgs args) return false; } + private static bool HandleSyncExtraValue(GetDataHandlerArgs args) + { + var npcIndex = args.Data.ReadInt16(); + var extraValue = args.Data.ReadSingle(); + var position = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); + + if (position.X < 0 || position.X >= Main.maxTilesX || position.Y < 0 || position.Y >= Main.maxTilesY) + { + return true; + } + + if (!Main.expertMode) + { + return true; + } + + if (TShock.CheckRangePermission(args.Player, (int)position.X, (int)position.Y)) + { + return true; + } + + return false; + } + + private static bool HandleLoadNetModule(GetDataHandlerArgs args) + { + // Since this packet is never actually sent to us, every attempt at sending it can be considered as a liquid exploit attempt + return true; + } + private static bool HandleToggleParty(GetDataHandlerArgs args) { if (args.Player != null && !args.Player.HasPermission(Permissions.toggleparty)) diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 61ec05cb5..792a41608 100755 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -198,8 +198,14 @@ public Group Group /// public int LoginAttempts { get; set; } + /// + /// Unused. + /// public Vector2 TeleportCoords = new Vector2(-1, -1); + /// + /// The player's last known position from PlayerUpdate packet. + /// public Vector2 LastNetPosition = Vector2.Zero; /// @@ -247,6 +253,9 @@ public int UserID /// public bool HasBeenNaggedAboutLoggingIn; + /// + /// Whether other players can teleport to the player. + /// public bool TPAllow = true; /// @@ -435,7 +444,7 @@ public IEnumerable Accessories } /// - /// Saves the player's inventory to SSI + /// Saves the player's inventory to SSC /// /// bool - True/false if it saved successfully public bool SaveServerCharacter() @@ -534,7 +543,7 @@ public float Y } /// - /// Gets the player's X tile coordinate. + /// Player X coordinate divided by 16. Supposed X world coordinate. /// public int TileX { @@ -542,13 +551,16 @@ public int TileX } /// - /// Gets the player's Y tile coordinate. + /// Player Y cooridnate divided by 16. Supposed Y world coordinate. /// public int TileY { get { return (int) (Y/16); } } + /// + /// Unused. + /// public bool TpLock; /// @@ -630,6 +642,10 @@ public object RemoveData(string key) return null; } + /// + /// Initializes a new instance of the class. + /// + /// The player's index in the. public TSPlayer(int index) { TilesDestroyed = new Dictionary(); @@ -640,6 +656,10 @@ public TSPlayer(int index) AwaitingResponse = new Dictionary>(); } + /// + /// Initializes a new instance of the class. + /// + /// The player's name. protected TSPlayer(String playerName) { TilesDestroyed = new Dictionary(); @@ -686,7 +706,7 @@ public void TempGroupTimerElapsed(object sender, ElapsedEventArgs args) } /// - /// Teleports a player to the given coordinates in the world. + /// Teleports the player to the given coordinates in the world. /// /// The X coordinate. /// The Y coordinate. @@ -989,7 +1009,7 @@ public virtual void SendMessage(string msg, byte red, byte green, byte blue) } /// - /// Sends a message to a player with the specified RGB color. + /// Sends a message to the player with the specified RGB color. /// /// The message. /// The amount of red color to factor in. Max: 255. @@ -1116,6 +1136,10 @@ private void LogStackFrame() TShock.Log.Debug(frame.GetMethod().DeclaringType.Name + " called Disable()."); } + /// + /// Annoys the player for a specified amount of time. + /// + /// The public virtual void Whoopie(object time) { var time2 = (int) time; diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 538148761..cd1d72a5a 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -45,7 +45,7 @@ namespace TShockAPI /// This is the TShock main class. TShock is a plugin on the TerrariaServerAPI, so it extends the base TerrariaPlugin. /// TShock also complies with the API versioning system, and defines its required API version here. /// - [ApiVersion(1, 23)] + [ApiVersion(1, 24)] public class TShock : TerrariaPlugin { /// VersionNum - The version number the TerrariaAPI will return back to the API. We just use the Assembly info. @@ -55,7 +55,7 @@ public class TShock : TerrariaPlugin /// CNMode - 显示当前汉化版本信息. public static readonly string CNMode = "高级汉化-开发"; /// CNVersion - 显示当前汉化版本号. - public static readonly Version CNVersion = new Version(1, 2, 2, 0); + public static readonly Version CNVersion = new Version(1, 2, 3, 0); /// SavePath - This is the path TShock saves its data in. This path is relative to the TerrariaServer.exe (not in ServerPlugins). public static string SavePath = "tshock"; @@ -322,6 +322,7 @@ public override void Initialize() ServerApi.Hooks.WorldChristmasCheck.Register(this, OnXmasCheck); ServerApi.Hooks.WorldHalloweenCheck.Register(this, OnHalloweenCheck); ServerApi.Hooks.NetNameCollision.Register(this, NetHooks_NameCollision); + ServerApi.Hooks.ItemForceIntoChest.Register(this, OnItemForceIntoChest); Hooks.PlayerHooks.PlayerPreLogin += OnPlayerPreLogin; Hooks.PlayerHooks.PlayerPostLogin += OnPlayerLogin; Hooks.AccountHooks.AccountDelete += OnAccountDelete; @@ -389,6 +390,7 @@ protected override void Dispose(bool disposing) ServerApi.Hooks.WorldChristmasCheck.Deregister(this, OnXmasCheck); ServerApi.Hooks.WorldHalloweenCheck.Deregister(this, OnHalloweenCheck); ServerApi.Hooks.NetNameCollision.Deregister(this, NetHooks_NameCollision); + ServerApi.Hooks.ItemForceIntoChest.Deregister(this, OnItemForceIntoChest); TShockAPI.Hooks.PlayerHooks.PlayerPostLogin -= OnPlayerLogin; if (File.Exists(Path.Combine(SavePath, "tshock.pid"))) @@ -476,6 +478,44 @@ private void NetHooks_NameCollision(NameCollisionEventArgs args) } } + /// OnItemForceIntoChest - Internal hook fired when a player quick stacks items into a chest. + /// The object. + private void OnItemForceIntoChest(ForceItemIntoChestEventArgs args) + { + if (args.Handled) + { + return; + } + + if (args.Player == null) + { + args.Handled = true; + return; + } + + TSPlayer tsplr = Players[args.Player.whoAmI]; + if (tsplr == null) + { + args.Handled = true; + return; + } + + if (args.Chest != null) + { + if (Config.RegionProtectChests && !Regions.CanBuild((int)args.Position.X, (int)args.Position.Y, tsplr)) + { + args.Handled = true; + return; + } + + if (CheckRangePermission(tsplr, (int)args.Position.X, (int)args.Position.Y)) + { + args.Handled = true; + return; + } + } + } + /// OnXmasCheck - Internal hook fired when the XMasCheck happens. /// args - The ChristmasCheckEventArgs object. private void OnXmasCheck(ChristmasCheckEventArgs args) @@ -1705,8 +1745,7 @@ public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY, sh return true; } - if (!player.HasPermission(Permissions.editregion) && !Regions.CanBuild(tileX, tileY, player) && - Regions.InArea(tileX, tileY)) + if (!Regions.CanBuild(tileX, tileY, player)) { if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000) { @@ -1773,8 +1812,7 @@ public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY, bo return true; } - if (!player.HasPermission(Permissions.editregion) && !Regions.CanBuild(tileX, tileY, player) && - Regions.InArea(tileX, tileY)) + if (!Regions.CanBuild(tileX, tileY, player)) { if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000) { diff --git a/TerrariaServerAPI b/TerrariaServerAPI index 79db99008..f227f3954 160000 --- a/TerrariaServerAPI +++ b/TerrariaServerAPI @@ -1 +1 @@ -Subproject commit 79db99008df77df0ee0149805197be4b56b9b435 +Subproject commit f227f39541c90e73c201374aedcd2138b32a3b4a