From 8c1cf3c15ed337c56911f2ac5a09059c747d9651 Mon Sep 17 00:00:00 2001 From: Pia Mancini Date: Thu, 20 Apr 2017 11:45:15 -0400 Subject: [PATCH 001/430] Add backers and sponsors from Open Collective Now your open collective backers and sponsors can to appear directly on your README. see how it'll look [here](https://github.com/apex/apex#backers) [More info](https://github.com/opencollective/opencollective/wiki/Github-banner) Also add badges on top --- README.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/README.md b/README.md index b379295e..da702579 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@

+[![OpenCollective](https://opencollective.com/tshock/backers/badge.svg)](#backers) +[![OpenCollective](https://opencollective.com/tshock/sponsors/badge.svg)](#sponsors) + TShock is a server modification for Terraria, written in C#, and based upon the [Terraria Server API](https://github.com/NyxStudios/TerrariaAPI-Server). It uses JSON for configuration management, and offers several features not present in the Terraria Server normally. ## :star: Quick Start @@ -38,3 +41,73 @@ Please see the contributing file before sending pull requests. * [Development Builds](https://travis.tshock.co/) * [Plugins](https://tshock.co/xf/index.php?resources/) * [Very, very old versions of TShock](https://github.com/TShock/TShock/downloads) + +## Backers + +Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/tshock#backer)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Sponsors + +Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/tshock#sponsor)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 0e051d1e80b8f6faf4652b7b1a5b0cae781c2abd Mon Sep 17 00:00:00 2001 From: Hussein Farran Date: Mon, 15 May 2017 14:43:20 -0400 Subject: [PATCH 002/430] Changed Slack references to Discord So Deathmax can sleep easy --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6382cc88..01735e16 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ Note: This includes the API by default. If you need only the API, you need to cd - Run ```msbuild TShock.sln``` in the root of the cloned folder on Windows in a 'Developer Command Prompt' OR - Run ```xbuild TShock.sln``` in the root of the cloned folder on Unix. -Need help? Drop by Slack and we'll be happy to explain it with more words, step by step. +Need help? Drop by Discord and we'll be happy to explain it with more words, step by step. ### TShock Additions @@ -26,7 +26,7 @@ If something is better suited to be a plugin for TShock, rather than a TShock co _If you are confused, make a suggestion. We will determine scope and relevance for you._ -_If a person makes a suggestion in Slack, capture the suggestion as a Github issue. If a suggestion crops up on the forums, make a Github issue to capture it. If you want, direct the user to make a suggestion on Github, but set an alarm/timer/reminder so that if they don't know how to use Github or they don't have an account, an issue is still made and discussed. Make it clear that the issue is a surrogate issue for a suggestion from Slack/the forums too._ +_If a person makes a suggestion in Discord, capture the suggestion as a Github issue. If a suggestion crops up on the forums, make a Github issue to capture it. If you want, direct the user to make a suggestion on Github, but set an alarm/timer/reminder so that if they don't know how to use Github or they don't have an account, an issue is still made and discussed. Make it clear that the issue is a surrogate issue for a suggestion from Discord/the forums too._ ### Pull Request Dev Guidelines From 81e21f31dc9f68d4db77f15dbb207d2b3373cb63 Mon Sep 17 00:00:00 2001 From: death Date: Tue, 16 May 2017 22:41:27 +1000 Subject: [PATCH 003/430] Submodule update and new grass creep checks Pulls through the latest OTAPI to make use of the new WorldGrassSpread hook which should allow corruption/crimsion/hallow creep config options work. --- TShockAPI/TShock.cs | 44 ++++++++++++++++++++++++++++++++++++-------- TerrariaServerAPI | 2 +- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 0d1c2bc7..42cd9ef1 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -349,6 +349,7 @@ namespace TShockAPI ServerApi.Hooks.WorldHalloweenCheck.Register(this, OnHalloweenCheck); ServerApi.Hooks.NetNameCollision.Register(this, NetHooks_NameCollision); ServerApi.Hooks.ItemForceIntoChest.Register(this, OnItemForceIntoChest); + ServerApi.Hooks.WorldGrassSpread.Register(this, OnWorldGrassSpread); Hooks.PlayerHooks.PlayerPreLogin += OnPlayerPreLogin; Hooks.PlayerHooks.PlayerPostLogin += OnPlayerLogin; Hooks.AccountHooks.AccountDelete += OnAccountDelete; @@ -419,6 +420,7 @@ namespace TShockAPI ServerApi.Hooks.WorldHalloweenCheck.Deregister(this, OnHalloweenCheck); ServerApi.Hooks.NetNameCollision.Deregister(this, NetHooks_NameCollision); ServerApi.Hooks.ItemForceIntoChest.Deregister(this, OnItemForceIntoChest); + ServerApi.Hooks.WorldGrassSpread.Deregister(this, OnWorldGrassSpread); TShockAPI.Hooks.PlayerHooks.PlayerPostLogin -= OnPlayerLogin; if (File.Exists(Path.Combine(SavePath, "tshock.pid"))) @@ -1208,24 +1210,50 @@ namespace TShockAPI if (args.Handled) return; - if (!Config.AllowCrimsonCreep && (args.Type == TileID.Dirt || args.Type == TileID.FleshWeeds - || TileID.Sets.Crimson[args.Type])) + if (!OnCreep(args.Type)) { args.Handled = true; + } + } + + /// OnWorldGrassSpread - Fired when grass is attempting to spread. + /// args - The GrassSpreadEventArgs object. + private void OnWorldGrassSpread(GrassSpreadEventArgs args) + { + if (args.Handled) return; + + if(!OnCreep(args.Grass)) + { + args.Handled = true; + } + } + + /// + /// Checks if the tile type is allowed to creep + /// + /// Tile id + /// True if allowed, otherwise false + private bool OnCreep(int tileType) + { + if (!Config.AllowCrimsonCreep && (tileType == TileID.Dirt || tileType == TileID.FleshWeeds + || TileID.Sets.Crimson[tileType])) + { + return false; } - if (!Config.AllowCorruptionCreep && (args.Type == TileID.Dirt || args.Type == TileID.CorruptThorns - || TileID.Sets.Corrupt[args.Type])) + if (!Config.AllowCorruptionCreep && (tileType == TileID.Dirt || tileType == TileID.CorruptThorns + || TileID.Sets.Corrupt[tileType])) { - args.Handled = true; - return; + return false; } - if (!Config.AllowHallowCreep && (TileID.Sets.Hallow[args.Type])) + if (!Config.AllowHallowCreep && (TileID.Sets.Hallow[tileType])) { - args.Handled = true; + return false; } + + return true; } /// OnStatueSpawn - Fired when a statue spawns. diff --git a/TerrariaServerAPI b/TerrariaServerAPI index a9d1b0e4..d3b7d9f4 160000 --- a/TerrariaServerAPI +++ b/TerrariaServerAPI @@ -1 +1 @@ -Subproject commit a9d1b0e4e096ecbd0b2033ce4ff636759c9448c3 +Subproject commit d3b7d9f4575602f468cf1e009ebc4bc5b79547c4 From c841a86cdf7987a079f5665aa7608ca02f12ef99 Mon Sep 17 00:00:00 2001 From: Ruby Rose Date: Wed, 7 Jun 2017 10:46:46 +0300 Subject: [PATCH 004/430] hooks added --- TShockAPI/Hooks/PlayerHooks.cs | 158 +++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/TShockAPI/Hooks/PlayerHooks.cs b/TShockAPI/Hooks/PlayerHooks.cs index 43684387..062a78b8 100644 --- a/TShockAPI/Hooks/PlayerHooks.cs +++ b/TShockAPI/Hooks/PlayerHooks.cs @@ -18,6 +18,7 @@ along with this program. If not, see . using System.Collections.Generic; using System.ComponentModel; +using TShockAPI.DB; namespace TShockAPI.Hooks { @@ -166,6 +167,87 @@ namespace TShockAPI.Hooks } } + /// + /// EventArgs used for the event. + /// + public class PlayerItembanPermissionEventArgs : HandledEventArgs + { + /// + /// The player who fired the event. + /// + public TSPlayer Player { get; set; } + + /// + /// The banned item being checked. + /// + public ItemBan BannedItem { get; set; } + + /// + /// Initializes a new instance of the PlayerItembanPermissionEventArgs class. + /// + /// The player who fired the event. + /// The permission being checked. + public PlayerItembanPermissionEventArgs(TSPlayer player, ItemBan bannedItem) + { + Player = player; + BannedItem = bannedItem; + } + } + + /// + /// EventArgs used for the event. + /// + public class PlayerProjbanPermissionEventArgs : HandledEventArgs + { + /// + /// The player who fired the event. + /// + public TSPlayer Player { get; set; } + + /// + /// The banned projectile being checked. + /// + public ProjectileBan BannedProjectile { get; set; } + + /// + /// Initializes a new instance of the PlayerProjbanPermissionEventArgs class. + /// + /// The player who fired the event. + /// The banned projectile being checked. + public PlayerProjbanPermissionEventArgs(TSPlayer player, ProjectileBan checkedProjectile) + { + Player = player; + BannedProjectile = checkedProjectile; + } + } + + /// + /// EventArgs used for the event. + /// + public class PlayerTilebanPermissionEventArgs : HandledEventArgs + { + /// + /// The player who fired the event. + /// + public TSPlayer Player { get; set; } + + /// + /// The banned tile being checked. + /// + public TileBan BannedTile { get; set; } + + /// + /// Initializes a new instance of the PlayerTilebanPermissionEventArgs class. + /// + /// The player who fired the event. + /// The banned tile being checked. + public PlayerTilebanPermissionEventArgs(TSPlayer player, TileBan checkedTile) + { + Player = player; + BannedTile = checkedTile; + } + } + /// /// A collection of events fired by players that can be hooked to. /// @@ -232,6 +314,37 @@ namespace TShockAPI.Hooks /// public static event PlayerPermissionD PlayerPermission; + /// + /// The delegate of the event. + /// + /// The EventArgs for this event. + public delegate void PlayerItembanPermissionD(PlayerItembanPermissionEventArgs e); + /// + /// Fired by players every time a permission check on banned items involving them occurs. + /// + public static event PlayerItembanPermissionD PlayerItembanPermission; + + /// + /// The delegate of the event. + /// + /// The EventArgs for this event. + public delegate void PlayerProjbanPermissionD(PlayerProjbanPermissionEventArgs e); + /// + /// Fired by players every time a permission check on banned projectiles involving them occurs. + /// + public static event PlayerProjbanPermissionD PlayerProjbanPermission; + + /// + /// The delegate of the event. + /// + /// The EventArgs for this event. + public delegate void PlayerTilebanPermissionD(PlayerTilebanPermissionEventArgs e); + /// + /// Fired by players every time a permission check on banned tiles involving them occurs. + /// + public static event PlayerTilebanPermissionD PlayerTilebanPermission; + + /// /// Fires the event. /// @@ -336,5 +449,50 @@ namespace TShockAPI.Hooks PlayerPermission(args); return args.Handled; } + + /// + /// Fires the event. + /// + /// The player firing the event. + /// True if the event has been handled. + public static bool OnPlayerItembanPermission(TSPlayer player, ItemBan bannedItem) + { + if (PlayerItembanPermission == null) + return false; + + var args = new PlayerItembanPermissionEventArgs(player, bannedItem); + PlayerItembanPermission(args); + return args.Handled; + } + + /// + /// Fires the event. + /// + /// The player firing the event. + /// True if the event has been handled. + public static bool OnPlayerProjbanPermission(TSPlayer player, ProjectileBan bannedProj) + { + if (PlayerProjbanPermission == null) + return false; + + var args = new PlayerProjbanPermissionEventArgs(player, bannedProj); + PlayerProjbanPermission(args); + return args.Handled; + } + + /// + /// Fires the event. + /// + /// The player firing the event. + /// True if the event has been handled. + public static bool OnPlayerTilebanPermission(TSPlayer player, TileBan bannedTile) + { + if (PlayerTilebanPermission == null) + return false; + + var args = new PlayerTilebanPermissionEventArgs(player, bannedTile); + PlayerTilebanPermission(args); + return args.Handled; + } } } From 81cb1381b44fdc16882da43ddb2df1f294277ba7 Mon Sep 17 00:00:00 2001 From: Ruby Rose Date: Wed, 7 Jun 2017 15:32:40 +0300 Subject: [PATCH 005/430] Add hooks for item/projectile/tile bans --- TShockAPI/DB/ItemManager.cs | 4 ++++ TShockAPI/DB/ProjectileManager.cs | 4 ++++ TShockAPI/DB/TileManager.cs | 4 ++++ TShockAPI/TSPlayer.cs | 18 ++++++++++++++++++ 4 files changed, 30 insertions(+) diff --git a/TShockAPI/DB/ItemManager.cs b/TShockAPI/DB/ItemManager.cs index 4ce43066..0ff89b40 100644 --- a/TShockAPI/DB/ItemManager.cs +++ b/TShockAPI/DB/ItemManager.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using MySql.Data.MySqlClient; +using TShockAPI.Hooks; namespace TShockAPI.DB { @@ -200,6 +201,9 @@ namespace TShockAPI.DB if (ply.HasPermission(Permissions.usebanneditem)) return true; + if (PlayerHooks.OnPlayerItembanPermission(ply, this)) + return true; + var cur = ply.Group; var traversed = new List(); while (cur != null) diff --git a/TShockAPI/DB/ProjectileManager.cs b/TShockAPI/DB/ProjectileManager.cs index 3f736c9b..79bf9a37 100644 --- a/TShockAPI/DB/ProjectileManager.cs +++ b/TShockAPI/DB/ProjectileManager.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using MySql.Data.MySqlClient; +using TShockAPI.Hooks; namespace TShockAPI.DB { @@ -205,6 +206,9 @@ namespace TShockAPI.DB if (ply.HasPermission(Permissions.canusebannedprojectiles)) return true; + if (PlayerHooks.OnPlayerProjbanPermission(ply, this)) + return true; + var cur = ply.Group; var traversed = new List(); while (cur != null) diff --git a/TShockAPI/DB/TileManager.cs b/TShockAPI/DB/TileManager.cs index 911bf27b..90a235f8 100644 --- a/TShockAPI/DB/TileManager.cs +++ b/TShockAPI/DB/TileManager.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; using MySql.Data.MySqlClient; +using TShockAPI.Hooks; namespace TShockAPI.DB { @@ -205,6 +206,9 @@ namespace TShockAPI.DB if (ply.HasPermission(Permissions.canusebannedtiles)) return true; + if (PlayerHooks.OnPlayerTilebanPermission(ply, this)) + return true; + var cur = ply.Group; var traversed = new List(); while (cur != null) diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 43f7fe18..9b42d7b4 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -1253,6 +1253,24 @@ namespace TShockAPI else return Group.HasPermission(permission); } + + /// + public bool HasPermission(ItemBan bannedItem) + { + return TShock.Itembans.ItemIsBanned(bannedItem.Name, this); + } + + /// + public bool HasPermission(ProjectileBan bannedProj) + { + return TShock.ProjectileBans.ProjectileIsBanned(bannedProj.ID, this); + } + + /// + public bool HasPermission(TileBan bannedTile) + { + return TShock.TileBans.TileIsBanned(bannedTile.ID, this); + } } public class TSRestPlayer : TSPlayer From 8ae0a3b5a6518a573f1287356f23d7a03398678a Mon Sep 17 00:00:00 2001 From: Ruby Rose Date: Thu, 8 Jun 2017 17:18:38 +0300 Subject: [PATCH 006/430] Write proper docs --- TShockAPI/TSPlayer.cs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 9b42d7b4..42d1b157 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -1254,19 +1254,33 @@ namespace TShockAPI return Group.HasPermission(permission); } - /// + /// + /// Checks to see if a player has permission to use the specific banned item. + /// Fires the hook which may be handled to override item ban permission checks. + /// + /// The to check. + /// True if the player has permission to use the banned item. public bool HasPermission(ItemBan bannedItem) { return TShock.Itembans.ItemIsBanned(bannedItem.Name, this); } - /// + /// + /// Checks to see if a player has permission to use the specific banned projectile. + /// Fires the hook which may be handled to override projectile ban permission checks. + /// + /// The to check. + /// True if the player has permission to use the banned projectile. public bool HasPermission(ProjectileBan bannedProj) { return TShock.ProjectileBans.ProjectileIsBanned(bannedProj.ID, this); } - - /// + /// + /// Checks to see if a player has permission to use the specific banned tile. + /// Fires the hook which may be handled to override tile ban permission checks. + /// + /// The to check. + /// True if the player has permission to use the banned tile. public bool HasPermission(TileBan bannedTile) { return TShock.TileBans.TileIsBanned(bannedTile.ID, this); From 331eeb8cec794a963c05980178327cc6ef866b10 Mon Sep 17 00:00:00 2001 From: MarioE Date: Mon, 19 Jun 2017 01:15:45 -0400 Subject: [PATCH 007/430] Fix SaveManager saving when 1 player is on the server and another joins The real fix would be to fix ServerLeave to not fire incorrectly when a player joins, but this will do for now. --- TShockAPI/TShock.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 42cd9ef1..776846fa 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -1405,9 +1405,14 @@ namespace TShockAPI } var tsplr = Players[args.Who]; + if (tsplr == null) + { + return; + } + Players[args.Who] = null; - if (tsplr != null && tsplr.ReceivedInfo) + if (tsplr.ReceivedInfo) { if (!tsplr.SilentKickInProgress && tsplr.State >= 3) Utils.Broadcast(tsplr.Name + " has left.", Color.Yellow); @@ -1431,7 +1436,7 @@ namespace TShockAPI } // Fire the OnPlayerLogout hook too, if the player was logged in and they have a TSPlayer object. - if (tsplr != null && tsplr.IsLoggedIn) + if (tsplr.IsLoggedIn) { Hooks.PlayerHooks.OnPlayerLogout(tsplr); } From 9ad63c37a616e2b920fcdbc6d7fdc28cbcfae250 Mon Sep 17 00:00:00 2001 From: MarioE Date: Wed, 21 Jun 2017 01:21:32 -0400 Subject: [PATCH 008/430] Fix /spawnmob not spawning negative IDs again. --- TShockAPI/Commands.cs | 2 +- TShockAPI/TSServerPlayer.cs | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index ee9106fc..3b07ca75 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -2300,7 +2300,7 @@ namespace TShockAPI var npc = npcs[0]; if (npc.type >= 1 && npc.type < Main.maxNPCTypes && npc.type != 113) { - TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY, 50, 20); + TSPlayer.Server.SpawnNPC(npc.netID, npc.FullName, amount, args.Player.TileX, args.Player.TileY, 50, 20); if (args.Silent) { args.Player.SendSuccessMessage("Spawned {0} {1} time(s).", npc.FullName, amount); diff --git a/TShockAPI/TSServerPlayer.cs b/TShockAPI/TSServerPlayer.cs index a1084d61..b811e9a8 100644 --- a/TShockAPI/TSServerPlayer.cs +++ b/TShockAPI/TSServerPlayer.cs @@ -152,12 +152,7 @@ namespace TShockAPI int spawnTileY; TShock.Utils.GetRandomClearTileWithInRange(startTileX, startTileY, tileXRange, tileYRange, out spawnTileX, out spawnTileY); - int npcid = NPC.NewNPC(spawnTileX * 16, spawnTileY * 16, type, 0); - - // TODO: If special slimes break look at the git blame for this spot - // It's probably because I removed something that didn't work - Main.npc[npcid].SetDefaults(type); - + NPC.NewNPC(spawnTileX * 16, spawnTileY * 16, type); } } From 40e3a9d5b872ea005e72e6f25bdee351226030b3 Mon Sep 17 00:00:00 2001 From: Ryozuki Date: Thu, 22 Jun 2017 21:05:14 +0200 Subject: [PATCH 009/430] fix comment typo --- TShockAPI/DB/WarpsManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/DB/WarpsManager.cs b/TShockAPI/DB/WarpsManager.cs index d48ba40e..6ed72f4e 100644 --- a/TShockAPI/DB/WarpsManager.cs +++ b/TShockAPI/DB/WarpsManager.cs @@ -61,7 +61,7 @@ namespace TShockAPI.DB /// The X position. /// The Y position. /// The name. - /// Whether the opration succeeded. + /// Whether the operation succeeded. public bool Add(int x, int y, string name) { try From 241d4c566faedd740796822ed1f5cdb10c377dfd Mon Sep 17 00:00:00 2001 From: MarioE Date: Fri, 23 Jun 2017 14:44:17 -0400 Subject: [PATCH 010/430] Fix incorrect slot calculation, and update submodule. --- TShockAPI/TShock.cs | 6 +++--- TerrariaServerAPI | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 776846fa..022e70e5 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -2237,9 +2237,9 @@ namespace TShockAPI Netplay.ListenPort = file.ServerPort; } - if (file.MaxSlots > 235) - file.MaxSlots = 235; - Main.maxNetPlayers = file.MaxSlots + 20; + if (file.MaxSlots > Main.maxPlayers - file.ReservedSlots) + file.MaxSlots = Main.maxPlayers - file.ReservedSlots; + Main.maxNetPlayers = file.MaxSlots + file.ReservedSlots; Netplay.ServerPassword = ""; if (!string.IsNullOrEmpty(_cliPassword)) diff --git a/TerrariaServerAPI b/TerrariaServerAPI index d3b7d9f4..bc9f7c69 160000 --- a/TerrariaServerAPI +++ b/TerrariaServerAPI @@ -1 +1 @@ -Subproject commit d3b7d9f4575602f468cf1e009ebc4bc5b79547c4 +Subproject commit bc9f7c69becb60816fc1e4587bbca15991231317 From 50a4b07bc39ad58dcec4f5c16cf5ea31135bd6f7 Mon Sep 17 00:00:00 2001 From: MarioE Date: Fri, 23 Jun 2017 14:47:38 -0400 Subject: [PATCH 011/430] Add "new" EditActions. --- TShockAPI/GetDataHandlers.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 0bb216e1..2a7ddd00 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -1909,7 +1909,10 @@ namespace TShockAPI KillWire2, PlaceWire3, KillWire3, - SlopeTile + SlopeTile, + FrameTrack, + PlaceWire4, + KillWire4 } public enum EditType { From 6b3f18b1da7142ad23fe7fe27c93a13d6677e349 Mon Sep 17 00:00:00 2001 From: ProfessorXZ Date: Wed, 5 Jul 2017 15:09:31 +0200 Subject: [PATCH 012/430] Validate tile placement on PlaceObject, update CHANGELOG.md. Fixes #1418 --- CHANGELOG.md | 6 ++++++ TShockAPI/GetDataHandlers.cs | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa42a2aa..267c8ece 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,13 @@ 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 +* API: Added hooks for item, projectile and tile bans (@deadsurgeon42) +* API: New WorldGrassSpread hook which shold allow corruption/crimson/hallow creep config options to work (@DeathCradle) +* Fixed saving when one player is one the server and another one joins (@MarioE) +* Fixed /spawnmob not spawning negative IDs (@MarioE) +* Validated tile placement on PlaceObject; clients can no longer place frames, paintings etc with dirt blocks (@bartico6, @ProfessorXZ) +## TShock 4.3.24 * Updated OpenTerraria API to 1.3.5.3 (@DeathCradle) * Updated Terraria Server API to 1.3.5.3 (@WhiteXZ, @hakusaro) * Updated TShock core components to 1.3.5.3 (@hakusaro) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 2a7ddd00..77e37c03 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -2350,6 +2350,15 @@ namespace TShockAPI return true; } + // This is neccessary to check in order to prevent special tiles such as + // queen bee larva, paintings etc that use this packet from being placed + // without selecting the right item. + if (type != args.TPlayer.inventory[args.TPlayer.selectedItem].createTile) + { + args.Player.SendTileSquare(x, y, 4); + return true; + } + TileObjectData tileData = TileObjectData.GetTileData(type, style, 0); if (tileData == null) return true; From db480a16f0308d2d36d8eb672ce4ced772bf3782 Mon Sep 17 00:00:00 2001 From: Pia Mancini Date: Thu, 20 Apr 2017 11:45:15 -0400 Subject: [PATCH 013/430] Add backers and sponsors from Open Collective Now your open collective backers and sponsors can to appear directly on your README. see how it'll look [here](https://github.com/apex/apex#backers) [More info](https://github.com/opencollective/opencollective/wiki/Github-banner) Also add badges on top --- README.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/README.md b/README.md index 9fa0710d..2d024912 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@

+[![OpenCollective](https://opencollective.com/tshock/backers/badge.svg)](#backers) +[![OpenCollective](https://opencollective.com/tshock/sponsors/badge.svg)](#sponsors) + TShock is a server modification for Terraria, written in C#, and based upon the [Terraria Server API](https://github.com/NyxStudios/TerrariaAPI-Server). It uses JSON for configuration management, and offers several features not present in the Terraria Server normally. ## :star: Quick Start @@ -44,3 +47,73 @@ Please see the contributing file before sending pull requests. * [Development Builds](https://travis.tshock.co/) * [Plugins](https://tshock.co/xf/index.php?resources/) * [Very, very old versions of TShock](https://github.com/TShock/TShock/downloads) + +## Backers + +Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/tshock#backer)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Sponsors + +Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/tshock#sponsor)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 587d1b739079a1a38ecf03bfe347a55087c8800f Mon Sep 17 00:00:00 2001 From: Ryozuki Date: Thu, 22 Jun 2017 21:05:14 +0200 Subject: [PATCH 014/430] fix comment typo --- TShockAPI/DB/WarpsManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/DB/WarpsManager.cs b/TShockAPI/DB/WarpsManager.cs index d48ba40e..6ed72f4e 100644 --- a/TShockAPI/DB/WarpsManager.cs +++ b/TShockAPI/DB/WarpsManager.cs @@ -61,7 +61,7 @@ namespace TShockAPI.DB /// The X position. /// The Y position. /// The name. - /// Whether the opration succeeded. + /// Whether the operation succeeded. public bool Add(int x, int y, string name) { try From 983a678ff3f2a8fce397c3e6d0e444faac4e2528 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Sat, 15 Jul 2017 13:32:27 -0600 Subject: [PATCH 015/430] Fix issue 1467 - Password is now hashed when adding a user via REST API --- TShockAPI/Rest/RestManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index eace08ee..bd10de2d 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -520,9 +520,10 @@ namespace TShockAPI return RestMissingParam("password"); // NOTE: ip can be blank - User user = new User(username, password, "", group, "", "", ""); + User user = new User(username, "", "", group, "", "", ""); try { + user.CreateBCryptHash(password); TShock.Users.AddUser(user); } catch (Exception e) From ac8fe2a2153f183068096a489317da44d2cd3c28 Mon Sep 17 00:00:00 2001 From: MarioE Date: Tue, 11 Jul 2017 00:33:34 -0400 Subject: [PATCH 016/430] Remove netID handling of GiveItem, and provide a smaller overload --- TShockAPI/Commands.cs | 4 +- TShockAPI/TSPlayer.cs | 130 ++++++++++++++++++++++++------------------ 2 files changed, 77 insertions(+), 57 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 3b07ca75..5e7b84bf 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -5297,7 +5297,7 @@ namespace TShockAPI if (itemAmount == 0 || itemAmount > item.maxStack) itemAmount = item.maxStack; - if (args.Player.GiveItemCheck(item.type, EnglishLanguage.GetItemNameById(item.type), item.width, item.height, itemAmount, prefixId)) + if (args.Player.GiveItemCheck(item.type, EnglishLanguage.GetItemNameById(item.type), itemAmount, prefixId)) { item.prefix = (byte)prefixId; args.Player.SendSuccessMessage("Gave {0} {1}(s).", itemAmount, item.AffixName()); @@ -5436,7 +5436,7 @@ namespace TShockAPI { if (itemAmount == 0 || itemAmount > item.maxStack) itemAmount = item.maxStack; - if (plr.GiveItemCheck(item.type, EnglishLanguage.GetItemNameById(item.type), item.width, item.height, itemAmount, prefix)) + if (plr.GiveItemCheck(item.type, EnglishLanguage.GetItemNameById(item.type), itemAmount, prefix)) { args.Player.SendSuccessMessage(string.Format("Gave {0} {1} {2}(s).", plr.Name, itemAmount, item.Name)); plr.SendSuccessMessage(string.Format("{0} gave you {1} {2}(s).", args.Player.Name, itemAmount, item.Name)); diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 42d1b157..8d0819bf 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -375,7 +375,7 @@ namespace TShockAPI get { return RealPlayer - && (Netplay.Clients[Index] != null && Netplay.Clients[Index].IsActive && !Netplay.Clients[Index].PendingTermination); + && (Netplay.Clients[Index] != null && Netplay.Clients[Index].IsActive && !Netplay.Clients[Index].PendingTermination); } } @@ -413,10 +413,10 @@ namespace TShockAPI { if (string.IsNullOrEmpty(CacheIP)) return - CacheIP = RealPlayer ? (Netplay.Clients[Index].Socket.IsConnected() - ? TShock.Utils.GetRealIP(Netplay.Clients[Index].Socket.GetRemoteAddress().ToString()) - : "") - : ""; + CacheIP = RealPlayer ? (Netplay.Clients[Index].Socket.IsConnected() + ? TShock.Utils.GetRealIP(Netplay.Clients[Index].Socket.GetRemoteAddress().ToString()) + : "") + : ""; else return CacheIP; } @@ -522,7 +522,7 @@ namespace TShockAPI /// public float X { - get { return RealPlayer ? TPlayer.position.X : Main.spawnTileX*16; } + get { return RealPlayer ? TPlayer.position.X : Main.spawnTileX * 16; } } /// @@ -530,7 +530,7 @@ namespace TShockAPI /// public float Y { - get { return RealPlayer ? TPlayer.position.Y : Main.spawnTileY*16; } + get { return RealPlayer ? TPlayer.position.Y : Main.spawnTileY * 16; } } /// @@ -538,7 +538,7 @@ namespace TShockAPI /// public int TileX { - get { return (int) (X/16); } + get { return (int)(X / 16); } } /// @@ -546,7 +546,7 @@ namespace TShockAPI /// public int TileY { - get { return (int) (Y/16); } + get { return (int)(Y / 16); } } /// @@ -688,7 +688,7 @@ namespace TShockAPI TilesDestroyed = new Dictionary(); TilesCreated = new Dictionary(); Index = -1; - FakePlayer = new Player {name = playerName, whoAmI = -1}; + FakePlayer = new Player { name = playerName, whoAmI = -1 }; Group = Group.DefaultGroup; AwaitingResponse = new Dictionary>(); } @@ -744,7 +744,7 @@ namespace TShockAPI y = 992; } - SendTileSquare((int) (x/16), (int) (y/16), 15); + SendTileSquare((int)(x / 16), (int)(y / 16), 15); TPlayer.Teleport(new Vector2(x, y), style); NetMessage.SendData((int)PacketTypes.Teleport, -1, -1, NetworkText.Empty, 0, TPlayer.whoAmI, x, y, style); return true; @@ -784,11 +784,11 @@ namespace TShockAPI using (var ms = new MemoryStream()) { var msg = new SpawnMsg - { - PlayerIndex = (byte) Index, - TileX = (short)tilex, - TileY = (short)tiley - }; + { + PlayerIndex = (byte)Index, + TileX = (short)tilex, + TileY = (short)tiley + }; msg.PackFull(ms); SendRawData(ms.ToArray()); } @@ -804,10 +804,10 @@ namespace TShockAPI using (var ms = new MemoryStream()) { var msg = new ProjectileRemoveMsg - { - Index = (short) index, - Owner = (byte) owner - }; + { + Index = (short)index, + Owner = (byte)owner + }; msg.PackFull(ms); SendRawData(ms.ToArray()); } @@ -817,7 +817,7 @@ namespace TShockAPI { try { - int num = (size - 1)/2; + int num = (size - 1) / 2; int m_x = 0; int m_y = 0; @@ -866,18 +866,37 @@ namespace TShockAPI /// /// Gives an item to the player. Includes banned item spawn prevention to check if the player can spawn the item. /// - /// - /// - /// - /// - /// - /// + /// The item ID. + /// The item name. + /// The item stack. + /// The item prefix. /// True or false, depending if the item passed the check or not. + public bool GiveItemCheck(int type, string name, int stack, int prefix = 0) + { + if ((TShock.Itembans.ItemIsBanned(name) && TShock.Config.PreventBannedItemSpawn) && + (TShock.Itembans.ItemIsBanned(name, this) || !TShock.Config.AllowAllowedGroupsToSpawnBannedItems)) + return false; + + GiveItem(type, stack, prefix); + return true; + } + + /// + /// Gives an item to the player. Includes banned item spawn prevention to check if the player can spawn the item. + /// + /// The item ID. + /// The item name. + /// The width of the receiver. + /// The height of the receiver. + /// The item stack. + /// The item prefix. + /// True or false, depending if the item passed the check or not. + [Obsolete("Use the GiveItemCheck overload with fewer parameters.")] public bool GiveItemCheck(int type, string name, int width, int height, int stack, int prefix = 0) { if ((TShock.Itembans.ItemIsBanned(name) && TShock.Config.PreventBannedItemSpawn) && - (TShock.Itembans.ItemIsBanned(name, this) || !TShock.Config.AllowAllowedGroupsToSpawnBannedItems)) - return false; + (TShock.Itembans.ItemIsBanned(name, this) || !TShock.Config.AllowAllowedGroupsToSpawnBannedItems)) + return false; GiveItem(type, name, width, height, stack, prefix); return true; @@ -886,28 +905,29 @@ namespace TShockAPI /// /// Gives an item to the player. /// - /// The item's netID. - /// The tiem's name. - /// The item's width. - /// The item's height. - /// The item's stack. - /// The item's prefix. + /// The item ID. + /// The item stack. + /// The item prefix. + public virtual void GiveItem(int type, int stack, int prefix = 0) + { + int itemIndex = Item.NewItem((int)X, (int)Y, TPlayer.width, TPlayer.height, type, stack, true, prefix, true); + SendData(PacketTypes.ItemDrop, "", itemIndex); + } + + /// + /// Gives an item to the player. + /// + /// The item ID. + /// The item name. This parameter is unused. + /// The width of the receiver. + /// The height of the receiver. + /// The item stack. + /// The item prefix. + [Obsolete("Use the GiveItem overload with fewer parameters.")] public virtual void GiveItem(int type, string name, int width, int height, int stack, int prefix = 0) { - int itemid = Item.NewItem((int) X, (int) Y, width, height, type, stack, true, prefix, true); - - // This is for special pickaxe/hammers/swords etc - Main.item[itemid].netDefaults(type); - // The set default overrides the wet and stack set by NewItem - Main.item[itemid].wet = Collision.WetCollision(Main.item[itemid].position, Main.item[itemid].width, - Main.item[itemid].height); - Main.item[itemid].stack = stack; - Main.item[itemid].owner = Index; - Main.item[itemid].prefix = (byte) prefix; - Main.item[itemid].noGrabDelay = 1; - Main.item[itemid].velocity = Main.player[this.Index].velocity; - NetMessage.SendData((int)PacketTypes.ItemDrop, -1, -1, NetworkText.Empty, itemid, 0f, 0f, 0f); - NetMessage.SendData((int)PacketTypes.ItemOwner, -1, -1, NetworkText.Empty, itemid, 0f, 0f, 0f); + int itemIndex = Item.NewItem((int)X, (int)Y, width, height, type, stack, true, prefix, true); + SendData(PacketTypes.ItemDrop, "", itemIndex); } /// @@ -1144,7 +1164,7 @@ namespace TShockAPI /// The public virtual void Whoopie(object time) { - var time2 = (int) time; + var time2 = (int)time; var launch = DateTime.UtcNow; var startname = Name; SendInfoMessage("You are now being annoyed."); @@ -1186,7 +1206,7 @@ namespace TShockAPI if (RealPlayer && !ConnectionAlive) return; - NetMessage.SendData((int) msgType, Index, -1, NetworkText.FromLiteral(text), number, number2, number3, number4, number5); + NetMessage.SendData((int)msgType, Index, -1, NetworkText.FromLiteral(text), number, number2, number3, number4, number5); } /// @@ -1205,7 +1225,7 @@ namespace TShockAPI if (RealPlayer && !ConnectionAlive) return; - NetMessage.SendData((int) msgType, Index, -1, NetworkText.FromFormattable(text), ply, number2, number3, number4, number5); + NetMessage.SendData((int)msgType, Index, -1, NetworkText.FromFormattable(text), ply, number2, number3, number4, number5); } /// @@ -1225,9 +1245,9 @@ namespace TShockAPI /// /// The string representing the command i.e "yes" == /yes /// The method that will be executed on confirmation ie user accepts - public void AddResponse( string name, Action callback) + public void AddResponse(string name, Action callback) { - if( AwaitingResponse.ContainsKey(name)) + if (AwaitingResponse.ContainsKey(name)) { AwaitingResponse.Remove(name); } @@ -1291,7 +1311,7 @@ namespace TShockAPI { internal List CommandOutput = new List(); - public TSRestPlayer(string playerName, Group playerGroup): base(playerName) + public TSRestPlayer(string playerName, Group playerGroup) : base(playerName) { Group = playerGroup; AwaitingResponse = new Dictionary>(); From 1cdd33a78a9aa9c4a0e5ad71590878652937d289 Mon Sep 17 00:00:00 2001 From: Jordan Coulam Date: Mon, 17 Jul 2017 03:56:56 +0100 Subject: [PATCH 017/430] Added ignoreVersion and loaded plugin list to StatTracking for issue #1444 (#1445) --- TShockAPI/StatTracker.cs | 117 ++++++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 38 deletions(-) diff --git a/TShockAPI/StatTracker.cs b/TShockAPI/StatTracker.cs index 78aa10f5..d1c01c1c 100644 --- a/TShockAPI/StatTracker.cs +++ b/TShockAPI/StatTracker.cs @@ -22,11 +22,13 @@ using System.Threading; using System.Web; using TerrariaApi.Server; using System.Diagnostics; +using System.Linq; using System.Runtime.InteropServices; using System.Net.Http; using System.Threading.Tasks; using TShockAPI.Extensions; + namespace TShockAPI { /// @@ -52,10 +54,11 @@ namespace TShockAPI /// public bool OptOut = false; + private PluginItem[] plugins; + private long totalMem = 0; private string serverId = ""; private HttpClient _client; - private const string TrackerUrl = "http://stats.tshock.co/submit/{0}"; /// @@ -103,11 +106,9 @@ namespace TShockAPI private async Task SendUpdateAsync() { JsonData data = PrepareJsonData(); - var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(data); var encoded = HttpUtility.UrlEncode(serialized); - var uri = String.Format(TrackerUrl, encoded); - + var uri = string.Format(TrackerUrl, encoded); try { HttpResponseMessage msg = await _client.GetAsync(uri); @@ -139,49 +140,81 @@ namespace TShockAPI private JsonData PrepareJsonData() { - if (ServerApi.RunningMono) - { - if (totalMem == 0) - { - //Only do this if we haven't already cached the total physicaly memory - var pc = new PerformanceCounter("Mono Memory", "Total Physical Memory"); - totalMem = (pc.RawValue / 1024 / 1024 / 1024); - } - - return new JsonData - { - port = Terraria.Netplay.ListenPort, - currentPlayers = TShock.Utils.ActivePlayers(), - maxPlayers = TShock.Config.MaxSlots, - systemRam = totalMem, - version = TShock.VersionNum.ToString(), - terrariaVersion = Terraria.Main.versionNumber2, - providerId = ProviderToken, - serverId = serverId, - mono = true - }; - } - - if (totalMem == 0) - { - //Again, only call this if it hasn't previously been cached - GetPhysicallyInstalledSystemMemory(out totalMem); - totalMem = (totalMem / 1024 / 1024); // Super hardcore maths to convert to Gb from Kb - } - - return new JsonData + return new JsonData() { port = Terraria.Netplay.ListenPort, currentPlayers = TShock.Utils.ActivePlayers(), maxPlayers = TShock.Config.MaxSlots, - systemRam = totalMem, + systemRam = GetTotalSystemRam(ServerApi.RunningMono), version = TShock.VersionNum.ToString(), terrariaVersion = Terraria.Main.versionNumber2, providerId = ProviderToken, serverId = serverId, - mono = false + mono = ServerApi.RunningMono, + ignorePluginVersion = ServerApi.IgnoreVersion, + loadedPlugins = GetLoadedPlugins() }; } + + private PluginItem[] GetLoadedPlugins() + { + if (plugins != null) + { + return plugins;//Return early + } + + plugins = new PluginItem[ServerApi.Plugins.Count];//Initialize with enough room to store the ammount of plugins loaded. + for (var i = 0; i < ServerApi.Plugins.Count; i++) + { + var pluginItem = new PluginItem(); + var apiAttribute = (ApiVersionAttribute)ServerApi.Plugins[i].Plugin.GetType().GetCustomAttributes(typeof(ApiVersionAttribute), false).FirstOrDefault(); + //The current implementation of loading plugins doesn't allow for a plugin to be loaded without an ApiVersion, the UNKNOWN is there incase a change is made to allow it + pluginItem.apiVersion = apiAttribute?.ApiVersion.ToString() ?? "UNKNOWN"; + pluginItem.name = ServerApi.Plugins[i].Plugin.Name; + pluginItem.version = ServerApi.Plugins[i].Plugin.Version.ToString(); + plugins[i] = pluginItem; + } + return plugins; + } + + private long GetTotalSystemRam(bool isMono) + { + if (totalMem != 0) + { + return totalMem;//Return early + } + + if (isMono)//Set totalMem so it can be returned later + { + var pc = new PerformanceCounter("Mono Memory", "Total Physical Memory"); + totalMem = (pc.RawValue / 1024 / 1024 / 1024); + } + else + { + GetPhysicallyInstalledSystemMemory(out totalMem); + totalMem = (totalMem / 1024 / 1024); // Super hardcore maths to convert to Gb from Kb + } + + return totalMem; + } + } + /// + /// Holding information regarding loaded plugins + /// + public struct PluginItem + { + /// + /// Plugin name + /// + public string name; + /// + /// Assembly version + /// + public string version; + /// + /// Api version or UNKNOWN if attribute is missing, which is currently impossible + /// + public string apiVersion; } /// @@ -210,6 +243,14 @@ namespace TShockAPI /// public string version; /// + /// Whether or not server was started with --ignoreversion + /// + public bool ignorePluginVersion; + /// + /// List of loaded plugins and version name: + /// + public PluginItem[] loadedPlugins; + /// /// The Terraria version supported by the server /// public string terrariaVersion; @@ -226,4 +267,4 @@ namespace TShockAPI /// public bool mono; } -} +} \ No newline at end of file From b387d42e5342eb2c3eda941a40f0a2ec922b0677 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Sun, 16 Jul 2017 21:21:42 -0600 Subject: [PATCH 018/430] Add PR template file --- PULL_REQUEST_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 PULL_REQUEST_TEMPLATE.md diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..9e7b1cc8 --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1 @@ + From 4216501c458698b2235a185f3912cf6bfd5dcfcc Mon Sep 17 00:00:00 2001 From: Ruby Rose Date: Thu, 13 Jul 2017 16:00:40 +0300 Subject: [PATCH 019/430] Make User implement IEquatable for more consistent comparisons --- TShockAPI/DB/UserManager.cs | 64 ++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/TShockAPI/DB/UserManager.cs b/TShockAPI/DB/UserManager.cs index e79fb933..88103899 100644 --- a/TShockAPI/DB/UserManager.cs +++ b/TShockAPI/DB/UserManager.cs @@ -363,7 +363,7 @@ namespace TShockAPI.DB } /// A database user. - public class User + public class User : IEquatable { /// The database ID of the user. public int ID { get; set; } @@ -581,10 +581,66 @@ namespace TShockAPI.DB return HashPassword(Encoding.UTF8.GetBytes(password)); } - } + #region IEquatable - /// UserManagerException - An exception generated by the user manager. - [Serializable] + /// Indicates whether the current is equal to another . + /// true if the is equal to the parameter; otherwise, false. + /// An to compare with this . + public bool Equals(User other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return ID == other.ID && string.Equals(Name, other.Name); + } + + /// Indicates whether the current is equal to another object. + /// true if the is equal to the parameter; otherwise, false. + /// An to compare with this . + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((User)obj); + } + + /// Serves as the hash function. + /// A hash code for the current . + public override int GetHashCode() + { + unchecked + { + return (ID * 397) ^ (Name != null ? Name.GetHashCode() : 0); + } + } + + /// + /// Compares equality of two objects. + /// + /// Left hand of the comparison. + /// Right hand of the comparison. + /// true if the objects are equal; otherwise, false. + public static bool operator ==(User left, User right) + { + return Equals(left, right); + } + + /// + /// Compares equality of two objects. + /// + /// Left hand of the comparison. + /// Right hand of the comparison. + /// true if the objects aren't equal; otherwise, false. + public static bool operator !=(User left, User right) + { + return !Equals(left, right); + } + + #endregion + } + + /// UserManagerException - An exception generated by the user manager. + [Serializable] public class UserManagerException : Exception { /// Creates a new UserManagerException object. From c8e31231ba135465160eb43e20858d3c38c41a68 Mon Sep 17 00:00:00 2001 From: Ruby Rose Date: Thu, 13 Jul 2017 16:01:47 +0300 Subject: [PATCH 020/430] override ToString of user --- TShockAPI/DB/UserManager.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/TShockAPI/DB/UserManager.cs b/TShockAPI/DB/UserManager.cs index 88103899..f93f9935 100644 --- a/TShockAPI/DB/UserManager.cs +++ b/TShockAPI/DB/UserManager.cs @@ -637,7 +637,12 @@ namespace TShockAPI.DB } #endregion - } + + public override string ToString() + { + return Name; + } + } /// UserManagerException - An exception generated by the user manager. [Serializable] From 5e1be5b19b08350d833a96c46917248641b32782 Mon Sep 17 00:00:00 2001 From: Ruby Rose Date: Thu, 13 Jul 2017 16:04:17 +0300 Subject: [PATCH 021/430] Fix formatting below IEquatable block --- TShockAPI/DB/UserManager.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TShockAPI/DB/UserManager.cs b/TShockAPI/DB/UserManager.cs index f93f9935..368c2dae 100644 --- a/TShockAPI/DB/UserManager.cs +++ b/TShockAPI/DB/UserManager.cs @@ -644,8 +644,8 @@ namespace TShockAPI.DB } } - /// UserManagerException - An exception generated by the user manager. - [Serializable] + /// UserManagerException - An exception generated by the user manager. + [Serializable] public class UserManagerException : Exception { /// Creates a new UserManagerException object. @@ -704,4 +704,4 @@ namespace TShockAPI.DB { } } -} \ No newline at end of file +} From 02be378a2ec5b71ab1e878d22ac14a37b19f3da1 Mon Sep 17 00:00:00 2001 From: Ruby Rose Date: Fri, 14 Jul 2017 08:03:16 +0300 Subject: [PATCH 022/430] change doc of Equals --- TShockAPI/DB/UserManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/DB/UserManager.cs b/TShockAPI/DB/UserManager.cs index 368c2dae..07662b2b 100644 --- a/TShockAPI/DB/UserManager.cs +++ b/TShockAPI/DB/UserManager.cs @@ -595,7 +595,7 @@ namespace TShockAPI.DB /// Indicates whether the current is equal to another object. /// true if the is equal to the parameter; otherwise, false. - /// An to compare with this . + /// An to compare with this . public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; From 79f66f554febef5efa2167a13eec544a79f43413 Mon Sep 17 00:00:00 2001 From: Ruby Rose Date: Tue, 11 Jul 2017 10:37:17 +0300 Subject: [PATCH 023/430] Turn the player hooks into a tristate --- TShockAPI/DB/ItemManager.cs | 5 +- TShockAPI/DB/ProjectileManager.cs | 5 +- TShockAPI/DB/TileManager.cs | 5 +- TShockAPI/Hooks/PlayerHooks.cs | 89 +++++++++++++++++++++++++------ TShockAPI/TSPlayer.cs | 6 ++- 5 files changed, 85 insertions(+), 25 deletions(-) diff --git a/TShockAPI/DB/ItemManager.cs b/TShockAPI/DB/ItemManager.cs index 0ff89b40..54ae8ee5 100644 --- a/TShockAPI/DB/ItemManager.cs +++ b/TShockAPI/DB/ItemManager.cs @@ -201,8 +201,9 @@ namespace TShockAPI.DB if (ply.HasPermission(Permissions.usebanneditem)) return true; - if (PlayerHooks.OnPlayerItembanPermission(ply, this)) - return true; + PermissionResult hookResult = PlayerHooks.OnPlayerItembanPermission(ply, this); + if (hookResult != PermissionResult.Inconclusive) + return hookResult == PermissionResult.Granted; var cur = ply.Group; var traversed = new List(); diff --git a/TShockAPI/DB/ProjectileManager.cs b/TShockAPI/DB/ProjectileManager.cs index 79bf9a37..234d3cca 100644 --- a/TShockAPI/DB/ProjectileManager.cs +++ b/TShockAPI/DB/ProjectileManager.cs @@ -206,8 +206,9 @@ namespace TShockAPI.DB if (ply.HasPermission(Permissions.canusebannedprojectiles)) return true; - if (PlayerHooks.OnPlayerProjbanPermission(ply, this)) - return true; + PermissionResult hookResult = PlayerHooks.OnPlayerProjbanPermission(ply, this); + if (hookResult != PermissionResult.Inconclusive) + return hookResult == PermissionResult.Granted; var cur = ply.Group; var traversed = new List(); diff --git a/TShockAPI/DB/TileManager.cs b/TShockAPI/DB/TileManager.cs index 90a235f8..83b079ab 100644 --- a/TShockAPI/DB/TileManager.cs +++ b/TShockAPI/DB/TileManager.cs @@ -206,8 +206,9 @@ namespace TShockAPI.DB if (ply.HasPermission(Permissions.canusebannedtiles)) return true; - if (PlayerHooks.OnPlayerTilebanPermission(ply, this)) - return true; + PermissionResult hookResult = PlayerHooks.OnPlayerTilebanPermission(ply, this); + if (hookResult != PermissionResult.Inconclusive) + return hookResult == PermissionResult.Granted; var cur = ply.Group; var traversed = new List(); diff --git a/TShockAPI/Hooks/PlayerHooks.cs b/TShockAPI/Hooks/PlayerHooks.cs index 062a78b8..7f2e8601 100644 --- a/TShockAPI/Hooks/PlayerHooks.cs +++ b/TShockAPI/Hooks/PlayerHooks.cs @@ -155,6 +155,11 @@ namespace TShockAPI.Hooks /// public string Permission { get; set; } + /// + /// of the hook. + /// + public PermissionResult Result { get; set; } + /// /// Initializes a new instance of the PlayerPermissionEventArgs class. /// @@ -164,6 +169,7 @@ namespace TShockAPI.Hooks { Player = player; Permission = permission; + Result = PermissionResult.Inconclusive; } } @@ -182,15 +188,21 @@ namespace TShockAPI.Hooks /// public ItemBan BannedItem { get; set; } + /// + /// of the hook. + /// + public PermissionResult Result { get; set; } + /// /// Initializes a new instance of the PlayerItembanPermissionEventArgs class. /// /// The player who fired the event. - /// The permission being checked. + /// The banned item being checked. public PlayerItembanPermissionEventArgs(TSPlayer player, ItemBan bannedItem) { Player = player; BannedItem = bannedItem; + Result = PermissionResult.Inconclusive; } } @@ -209,6 +221,11 @@ namespace TShockAPI.Hooks /// public ProjectileBan BannedProjectile { get; set; } + /// + /// of the hook. + /// + public PermissionResult Result { get; set; } + /// /// Initializes a new instance of the PlayerProjbanPermissionEventArgs class. /// @@ -218,6 +235,7 @@ namespace TShockAPI.Hooks { Player = player; BannedProjectile = checkedProjectile; + Result = PermissionResult.Inconclusive; } } @@ -236,6 +254,11 @@ namespace TShockAPI.Hooks /// public TileBan BannedTile { get; set; } + /// + /// of the hook. + /// + public PermissionResult Result { get; set; } + /// /// Initializes a new instance of the PlayerTilebanPermissionEventArgs class. /// @@ -245,6 +268,7 @@ namespace TShockAPI.Hooks { Player = player; BannedTile = checkedTile; + Result = PermissionResult.Inconclusive; } } @@ -439,60 +463,91 @@ namespace TShockAPI.Hooks /// Fires the event. /// /// The player firing the event. - /// True if the event has been handled. - public static bool OnPlayerPermission(TSPlayer player, string permission) + /// Event result if the event has been handled, otherwise . + public static PermissionResult OnPlayerPermission(TSPlayer player, string permission) { if (PlayerPermission == null) - return false; + return PermissionResult.Inconclusive; var args = new PlayerPermissionEventArgs(player, permission); PlayerPermission(args); - return args.Handled; + + if (args.Handled) + return args.Result; + else + return PermissionResult.Inconclusive; } /// /// Fires the event. /// /// The player firing the event. - /// True if the event has been handled. - public static bool OnPlayerItembanPermission(TSPlayer player, ItemBan bannedItem) + /// Event result if the event has been handled, otherwise . + public static PermissionResult OnPlayerItembanPermission(TSPlayer player, ItemBan bannedItem) { if (PlayerItembanPermission == null) - return false; + return PermissionResult.Inconclusive; var args = new PlayerItembanPermissionEventArgs(player, bannedItem); PlayerItembanPermission(args); - return args.Handled; + + if (args.Handled) + return args.Result; + else + return PermissionResult.Inconclusive; } /// /// Fires the event. /// /// The player firing the event. - /// True if the event has been handled. - public static bool OnPlayerProjbanPermission(TSPlayer player, ProjectileBan bannedProj) + /// Event result if the event has been handled, otherwise . + public static PermissionResult OnPlayerProjbanPermission(TSPlayer player, ProjectileBan bannedProj) { if (PlayerProjbanPermission == null) - return false; + return PermissionResult.Inconclusive; var args = new PlayerProjbanPermissionEventArgs(player, bannedProj); PlayerProjbanPermission(args); - return args.Handled; + + if (args.Handled) + return args.Result; + else + return PermissionResult.Inconclusive; } /// /// Fires the event. /// /// The player firing the event. - /// True if the event has been handled. - public static bool OnPlayerTilebanPermission(TSPlayer player, TileBan bannedTile) + /// Event result if the event has been handled, otherwise . + public static PermissionResult OnPlayerTilebanPermission(TSPlayer player, TileBan bannedTile) { if (PlayerTilebanPermission == null) - return false; + return PermissionResult.Inconclusive; var args = new PlayerTilebanPermissionEventArgs(player, bannedTile); PlayerTilebanPermission(args); - return args.Handled; + + if (args.Handled) + return args.Result; + else + return PermissionResult.Inconclusive; } + } + + /// + /// Defines the possible outcomes of handlers. + /// + public enum PermissionResult + { + /// Hook doesn't return a result on the permission check. + Inconclusive, + /// Permission is explicitly denied by a hook. + Denied, + /// Permission is explicitly granted by a hook. + Granted + } + } diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 8d0819bf..930c587b 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -1265,8 +1265,10 @@ namespace TShockAPI /// True if the player has that permission. public bool HasPermission(string permission) { - if (PlayerHooks.OnPlayerPermission(this, permission)) - return true; + PermissionResult hookResult = PlayerHooks.OnPlayerPermission(this, permission); + + if (hookResult != PermissionResult.Inconclusive) + return hookResult == PermissionResult.Granted; if (tempGroup != null) return tempGroup.HasPermission(permission); From 3764527d3d390091c4e12f14481cad54b2b0a63d Mon Sep 17 00:00:00 2001 From: Ruby Rose Date: Tue, 11 Jul 2017 16:29:48 +0300 Subject: [PATCH 024/430] don't inherit handled event args for them --- TShockAPI/Hooks/PlayerHooks.cs | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/TShockAPI/Hooks/PlayerHooks.cs b/TShockAPI/Hooks/PlayerHooks.cs index 7f2e8601..6e3db3d5 100644 --- a/TShockAPI/Hooks/PlayerHooks.cs +++ b/TShockAPI/Hooks/PlayerHooks.cs @@ -143,7 +143,7 @@ namespace TShockAPI.Hooks /// /// EventArgs used for the event. /// - public class PlayerPermissionEventArgs : HandledEventArgs + public class PlayerPermissionEventArgs { /// /// The player who fired the event. @@ -176,7 +176,7 @@ namespace TShockAPI.Hooks /// /// EventArgs used for the event. /// - public class PlayerItembanPermissionEventArgs : HandledEventArgs + public class PlayerItembanPermissionEventArgs { /// /// The player who fired the event. @@ -209,7 +209,7 @@ namespace TShockAPI.Hooks /// /// EventArgs used for the event. /// - public class PlayerProjbanPermissionEventArgs : HandledEventArgs + public class PlayerProjbanPermissionEventArgs { /// /// The player who fired the event. @@ -242,7 +242,7 @@ namespace TShockAPI.Hooks /// /// EventArgs used for the event. /// - public class PlayerTilebanPermissionEventArgs : HandledEventArgs + public class PlayerTilebanPermissionEventArgs { /// /// The player who fired the event. @@ -472,10 +472,7 @@ namespace TShockAPI.Hooks var args = new PlayerPermissionEventArgs(player, permission); PlayerPermission(args); - if (args.Handled) - return args.Result; - else - return PermissionResult.Inconclusive; + return args.Result; } /// @@ -491,10 +488,7 @@ namespace TShockAPI.Hooks var args = new PlayerItembanPermissionEventArgs(player, bannedItem); PlayerItembanPermission(args); - if (args.Handled) - return args.Result; - else - return PermissionResult.Inconclusive; + return args.Result; } /// @@ -510,10 +504,7 @@ namespace TShockAPI.Hooks var args = new PlayerProjbanPermissionEventArgs(player, bannedProj); PlayerProjbanPermission(args); - if (args.Handled) - return args.Result; - else - return PermissionResult.Inconclusive; + return args.Result; } /// @@ -529,10 +520,7 @@ namespace TShockAPI.Hooks var args = new PlayerTilebanPermissionEventArgs(player, bannedTile); PlayerTilebanPermission(args); - if (args.Handled) - return args.Result; - else - return PermissionResult.Inconclusive; + return args.Result; } } From 685d9964f0be1e36ace592e655f69cf416abaf66 Mon Sep 17 00:00:00 2001 From: Ruby Rose Date: Wed, 12 Jul 2017 08:47:27 +0300 Subject: [PATCH 025/430] Change enum names for clarity --- TShockAPI/DB/ItemManager.cs | 6 ++-- TShockAPI/DB/ProjectileManager.cs | 6 ++-- TShockAPI/DB/TileManager.cs | 6 ++-- TShockAPI/Hooks/PlayerHooks.cs | 52 +++++++++++++++---------------- TShockAPI/TSPlayer.cs | 6 ++-- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/TShockAPI/DB/ItemManager.cs b/TShockAPI/DB/ItemManager.cs index 54ae8ee5..c3d92840 100644 --- a/TShockAPI/DB/ItemManager.cs +++ b/TShockAPI/DB/ItemManager.cs @@ -201,9 +201,9 @@ namespace TShockAPI.DB if (ply.HasPermission(Permissions.usebanneditem)) return true; - PermissionResult hookResult = PlayerHooks.OnPlayerItembanPermission(ply, this); - if (hookResult != PermissionResult.Inconclusive) - return hookResult == PermissionResult.Granted; + PermissionHookResult hookResult = PlayerHooks.OnPlayerItembanPermission(ply, this); + if (hookResult != PermissionHookResult.Unhandled) + return hookResult == PermissionHookResult.Granted; var cur = ply.Group; var traversed = new List(); diff --git a/TShockAPI/DB/ProjectileManager.cs b/TShockAPI/DB/ProjectileManager.cs index 234d3cca..4214fce6 100644 --- a/TShockAPI/DB/ProjectileManager.cs +++ b/TShockAPI/DB/ProjectileManager.cs @@ -206,9 +206,9 @@ namespace TShockAPI.DB if (ply.HasPermission(Permissions.canusebannedprojectiles)) return true; - PermissionResult hookResult = PlayerHooks.OnPlayerProjbanPermission(ply, this); - if (hookResult != PermissionResult.Inconclusive) - return hookResult == PermissionResult.Granted; + PermissionHookResult hookResult = PlayerHooks.OnPlayerProjbanPermission(ply, this); + if (hookResult != PermissionHookResult.Unhandled) + return hookResult == PermissionHookResult.Granted; var cur = ply.Group; var traversed = new List(); diff --git a/TShockAPI/DB/TileManager.cs b/TShockAPI/DB/TileManager.cs index 83b079ab..c291b21a 100644 --- a/TShockAPI/DB/TileManager.cs +++ b/TShockAPI/DB/TileManager.cs @@ -206,9 +206,9 @@ namespace TShockAPI.DB if (ply.HasPermission(Permissions.canusebannedtiles)) return true; - PermissionResult hookResult = PlayerHooks.OnPlayerTilebanPermission(ply, this); - if (hookResult != PermissionResult.Inconclusive) - return hookResult == PermissionResult.Granted; + PermissionHookResult hookResult = PlayerHooks.OnPlayerTilebanPermission(ply, this); + if (hookResult != PermissionHookResult.Unhandled) + return hookResult == PermissionHookResult.Granted; var cur = ply.Group; var traversed = new List(); diff --git a/TShockAPI/Hooks/PlayerHooks.cs b/TShockAPI/Hooks/PlayerHooks.cs index 6e3db3d5..91f9612c 100644 --- a/TShockAPI/Hooks/PlayerHooks.cs +++ b/TShockAPI/Hooks/PlayerHooks.cs @@ -156,9 +156,9 @@ namespace TShockAPI.Hooks public string Permission { get; set; } /// - /// of the hook. + /// of the hook. /// - public PermissionResult Result { get; set; } + public PermissionHookResult Result { get; set; } /// /// Initializes a new instance of the PlayerPermissionEventArgs class. @@ -169,7 +169,7 @@ namespace TShockAPI.Hooks { Player = player; Permission = permission; - Result = PermissionResult.Inconclusive; + Result = PermissionHookResult.Unhandled; } } @@ -189,9 +189,9 @@ namespace TShockAPI.Hooks public ItemBan BannedItem { get; set; } /// - /// of the hook. + /// of the hook. /// - public PermissionResult Result { get; set; } + public PermissionHookResult Result { get; set; } /// /// Initializes a new instance of the PlayerItembanPermissionEventArgs class. @@ -202,7 +202,7 @@ namespace TShockAPI.Hooks { Player = player; BannedItem = bannedItem; - Result = PermissionResult.Inconclusive; + Result = PermissionHookResult.Unhandled; } } @@ -222,9 +222,9 @@ namespace TShockAPI.Hooks public ProjectileBan BannedProjectile { get; set; } /// - /// of the hook. + /// of the hook. /// - public PermissionResult Result { get; set; } + public PermissionHookResult Result { get; set; } /// /// Initializes a new instance of the PlayerProjbanPermissionEventArgs class. @@ -235,7 +235,7 @@ namespace TShockAPI.Hooks { Player = player; BannedProjectile = checkedProjectile; - Result = PermissionResult.Inconclusive; + Result = PermissionHookResult.Unhandled; } } @@ -255,9 +255,9 @@ namespace TShockAPI.Hooks public TileBan BannedTile { get; set; } /// - /// of the hook. + /// of the hook. /// - public PermissionResult Result { get; set; } + public PermissionHookResult Result { get; set; } /// /// Initializes a new instance of the PlayerTilebanPermissionEventArgs class. @@ -268,7 +268,7 @@ namespace TShockAPI.Hooks { Player = player; BannedTile = checkedTile; - Result = PermissionResult.Inconclusive; + Result = PermissionHookResult.Unhandled; } } @@ -463,11 +463,11 @@ namespace TShockAPI.Hooks /// Fires the event. /// /// The player firing the event. - /// Event result if the event has been handled, otherwise . - public static PermissionResult OnPlayerPermission(TSPlayer player, string permission) + /// Event result if the event has been handled, otherwise . + public static PermissionHookResult OnPlayerPermission(TSPlayer player, string permission) { if (PlayerPermission == null) - return PermissionResult.Inconclusive; + return PermissionHookResult.Unhandled; var args = new PlayerPermissionEventArgs(player, permission); PlayerPermission(args); @@ -479,11 +479,11 @@ namespace TShockAPI.Hooks /// Fires the event. /// /// The player firing the event. - /// Event result if the event has been handled, otherwise . - public static PermissionResult OnPlayerItembanPermission(TSPlayer player, ItemBan bannedItem) + /// Event result if the event has been handled, otherwise . + public static PermissionHookResult OnPlayerItembanPermission(TSPlayer player, ItemBan bannedItem) { if (PlayerItembanPermission == null) - return PermissionResult.Inconclusive; + return PermissionHookResult.Unhandled; var args = new PlayerItembanPermissionEventArgs(player, bannedItem); PlayerItembanPermission(args); @@ -495,11 +495,11 @@ namespace TShockAPI.Hooks /// Fires the event. /// /// The player firing the event. - /// Event result if the event has been handled, otherwise . - public static PermissionResult OnPlayerProjbanPermission(TSPlayer player, ProjectileBan bannedProj) + /// Event result if the event has been handled, otherwise . + public static PermissionHookResult OnPlayerProjbanPermission(TSPlayer player, ProjectileBan bannedProj) { if (PlayerProjbanPermission == null) - return PermissionResult.Inconclusive; + return PermissionHookResult.Unhandled; var args = new PlayerProjbanPermissionEventArgs(player, bannedProj); PlayerProjbanPermission(args); @@ -511,11 +511,11 @@ namespace TShockAPI.Hooks /// Fires the event. /// /// The player firing the event. - /// Event result if the event has been handled, otherwise . - public static PermissionResult OnPlayerTilebanPermission(TSPlayer player, TileBan bannedTile) + /// Event result if the event has been handled, otherwise . + public static PermissionHookResult OnPlayerTilebanPermission(TSPlayer player, TileBan bannedTile) { if (PlayerTilebanPermission == null) - return PermissionResult.Inconclusive; + return PermissionHookResult.Unhandled; var args = new PlayerTilebanPermissionEventArgs(player, bannedTile); PlayerTilebanPermission(args); @@ -528,10 +528,10 @@ namespace TShockAPI.Hooks /// /// Defines the possible outcomes of handlers. /// - public enum PermissionResult + public enum PermissionHookResult { /// Hook doesn't return a result on the permission check. - Inconclusive, + Unhandled, /// Permission is explicitly denied by a hook. Denied, /// Permission is explicitly granted by a hook. diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 930c587b..8f7b831e 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -1265,10 +1265,10 @@ namespace TShockAPI /// True if the player has that permission. public bool HasPermission(string permission) { - PermissionResult hookResult = PlayerHooks.OnPlayerPermission(this, permission); + PermissionHookResult hookResult = PlayerHooks.OnPlayerPermission(this, permission); - if (hookResult != PermissionResult.Inconclusive) - return hookResult == PermissionResult.Granted; + if (hookResult != PermissionHookResult.Unhandled) + return hookResult == PermissionHookResult.Granted; if (tempGroup != null) return tempGroup.HasPermission(permission); From 7f68053d3a8bee0a555d89353510f07bab7ce230 Mon Sep 17 00:00:00 2001 From: Ruby Rose Date: Tue, 11 Jul 2017 16:33:59 +0300 Subject: [PATCH 026/430] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa42a2aa..f0d0f29c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin ## Upcoming Changes +* API: Changed `PlayerHooks` permission hook mechanisms to allow negation from hooks (@deadsurgeon42) * Updated OpenTerraria API to 1.3.5.3 (@DeathCradle) * Updated Terraria Server API to 1.3.5.3 (@WhiteXZ, @hakusaro) * Updated TShock core components to 1.3.5.3 (@hakusaro) From 156ce5284518b8b4dceda0eb0a973930a1625b29 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Thu, 20 Jul 2017 18:10:16 -0600 Subject: [PATCH 027/430] Closes #1478 This addresses code feedback in the previously deleted pull request --- CHANGELOG.md | 1 + TShockAPI/StatTracker.cs | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91b371a2..d7ab5308 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Fixed saving when one player is one the server and another one joins (@MarioE) * Fixed /spawnmob not spawning negative IDs (@MarioE) * Validated tile placement on PlaceObject; clients can no longer place frames, paintings etc with dirt blocks (@bartico6, @ProfessorXZ) +* Updated to new stat tracking system with more data so we can actually make informed software decisions (Jordan Coulam) ## TShock 4.3.24 * API: Changed `PlayerHooks` permission hook mechanisms to allow negation from hooks (@deadsurgeon42) diff --git a/TShockAPI/StatTracker.cs b/TShockAPI/StatTracker.cs index d1c01c1c..47e5d2cc 100644 --- a/TShockAPI/StatTracker.cs +++ b/TShockAPI/StatTracker.cs @@ -160,10 +160,10 @@ namespace TShockAPI { if (plugins != null) { - return plugins;//Return early + return plugins; //Return early } - plugins = new PluginItem[ServerApi.Plugins.Count];//Initialize with enough room to store the ammount of plugins loaded. + plugins = new PluginItem[ServerApi.Plugins.Count]; //Initialize with enough room to store the ammount of plugins loaded. for (var i = 0; i < ServerApi.Plugins.Count; i++) { var pluginItem = new PluginItem(); @@ -181,10 +181,10 @@ namespace TShockAPI { if (totalMem != 0) { - return totalMem;//Return early + return totalMem; //Return early } - if (isMono)//Set totalMem so it can be returned later + if (isMono) //Set totalMem so it can be returned later { var pc = new PerformanceCounter("Mono Memory", "Total Physical Memory"); totalMem = (pc.RawValue / 1024 / 1024 / 1024); From 0753e6d2136231d0c0b456891ad874d352be07f3 Mon Sep 17 00:00:00 2001 From: Leo Li Date: Sun, 23 Jul 2017 20:42:42 -0700 Subject: [PATCH 028/430] Add more HintPaths for OTAPI This will help msbuild to find missing libraries when create release with `/p:Configuration=Release`. With this patch, the searching order will be: - If OTAPI with same configuration found, use that. - Else if OTAPI with Release configuration found, use that. - Else use OTAPI with Debug configuration. --- TShockAPI/TShockAPI.csproj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj index 9bf2ebd9..08e9323d 100644 --- a/TShockAPI/TShockAPI.csproj +++ b/TShockAPI/TShockAPI.csproj @@ -74,7 +74,9 @@ False - ..\TerrariaServerAPI\TerrariaServerAPI\bin\Debug\OTAPI.dll + ..\TerrariaServerAPI\TerrariaServerAPI\bin\Debug\OTAPI.dll + ..\TerrariaServerAPI\TerrariaServerAPI\bin\Release\OTAPI.dll + ..\TerrariaServerAPI\TerrariaServerAPI\bin\$(Configuration)\OTAPI.dll @@ -214,4 +216,4 @@ --> - \ No newline at end of file + From 7768511e6e7a778acbbde7e8c7d02aba2e1e45d6 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Sun, 23 Jul 2017 22:05:55 -0600 Subject: [PATCH 029/430] Update travis ci badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2d024912..2ad38b13 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

TShock for Terraria
- Build StatusAppVeyor Build Status
+ Build StatusAppVeyor Build Status


From 031ef517e3875e7be8edae0ae53b95052daff4a2 Mon Sep 17 00:00:00 2001 From: quake1337 Date: Fri, 4 Aug 2017 12:52:07 +0200 Subject: [PATCH 030/430] Change field visibility --- TShockAPI/Sockets/LinuxTcpSocket.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/TShockAPI/Sockets/LinuxTcpSocket.cs b/TShockAPI/Sockets/LinuxTcpSocket.cs index 98df1674..86381237 100644 --- a/TShockAPI/Sockets/LinuxTcpSocket.cs +++ b/TShockAPI/Sockets/LinuxTcpSocket.cs @@ -12,23 +12,23 @@ namespace TShockAPI.Sockets { public class LinuxTcpSocket : ISocket { - private byte[] _packetBuffer = new byte[1024]; + public byte[] _packetBuffer = new byte[1024]; - private int _packetBufferLength; + public int _packetBufferLength; - private List _callbackBuffer = new List(); + public List _callbackBuffer = new List(); - private int _messagesInQueue; + public int _messagesInQueue; - private TcpClient _connection; + public TcpClient _connection; - private TcpListener _listener; + public TcpListener _listener; - private SocketConnectionAccepted _listenerCallback; + public SocketConnectionAccepted _listenerCallback; - private RemoteAddress _remoteAddress; + public RemoteAddress _remoteAddress; - private bool _isListening; + public bool _isListening; public int MessagesInQueue { From 68437f0a224580de572737d853addadc06cc5970 Mon Sep 17 00:00:00 2001 From: quake1337 Date: Mon, 14 Aug 2017 14:39:22 +0200 Subject: [PATCH 031/430] Add "less than 2gb ram" warning --- TShockAPI/StatTracker.cs | 2 +- TShockAPI/TShock.cs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/TShockAPI/StatTracker.cs b/TShockAPI/StatTracker.cs index 47e5d2cc..61f42d14 100644 --- a/TShockAPI/StatTracker.cs +++ b/TShockAPI/StatTracker.cs @@ -177,7 +177,7 @@ namespace TShockAPI return plugins; } - private long GetTotalSystemRam(bool isMono) + public long GetTotalSystemRam(bool isMono) { if (totalMem != 0) { diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 022e70e5..8a109a08 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -329,6 +329,10 @@ namespace TShockAPI Log.ConsoleInfo("TShock {0} ({1}) now running.", Version, VersionCodename); + if (StatTracker.GetTotalSystemRam(ServerApi.RunningMono) < 2) + { + Log.ConsoleInfo("This machine has less than 2 gigabytes of RAM installed. Be advised that it might not be enough to run TShock."); + } ServerApi.Hooks.GamePostInitialize.Register(this, OnPostInit); ServerApi.Hooks.GameUpdate.Register(this, OnUpdate); ServerApi.Hooks.GameHardmodeTileUpdate.Register(this, OnHardUpdate); From 5a04b6651427dca02018effe87ab4ae208cf48fe Mon Sep 17 00:00:00 2001 From: ProfessorXZ Date: Fri, 8 Sep 2017 21:59:13 +0200 Subject: [PATCH 032/430] Make Utils.GetBuffDescription actually return the buff's description & properly read 'buffTime' from the stream. Fixes #1469 --- TShockAPI/GetDataHandlers.cs | 8 ++++---- TShockAPI/Utils.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 77e37c03..b593af2c 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -895,14 +895,14 @@ namespace TShockAPI /// /// Time the buff lasts /// - public short Time { get; set; } + public int Time { get; set; } } /// /// PlayerBuff - Called when a player is buffed /// public static HandlerList PlayerBuff; - private static bool OnPlayerBuff(byte id, byte type, short time) + private static bool OnPlayerBuff(byte id, byte type, int time) { if (PlayerBuff == null) return false; @@ -911,7 +911,7 @@ namespace TShockAPI { ID = id, Type = type, - Time = time, + Time = time }; PlayerBuff.Invoke(null, args); return args.Handled; @@ -3425,7 +3425,7 @@ namespace TShockAPI { var id = args.Data.ReadInt8(); var type = args.Data.ReadInt8(); - var time = args.Data.ReadInt16(); + var time = args.Data.ReadInt32(); if (OnPlayerBuff(id, type, time)) return true; diff --git a/TShockAPI/Utils.cs b/TShockAPI/Utils.cs index 520bed9c..5081f8e4 100644 --- a/TShockAPI/Utils.cs +++ b/TShockAPI/Utils.cs @@ -465,7 +465,7 @@ namespace TShockAPI /// description public string GetBuffDescription(int id) { - return (id > 0 && id < Main.maxBuffTypes) ? Lang.GetBuffName(id) : "null"; + return (id > 0 && id < Main.maxBuffTypes) ? Lang.GetBuffDescription(id) : "null"; } /// From c8549db08726122a5ea1cc62946fc1fe3249d625 Mon Sep 17 00:00:00 2001 From: koneko-nyan <31385587+koneko-nyan@users.noreply.github.com> Date: Tue, 19 Sep 2017 21:00:15 +0200 Subject: [PATCH 033/430] Update Commands.cs (time % 1.0) * 60.0 can be equal to 59.8, then it gets rounded to undesirable 60 displayed in the time format --- TShockAPI/Commands.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 5e7b84bf..fbc6c061 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -3872,7 +3872,7 @@ namespace TShockAPI if (!Main.dayTime) time += 15.0; time = time % 24.0; - args.Player.SendInfoMessage("The current time is {0}:{1:D2}.", (int)Math.Floor(time), (int)Math.Round((time % 1.0) * 60.0)); + args.Player.SendInfoMessage("The current time is {0}:{1:D2}.", (int)Math.Floor(time), (int)Math.Floor((time % 1.0) * 60.0)); return; } From 65582ceaecb4be28acecf88059a4bc4798e38bbd Mon Sep 17 00:00:00 2001 From: koneko-nyan <31385587+koneko-nyan@users.noreply.github.com> Date: Tue, 19 Sep 2017 21:22:56 +0200 Subject: [PATCH 034/430] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ab5308..efa71d54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Fixed /spawnmob not spawning negative IDs (@MarioE) * Validated tile placement on PlaceObject; clients can no longer place frames, paintings etc with dirt blocks (@bartico6, @ProfessorXZ) * Updated to new stat tracking system with more data so we can actually make informed software decisions (Jordan Coulam) +* Fixed /time display at the end of Terraria hours (@koneko-nyan) ## TShock 4.3.24 * API: Changed `PlayerHooks` permission hook mechanisms to allow negation from hooks (@deadsurgeon42) From e6ec63a90ee17ac374fba66a8ec3441e4ec8f421 Mon Sep 17 00:00:00 2001 From: quake1337 Date: Wed, 20 Sep 2017 09:27:28 +0200 Subject: [PATCH 035/430] Add @ijwu's changes + add /proc/meminfo trick for linux --- TShockAPI/StatTracker.cs | 38 +++++++++++++++++++++++++++++++++++--- TShockAPI/TShock.cs | 6 ++++-- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/TShockAPI/StatTracker.cs b/TShockAPI/StatTracker.cs index 61f42d14..1e4124b6 100644 --- a/TShockAPI/StatTracker.cs +++ b/TShockAPI/StatTracker.cs @@ -27,7 +27,8 @@ using System.Runtime.InteropServices; using System.Net.Http; using System.Threading.Tasks; using TShockAPI.Extensions; - +using System.IO; +using System.Text.RegularExpressions; namespace TShockAPI { @@ -176,7 +177,38 @@ namespace TShockAPI } return plugins; } - + public long GetFreeSystemRam(bool mono) + { + if (mono) + { + //Temporary in case mono won't work + if (File.Exists("/proc/meminfo")) + { + var l = File.ReadAllLines("/proc/meminfo"); + foreach (string s in l) + { + if (s.StartsWith("MemFree:")) + { + var m = Regex.Match(s, "MemFree:(\\s*)(\\d*) kB"); + if (m.Success) + { + long val; + if (long.TryParse(m.Groups[2].Value, out val)) + { + return val / 1024; + } + } + } + } + } + return -1; + } + else + { + var pc = new PerformanceCounter("Memory", "Available MBytes"); + return pc.RawValue; + } + } public long GetTotalSystemRam(bool isMono) { if (totalMem != 0) @@ -267,4 +299,4 @@ namespace TShockAPI /// public bool mono; } -} \ No newline at end of file +} diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 8a109a08..db15277b 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -329,10 +329,12 @@ namespace TShockAPI Log.ConsoleInfo("TShock {0} ({1}) now running.", Version, VersionCodename); - if (StatTracker.GetTotalSystemRam(ServerApi.RunningMono) < 2) + var systemRam = StatTracker.GetFreeSystemRam(ServerApi.RunningMono); + if (systemRam > -1 && systemRam < 2048) { - Log.ConsoleInfo("This machine has less than 2 gigabytes of RAM installed. Be advised that it might not be enough to run TShock."); + Log.ConsoleError("This machine has less than 2 gigabytes of RAM free. Be advised that it might not be enough to run TShock."); } + ServerApi.Hooks.GamePostInitialize.Register(this, OnPostInit); ServerApi.Hooks.GameUpdate.Register(this, OnUpdate); ServerApi.Hooks.GameHardmodeTileUpdate.Register(this, OnHardUpdate); From 4aa81a3d308998c83b6ce6269ccacbcc93284227 Mon Sep 17 00:00:00 2001 From: quake1337 Date: Wed, 20 Sep 2017 17:39:38 +0200 Subject: [PATCH 036/430] Add changes requested by @hakusaro --- TShockAPI/StatTracker.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TShockAPI/StatTracker.cs b/TShockAPI/StatTracker.cs index 1e4124b6..b59d5cbc 100644 --- a/TShockAPI/StatTracker.cs +++ b/TShockAPI/StatTracker.cs @@ -177,6 +177,12 @@ namespace TShockAPI } return plugins; } + + /// + /// Returns the amount of free RAM, in megabytes. + /// + /// Whether or not this program is being executed in a Mono runtime + /// Free RAM memory amount, in megabytes public long GetFreeSystemRam(bool mono) { if (mono) @@ -209,6 +215,11 @@ namespace TShockAPI return pc.RawValue; } } + /// + /// Returns the total amount of installed RAM, in gigabytes. + /// + /// Whether or not this program is being executed in a Mono runtime + /// Total RAM memory amount, in gigabytes public long GetTotalSystemRam(bool isMono) { if (totalMem != 0) From 7d5a74330a6e4b5a611e81abde5dda11336b8686 Mon Sep 17 00:00:00 2001 From: quake1337 Date: Wed, 20 Sep 2017 17:42:32 +0200 Subject: [PATCH 037/430] Ate one newline. --- TShockAPI/StatTracker.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/TShockAPI/StatTracker.cs b/TShockAPI/StatTracker.cs index b59d5cbc..1151d170 100644 --- a/TShockAPI/StatTracker.cs +++ b/TShockAPI/StatTracker.cs @@ -215,6 +215,7 @@ namespace TShockAPI return pc.RawValue; } } + /// /// Returns the total amount of installed RAM, in gigabytes. /// From d396dc5cbbd7d4de2b48b24d750ec2e6aeae5c9c Mon Sep 17 00:00:00 2001 From: quake1337 Date: Wed, 20 Sep 2017 18:42:36 +0200 Subject: [PATCH 038/430] Add CHANGELOG.md entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index efa71d54..2e455dab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Validated tile placement on PlaceObject; clients can no longer place frames, paintings etc with dirt blocks (@bartico6, @ProfessorXZ) * Updated to new stat tracking system with more data so we can actually make informed software decisions (Jordan Coulam) * Fixed /time display at the end of Terraria hours (@koneko-nyan) +* Added a warning notifying users of the minimum memory required to run TShock (@bartico6) ## TShock 4.3.24 * API: Changed `PlayerHooks` permission hook mechanisms to allow negation from hooks (@deadsurgeon42) From 02806a24297e22763fb47f509e17576dc08ad980 Mon Sep 17 00:00:00 2001 From: ProfessorXZ Date: Thu, 21 Sep 2017 10:51:37 +0200 Subject: [PATCH 039/430] Added support for renaming groups. Fixes #1420 --- CHANGELOG.md | 3 +- TShockAPI/Commands.cs | 24 ++++++ TShockAPI/DB/GroupManager.cs | 160 +++++++++++++++++++++++++++++++---- 3 files changed, 168 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e455dab..8e59d2ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin ## Upcoming Changes * API: Added hooks for item, projectile and tile bans (@deadsurgeon42) +* API: Changed `PlayerHooks` permission hook mechanisms to allow negation from hooks (@deadsurgeon42) * API: New WorldGrassSpread hook which shold allow corruption/crimson/hallow creep config options to work (@DeathCradle) * Fixed saving when one player is one the server and another one joins (@MarioE) * Fixed /spawnmob not spawning negative IDs (@MarioE) @@ -11,9 +12,9 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Updated to new stat tracking system with more data so we can actually make informed software decisions (Jordan Coulam) * Fixed /time display at the end of Terraria hours (@koneko-nyan) * Added a warning notifying users of the minimum memory required to run TShock (@bartico6) +* Added /group rename to allow changing group names (@ColinBohn, @ProfessorXZ) ## TShock 4.3.24 -* API: Changed `PlayerHooks` permission hook mechanisms to allow negation from hooks (@deadsurgeon42) * Updated OpenTerraria API to 1.3.5.3 (@DeathCradle) * Updated Terraria Server API to 1.3.5.3 (@WhiteXZ, @hakusaro) * Updated TShock core components to 1.3.5.3 (@hakusaro) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index fbc6c061..6fd3ca93 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -2865,6 +2865,7 @@ namespace TShockAPI "add - Adds a new group.", "addperm - Adds permissions to a group.", "color - Changes a group's chat color.", + "rename - Changes a group's name.", "del - Deletes a group.", "delperm - Removes permissions from a group.", "list [page] - Lists groups.", @@ -3074,6 +3075,29 @@ namespace TShockAPI } #endregion return; + case "rename": + #region Rename group + { + if (args.Parameters.Count != 3) + { + args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}group rename ", Specifier); + return; + } + + string group = args.Parameters[1]; + string newName = args.Parameters[2]; + try + { + string response = TShock.Groups.RenameGroup(group, newName); + args.Player.SendSuccessMessage(response); + } + catch (GroupManagerException ex) + { + args.Player.SendErrorMessage(ex.Message); + } + } + #endregion + return; case "del": #region Delete group { diff --git a/TShockAPI/DB/GroupManager.cs b/TShockAPI/DB/GroupManager.cs index 62bad891..0332379f 100644 --- a/TShockAPI/DB/GroupManager.cs +++ b/TShockAPI/DB/GroupManager.cs @@ -26,6 +26,9 @@ using MySql.Data.MySqlClient; namespace TShockAPI.DB { + /// + /// Represents the GroupManager, which is in charge of group management. + /// public class GroupManager : IEnumerable { private IDbConnection database; @@ -36,17 +39,17 @@ namespace TShockAPI.DB database = db; var table = new SqlTable("GroupList", - new SqlColumn("GroupName", MySqlDbType.VarChar, 32) {Primary = true}, - new SqlColumn("Parent", MySqlDbType.VarChar, 32), - new SqlColumn("Commands", MySqlDbType.Text), - new SqlColumn("ChatColor", MySqlDbType.Text), - new SqlColumn("Prefix", MySqlDbType.Text), - new SqlColumn("Suffix", MySqlDbType.Text) - ); + new SqlColumn("GroupName", MySqlDbType.VarChar, 32) { Primary = true }, + new SqlColumn("Parent", MySqlDbType.VarChar, 32), + new SqlColumn("Commands", MySqlDbType.Text), + new SqlColumn("ChatColor", MySqlDbType.Text), + new SqlColumn("Prefix", MySqlDbType.Text), + new SqlColumn("Suffix", MySqlDbType.Text) + ); var creator = new SqlTableCreator(db, - db.GetSqlType() == SqlType.Sqlite - ? (IQueryBuilder) new SqliteQueryCreator() - : new MysqlQueryCreator()); + db.GetSqlType() == SqlType.Sqlite + ? (IQueryBuilder)new SqliteQueryCreator() + : new MysqlQueryCreator()); if (creator.EnsureTableStructure(table)) { // Add default groups if they don't exist @@ -85,7 +88,11 @@ namespace TShockAPI.DB AddGroup(name, parent, permissions, Group.defaultChatColor); } - + /// + /// Determines whether the given group exists. + /// + /// The group. + /// true if it does; otherwise, false. public bool GroupExists(string group) { if (group == "superadmin") @@ -99,11 +106,20 @@ namespace TShockAPI.DB return GetEnumerator(); } + /// + /// Gets the enumerator. + /// + /// The enumerator. public IEnumerator GetEnumerator() { return groups.GetEnumerator(); } + /// + /// Gets the group matching the specified name. + /// + /// The name. + /// The group. public Group GetGroupByName(string name) { var ret = groups.Where(g => g.Name == name); @@ -139,8 +155,8 @@ namespace TShockAPI.DB } string query = (TShock.Config.StorageType.ToLower() == "sqlite") - ? "INSERT OR IGNORE INTO GroupList (GroupName, Parent, Commands, ChatColor) VALUES (@0, @1, @2, @3);" - : "INSERT IGNORE INTO GroupList SET GroupName=@0, Parent=@1, Commands=@2, ChatColor=@3"; + ? "INSERT OR IGNORE INTO GroupList (GroupName, Parent, Commands, ChatColor) VALUES (@0, @1, @2, @3);" + : "INSERT IGNORE INTO GroupList SET GroupName=@0, Parent=@1, Commands=@2, ChatColor=@3"; if (database.Query(query, name, parentname, permissions, chatcolor) == 1) { groups.Add(group); @@ -200,6 +216,70 @@ namespace TShockAPI.DB group.Suffix = suffix; } + /// + /// Renames the specified group. + /// + /// The group's name. + /// The new name. + /// The response. + public String RenameGroup(string name, string newName) + { + if (!GroupExists(name)) + { + throw new GroupNotExistException(name); + } + + if (GroupExists(newName)) + { + throw new GroupExistsException(newName); + } + + if (database.Query("UPDATE GroupList SET GroupName = @0 WHERE GroupName = @1", newName, name) == 1) + { + var oldGroup = GetGroupByName(name); + var newGroup = new Group(newName, oldGroup.Parent, oldGroup.ChatColor, oldGroup.Permissions) + { + Prefix = oldGroup.Prefix, + Suffix = oldGroup.Suffix + }; + + groups.Remove(oldGroup); + groups.Add(newGroup); + // We need to check if the old group has been referenced as a parent and update those references accordingly + database.Query("UPDATE GroupList SET Parent = @0 WHERE Parent = @1", newName, name); + foreach (var group in groups.Where(g => g.Parent != null && g.Parent == oldGroup)) + { + group.Parent = newGroup; + } + + if (TShock.Config.DefaultGuestGroupName == oldGroup.Name) + { + TShock.Config.DefaultGuestGroupName = newGroup.Name; + Group.DefaultGroup = newGroup; + } + if (TShock.Config.DefaultRegistrationGroupName == oldGroup.Name) + { + TShock.Config.DefaultRegistrationGroupName = newGroup.Name; + } + + TShock.Config.Write(FileTools.ConfigPath); + database.Query("UPDATE Users SET Usergroup = @0 WHERE Usergroup = @1", newName, name); + foreach (var player in TShock.Players.Where(p => p?.Group == oldGroup)) + { + player.Group = newGroup; + } + return $"Group \"{name}\" has been renamed to \"{newName}\"."; + } + + throw new GroupManagerException($"Failed to rename group \"{name}\"."); + } + + /// + /// Deletes the specified group. + /// + /// The group's name. + /// Whether exceptions will be thrown in case something goes wrong. + /// public String DeleteGroup(String name, bool exceptions = false) { if (!GroupExists(name)) @@ -214,12 +294,18 @@ namespace TShockAPI.DB groups.Remove(TShock.Utils.GetGroup(name)); return "Group " + name + " has been deleted successfully."; } - else if (exceptions) - throw new GroupManagerException("Failed to delete group '" + name + ".'"); - return ""; + if (exceptions) + throw new GroupManagerException("Failed to delete group '" + name + ".'"); + return "Failed to delete group '" + name + ".'"; } + /// + /// Enumerates the given permission list and adds permissions for the specified group accordingly. + /// + /// The group name. + /// The permission list. + /// public String AddPermissions(String name, List permissions) { if (!GroupExists(name)) @@ -237,6 +323,12 @@ namespace TShockAPI.DB return ""; } + /// + /// Enumerates the given permission list and removes valid permissions for the specified group accordingly. + /// + /// The group name. + /// The permission list. + /// public String DeletePermissions(String name, List permissions) { if (!GroupExists(name)) @@ -254,12 +346,15 @@ namespace TShockAPI.DB return ""; } + /// + /// Enumerates the group list and loads permissions for each group appropriately. + /// public void LoadPermisions() { try { List newGroups = new List(groups.Count); - Dictionary newGroupParents = new Dictionary(groups.Count); + Dictionary newGroupParents = new Dictionary(groups.Count); using (var reader = database.QueryReader("SELECT * FROM GroupList")) { while (reader.Read()) @@ -271,7 +366,8 @@ namespace TShockAPI.DB continue; } - newGroups.Add(new Group(groupName, null, reader.Get("ChatColor"), reader.Get("Commands")) { + newGroups.Add(new Group(groupName, null, reader.Get("ChatColor"), reader.Get("Commands")) + { Prefix = reader.Get("Prefix"), Suffix = reader.Get("Suffix"), }); @@ -360,32 +456,60 @@ namespace TShockAPI.DB } } + /// + /// Represents the base GroupManager exception. + /// [Serializable] public class GroupManagerException : Exception { + /// + /// Initializes a new instance of the with the specified message. + /// + /// The message. public GroupManagerException(string message) : base(message) { } + /// + /// Initializes a new instance of the with the specified message and inner exception. + /// + /// The message. + /// The inner exception. public GroupManagerException(string message, Exception inner) : base(message, inner) { } } + /// + /// Represents the GroupExists exception. + /// This exception is thrown whenever an attempt to add an existing group into the database is made. + /// [Serializable] public class GroupExistsException : GroupManagerException { + /// + /// Initializes a new instance of the with the specified group name. + /// + /// The group name. public GroupExistsException(string name) : base("Group '" + name + "' already exists") { } } + /// + /// Represents the GroupNotExist exception. + /// This exception is thrown whenever we try to access a group that does not exist. + /// [Serializable] public class GroupNotExistException : GroupManagerException { + /// + /// Initializes a new instance of the with the specified group name. + /// + /// The group name. public GroupNotExistException(string name) : base("Group '" + name + "' does not exist") { From 08e182f59e1f4fc679c8535152239ad4291fceeb Mon Sep 17 00:00:00 2001 From: ProfessorXZ Date: Sat, 23 Sep 2017 22:41:41 +0200 Subject: [PATCH 040/430] All GroupManager.RenameGroup() database calls are now done in a transaction As pointed out by @hakusaro, in order to prevent any damage during the process all database calls need to be done in a transaction. Transactions allow us to rollback from a pending state in case something goes wrong. --- TShockAPI/Commands.cs | 32 +++++----- TShockAPI/DB/GroupManager.cs | 110 +++++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 48 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 6fd3ca93..c171c1e0 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -3077,25 +3077,25 @@ namespace TShockAPI return; case "rename": #region Rename group - { - if (args.Parameters.Count != 3) { - args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}group rename ", Specifier); - return; - } + if (args.Parameters.Count != 3) + { + args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}group rename ", Specifier); + return; + } - string group = args.Parameters[1]; - string newName = args.Parameters[2]; - try - { - string response = TShock.Groups.RenameGroup(group, newName); - args.Player.SendSuccessMessage(response); + string group = args.Parameters[1]; + string newName = args.Parameters[2]; + try + { + string response = TShock.Groups.RenameGroup(group, newName); + args.Player.SendSuccessMessage(response); + } + catch (GroupManagerException ex) + { + args.Player.SendErrorMessage(ex.Message); + } } - catch (GroupManagerException ex) - { - args.Player.SendErrorMessage(ex.Message); - } - } #endregion return; case "del": diff --git a/TShockAPI/DB/GroupManager.cs b/TShockAPI/DB/GroupManager.cs index 0332379f..78596083 100644 --- a/TShockAPI/DB/GroupManager.cs +++ b/TShockAPI/DB/GroupManager.cs @@ -34,6 +34,10 @@ namespace TShockAPI.DB private IDbConnection database; public readonly List groups = new List(); + /// + /// Initializes a new instance of the class with the specified database connection. + /// + /// The connection. public GroupManager(IDbConnection db) { database = db; @@ -234,41 +238,83 @@ namespace TShockAPI.DB throw new GroupExistsException(newName); } - if (database.Query("UPDATE GroupList SET GroupName = @0 WHERE GroupName = @1", newName, name) == 1) + using (var db = database.CloneEx()) { - var oldGroup = GetGroupByName(name); - var newGroup = new Group(newName, oldGroup.Parent, oldGroup.ChatColor, oldGroup.Permissions) + db.Open(); + using (var transaction = db.BeginTransaction()) { - Prefix = oldGroup.Prefix, - Suffix = oldGroup.Suffix - }; + try + { + using (var command = db.CreateCommand()) + { + command.CommandText = "UPDATE GroupList SET GroupName = @0 WHERE GroupName = @1"; + command.AddParameter("@0", newName); + command.AddParameter("@1", name); + command.ExecuteNonQuery(); + } - groups.Remove(oldGroup); - groups.Add(newGroup); - // We need to check if the old group has been referenced as a parent and update those references accordingly - database.Query("UPDATE GroupList SET Parent = @0 WHERE Parent = @1", newName, name); - foreach (var group in groups.Where(g => g.Parent != null && g.Parent == oldGroup)) - { - group.Parent = newGroup; - } + var oldGroup = GetGroupByName(name); + var newGroup = new Group(newName, oldGroup.Parent, oldGroup.ChatColor, oldGroup.Permissions) + { + Prefix = oldGroup.Prefix, + Suffix = oldGroup.Suffix + }; + groups.Remove(oldGroup); + groups.Add(newGroup); - if (TShock.Config.DefaultGuestGroupName == oldGroup.Name) - { - TShock.Config.DefaultGuestGroupName = newGroup.Name; - Group.DefaultGroup = newGroup; - } - if (TShock.Config.DefaultRegistrationGroupName == oldGroup.Name) - { - TShock.Config.DefaultRegistrationGroupName = newGroup.Name; - } + // We need to check if the old group has been referenced as a parent and update those references accordingly + using (var command = db.CreateCommand()) + { + command.CommandText = "UPDATE GroupList SET Parent = @0 WHERE Parent = @1"; + command.AddParameter("@0", newName); + command.AddParameter("@1", name); + command.ExecuteNonQuery(); + } + foreach (var group in groups.Where(g => g.Parent != null && g.Parent == oldGroup)) + { + group.Parent = newGroup; + } - TShock.Config.Write(FileTools.ConfigPath); - database.Query("UPDATE Users SET Usergroup = @0 WHERE Usergroup = @1", newName, name); - foreach (var player in TShock.Players.Where(p => p?.Group == oldGroup)) - { - player.Group = newGroup; + if (TShock.Config.DefaultGuestGroupName == oldGroup.Name) + { + TShock.Config.DefaultGuestGroupName = newGroup.Name; + Group.DefaultGroup = newGroup; + } + if (TShock.Config.DefaultRegistrationGroupName == oldGroup.Name) + { + TShock.Config.DefaultRegistrationGroupName = newGroup.Name; + } + TShock.Config.Write(FileTools.ConfigPath); + + // We also need to check if any users belong to the old group and automatically apply changes + using (var command = db.CreateCommand()) + { + command.CommandText = "UPDATE Users SET Usergroup = @0 WHERE Usergroup = @1"; + command.AddParameter("@0", newName); + command.AddParameter("@1", name); + command.ExecuteNonQuery(); + } + foreach (var player in TShock.Players.Where(p => p?.Group == oldGroup)) + { + player.Group = newGroup; + } + + transaction.Commit(); + return $"Group \"{name}\" has been renamed to \"{newName}\"."; + } + catch (Exception ex) + { + TShock.Log.Error($"An exception has occured during database transaction: {ex.Message}"); + try + { + transaction.Rollback(); + } + catch (Exception rollbackEx) + { + TShock.Log.Error($"An exception has occured during database rollback: {rollbackEx.Message}"); + } + } } - return $"Group \"{name}\" has been renamed to \"{newName}\"."; } throw new GroupManagerException($"Failed to rename group \"{name}\"."); @@ -279,7 +325,7 @@ namespace TShockAPI.DB /// /// The group's name. /// Whether exceptions will be thrown in case something goes wrong. - /// + /// The response. public String DeleteGroup(String name, bool exceptions = false) { if (!GroupExists(name)) @@ -305,7 +351,7 @@ namespace TShockAPI.DB /// /// The group name. /// The permission list. - /// + /// The response. public String AddPermissions(String name, List permissions) { if (!GroupExists(name)) @@ -328,7 +374,7 @@ namespace TShockAPI.DB /// /// The group name. /// The permission list. - /// + /// The response. public String DeletePermissions(String name, List permissions) { if (!GroupExists(name)) From ec435e266e99e63068db97227fe9666140438b3d Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 25 Sep 2017 12:18:41 -0600 Subject: [PATCH 041/430] Make our string based error handling more explicit (Please, someone, please, get rid of this). --- TShockAPI/DB/GroupManager.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TShockAPI/DB/GroupManager.cs b/TShockAPI/DB/GroupManager.cs index 78596083..6a7d8c4d 100644 --- a/TShockAPI/DB/GroupManager.cs +++ b/TShockAPI/DB/GroupManager.cs @@ -225,7 +225,7 @@ namespace TShockAPI.DB /// /// The group's name. /// The new name. - /// The response. + /// The result from the operation to be sent back to the user. public String RenameGroup(string name, string newName) { if (!GroupExists(name)) @@ -325,7 +325,7 @@ namespace TShockAPI.DB /// /// The group's name. /// Whether exceptions will be thrown in case something goes wrong. - /// The response. + /// The result from the operation to be sent back to the user. public String DeleteGroup(String name, bool exceptions = false) { if (!GroupExists(name)) @@ -351,7 +351,7 @@ namespace TShockAPI.DB /// /// The group name. /// The permission list. - /// The response. + /// The result from the operation to be sent back to the user. public String AddPermissions(String name, List permissions) { if (!GroupExists(name)) @@ -374,7 +374,7 @@ namespace TShockAPI.DB /// /// The group name. /// The permission list. - /// The response. + /// The result from the operation to be sent back to the user. public String DeletePermissions(String name, List permissions) { if (!GroupExists(name)) From 6f8d795a65d0d553bcfc831d3b3aa9a6b41b3383 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 25 Sep 2017 12:28:25 -0600 Subject: [PATCH 042/430] Switch to msbuild commands Fixes #1494 --- scripts/create_release.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/create_release.py b/scripts/create_release.py index 3a25f76d..735c664c 100755 --- a/scripts/create_release.py +++ b/scripts/create_release.py @@ -145,7 +145,7 @@ def update_terraria_source(): def run_bootstrapper(): for build_config in ['Debug','Release'] : - mintaka = subprocess.Popen(['xbuild', './TerrariaServerAPI/TShock.4.OTAPI.sln', '/p:Configuration=' + build_config]) + mintaka = subprocess.Popen(['msbuild', './TerrariaServerAPI/TShock.4.OTAPI.sln', '/p:Configuration=' + build_config]) mintaka.wait() @@ -161,7 +161,7 @@ def run_bootstrapper(): if (bootstrapper_proc.returncode != 0): raise CalledProcessError(bootstrapper_proc.returncode) - tsapi_proc = subprocess.Popen(['xbuild', './TerrariaServerAPI/TerrariaServerAPI/TerrariaServerAPI.csproj', '/p:Configuration=' + build_config]) + tsapi_proc = subprocess.Popen(['msbuild', './TerrariaServerAPI/TerrariaServerAPI/TerrariaServerAPI.csproj', '/p:Configuration=' + build_config]) tsapi_proc.wait() @@ -169,8 +169,8 @@ def run_bootstrapper(): raise CalledProcessError(tsapi_proc.returncode) def build_software(): - release_proc = subprocess.Popen(['xbuild', './TShockAPI/TShockAPI.csproj', '/p:Configuration=Release']) - debug_proc = subprocess.Popen(['xbuild', './TShockAPI/TShockAPI.csproj', '/p:Configuration=Debug']) + release_proc = subprocess.Popen(['msbuild', './TShockAPI/TShockAPI.csproj', '/p:Configuration=Release']) + debug_proc = subprocess.Popen(['msbuild', './TShockAPI/TShockAPI.csproj', '/p:Configuration=Debug']) release_proc.wait() debug_proc.wait() if (release_proc.returncode != 0): From 639ffb3c7cc21d9db20e08e1eae6bcfadc3b1f8b Mon Sep 17 00:00:00 2001 From: ProfessorXZ Date: Thu, 28 Sep 2017 16:40:03 +0200 Subject: [PATCH 043/430] Fix GroupManager.RenameGroup() overwriting unsaved config changes --- TShockAPI/DB/GroupManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TShockAPI/DB/GroupManager.cs b/TShockAPI/DB/GroupManager.cs index 6a7d8c4d..7d4f5a1b 100644 --- a/TShockAPI/DB/GroupManager.cs +++ b/TShockAPI/DB/GroupManager.cs @@ -275,6 +275,8 @@ namespace TShockAPI.DB group.Parent = newGroup; } + // Read the config file to prevent the possible loss of any unsaved changes + TShock.Config = ConfigFile.Read(FileTools.ConfigPath); if (TShock.Config.DefaultGuestGroupName == oldGroup.Name) { TShock.Config.DefaultGuestGroupName = newGroup.Name; From d652fd6c83558e2b058f3788714fe53f6c960e7f Mon Sep 17 00:00:00 2001 From: koneko-nyan <31385587+koneko-nyan@users.noreply.github.com> Date: Mon, 2 Oct 2017 17:36:50 +0200 Subject: [PATCH 044/430] Add OnRegionRenamed hook --- TShockAPI/Hooks/RegionHooks.cs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/TShockAPI/Hooks/RegionHooks.cs b/TShockAPI/Hooks/RegionHooks.cs index 9f1b1e78..dcf8d6ce 100644 --- a/TShockAPI/Hooks/RegionHooks.cs +++ b/TShockAPI/Hooks/RegionHooks.cs @@ -110,5 +110,29 @@ namespace TShockAPI.Hooks RegionDeleted(new RegionDeletedEventArgs(region)); } + + public class RegionRenamedEventArgs + { + public Region Region { get; private set; } + public string OldName { get; private set; } + public string NewName { get; private set; } + + public RegionRenamedEventArgs(Region region, string oldName, string newName) + { + Region = region; + OldName = oldName; + NewName = newName; + } + } + + public delegate void RegionRenamedD(RegionRenamedEventArgs args); + public static event RegionRenamedD RegionRenamed; + public static void OnRegionRenamed(Region region, string oldName, string newName) + { + if (RegionRenamed == null) + return; + + RegionRenamed(new RegionRenamedEventArgs(region, oldName, newName)); + } } } From f5f516d409cc17b74d6f1e358dae7e00e813c068 Mon Sep 17 00:00:00 2001 From: koneko-nyan <31385587+koneko-nyan@users.noreply.github.com> Date: Mon, 2 Oct 2017 17:39:07 +0200 Subject: [PATCH 045/430] Add a CHANGELOG.md entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e455dab..94698e0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Updated to new stat tracking system with more data so we can actually make informed software decisions (Jordan Coulam) * Fixed /time display at the end of Terraria hours (@koneko-nyan) * Added a warning notifying users of the minimum memory required to run TShock (@bartico6) +* Added /region rename and OnRegionRenamed hook (@koneko-nyan, @deadsurgeon42) ## TShock 4.3.24 * API: Changed `PlayerHooks` permission hook mechanisms to allow negation from hooks (@deadsurgeon42) From 30475be268d1be3ddeb938ae56386d12f7f011a8 Mon Sep 17 00:00:00 2001 From: koneko-nyan <31385587+koneko-nyan@users.noreply.github.com> Date: Mon, 2 Oct 2017 17:42:22 +0200 Subject: [PATCH 046/430] Add RegionRename --- TShockAPI/DB/RegionManager.cs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/TShockAPI/DB/RegionManager.cs b/TShockAPI/DB/RegionManager.cs index 661ec1c5..8649dedf 100644 --- a/TShockAPI/DB/RegionManager.cs +++ b/TShockAPI/DB/RegionManager.cs @@ -401,7 +401,41 @@ namespace TShockAPI.DB } return false; } + + /// + /// Renames a region + /// + /// Name of the region to rename + /// New name of the region + /// true if renamed successfully, false otherwise + public bool RenameRegion(string oldName, string newName) + { + Region region = null; + string worldID = Main.worldID.ToString(); + bool result = false; + + try + { + int q = database.Query("UPDATE Regions SET RegionName = @0 WHERE RegionName=@1 AND WorldID=@2", + newName, oldName, worldID); + + if (q > 0) + { + region = Regions.First(r => r.Name == oldName && r.WorldID == worldID); + region.Name = newName; + Hooks.RegionHooks.OnRegionRenamed(region, oldName, newName); + result = true; + } + } + catch (Exception ex) + { + TShock.Log.Error(ex.ToString()); + } + + return result; + } + /// /// Removes an allowed user from a region /// From aaa84d1ba9c010dae726b207a1dab6bfc0de518e Mon Sep 17 00:00:00 2001 From: koneko-nyan <31385587+koneko-nyan@users.noreply.github.com> Date: Mon, 2 Oct 2017 17:45:57 +0200 Subject: [PATCH 047/430] Add 'rename' sub-command to /region --- TShockAPI/Commands.cs | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index fbc6c061..615ba59f 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -4530,6 +4530,51 @@ namespace TShockAPI args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}region resize ", Specifier); break; } + case "rename": + { + if (args.Parameters.Count != 3) + { + args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}region rename ", Specifier); + break; + } + else + { + string oldName = args.Parameters[1]; + string newName = args.Parameters[2]; + + if (oldName == newName) + { + args.Player.SendErrorMessage("Error: both names are the same."); + break; + } + + Region oldRegion = TShock.Regions.GetRegionByName(oldName); + + if (oldRegion == null) + { + args.Player.SendErrorMessage("Invalid region \"{0}\".", oldName); + break; + } + + Region newRegion = TShock.Regions.GetRegionByName(newName); + + if (newRegion != null) + { + args.Player.SendErrorMessage("Region \"{0}\" already exists.", newName); + break; + } + + if(TShock.Regions.RenameRegion(oldName, newName)) + { + args.Player.SendInfoMessage("Region renamed successfully!"); + } + else + { + args.Player.SendErrorMessage("Failed to rename the region."); + } + } + break; + } case "tp": { if (!args.Player.HasPermission(Permissions.tp)) @@ -4570,6 +4615,7 @@ namespace TShockAPI "define - Defines the region with the given name.", "delete - Deletes the given region.", "name [-u][-z][-p] - Shows the name of the region at the given point.", + "rename - Renames the given region.", "list - Lists all regions.", "resize - Resizes a region.", "allow - Allows a user to a region.", From 7f9d76f71fe3d9f6d154b102263d995a09e5586a Mon Sep 17 00:00:00 2001 From: Innectic Date: Fri, 6 Oct 2017 12:52:33 -0700 Subject: [PATCH 048/430] Put Github files where they belong Closes #1495 --- CONTRIBUTING.md => .github/CONTRIBUTING.md | 0 PULL_REQUEST_TEMPLATE.md => .github/PULL_REQUEST_TEMPLATE.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename CONTRIBUTING.md => .github/CONTRIBUTING.md (100%) rename PULL_REQUEST_TEMPLATE.md => .github/PULL_REQUEST_TEMPLATE.md (100%) diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md diff --git a/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from PULL_REQUEST_TEMPLATE.md rename to .github/PULL_REQUEST_TEMPLATE.md From 70019002c9013fe99cc5505d8c1060b6087edacb Mon Sep 17 00:00:00 2001 From: Innectic Date: Fri, 6 Oct 2017 12:58:17 -0700 Subject: [PATCH 049/430] Add issue template --- .github/ISSUE_TEMPLATE.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..2b249480 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,11 @@ + +## TShock version + + +## Any stack traces that may have happened when the issue occurred + + +## Steps to reproduce + + +## Screenshots of the problem, if applicable From 9d12461f8d8f1ca3a57c8c5b5c0b150324767e28 Mon Sep 17 00:00:00 2001 From: koneko-nyan <31385587+koneko-nyan@users.noreply.github.com> Date: Fri, 13 Oct 2017 09:12:56 +0200 Subject: [PATCH 050/430] Fix some spaces --- TShockAPI/DB/RegionManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/DB/RegionManager.cs b/TShockAPI/DB/RegionManager.cs index 8649dedf..f94b2a48 100644 --- a/TShockAPI/DB/RegionManager.cs +++ b/TShockAPI/DB/RegionManager.cs @@ -417,7 +417,7 @@ namespace TShockAPI.DB try { - int q = database.Query("UPDATE Regions SET RegionName = @0 WHERE RegionName=@1 AND WorldID=@2", + int q = database.Query("UPDATE Regions SET RegionName = @0 WHERE RegionName = @1 AND WorldID = @2", newName, oldName, worldID); if (q > 0) From 744c8123234f2c2276b6bdc368d4be132903270e Mon Sep 17 00:00:00 2001 From: Ziteng Wang Date: Mon, 20 Nov 2017 14:51:42 -0800 Subject: [PATCH 051/430] Fix item frame not working properly --- TShockAPI/GetDataHandlers.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index b593af2c..2fa9cbd0 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -2109,7 +2109,9 @@ namespace TShockAPI 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 && ((args.TPlayer.mount.Type != 8 && selectedItem.pick == 0) && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0)) + // Item frames can be modified without pickaxe tile. + else if (tile.type != TileID.ItemFrame + && !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; @@ -4376,12 +4378,6 @@ namespace TShockAPI return true; } - if (itemFrame.item?.netID == args.TPlayer.inventory[args.TPlayer.selectedItem]?.netID) - { - NetMessage.SendData((int)PacketTypes.UpdateTileEntity, -1, -1, NetworkText.Empty, itemFrame.ID, 0, 1); - return true; - } - return false; } From 9dee0aee7d6b1a401c8855d60035cc8fc01615d9 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Fri, 1 Dec 2017 23:12:06 -0700 Subject: [PATCH 052/430] Rewrote the /ban add sub command /ban add now replaces add, addtemp, and addip. New syntax: /ban add [time] [reason] Examples: - /ban add Shank 10d Rewrote the ban system. - /ban add Ash - /ban add 127.0.0.1 5d Go work on homework. Note that if you want to specify a reason and a permaban, you need to use 0 (zero) as the duration. Examples: - /ban add Ash 0 Love ya. - /ban add Shank 0 Hacking. Closes #1510 --- TShockAPI/Commands.cs | 341 +++++++++++++++++++++--------------------- 1 file changed, 171 insertions(+), 170 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 493aa956..87559392 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -35,6 +35,7 @@ using Terraria.GameContent.Events; using Microsoft.Xna.Framework; using OTAPI.Tile; using TShockAPI.Localization; +using System.Text.RegularExpressions; namespace TShockAPI { @@ -1273,200 +1274,202 @@ namespace TShockAPI switch (subcmd) { case "add": - #region Add ban + #region Add Ban { if (args.Parameters.Count < 2) { - args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}ban add [reason]", Specifier); + args.Player.SendErrorMessage("Invalid command. Format: {0}ban add [time] [reason]", Specifier); + args.Player.SendErrorMessage("Example: {0}ban add Shank 10d Hacking and cheating", Specifier); + args.Player.SendErrorMessage("Example: {0}ban add Ash", Specifier); + args.Player.SendErrorMessage("Use the time 0 (zero) for a permanent ban."); return; } + // Used only to notify if a ban was successful and who the ban was about + bool success = false; + string targetGeneralizedName = ""; + + // What if caller is console? Name? + + // Effective ban target assignment List players = TShock.Utils.FindPlayer(args.Parameters[1]); - string reason = args.Parameters.Count > 2 ? String.Join(" ", args.Parameters.Skip(2)) : "Misbehavior."; - if (players.Count == 0) + User offlineUser = TShock.Users.GetUserByName(args.Parameters[1]); + + // Determines if the caller is effective root for overriding permissions + bool callerIsEffectiveRoot = false; + + // A ban source is effective root if they are not not real and not rest + // Super admins ingame who attempt to run this will have to remove + // the immune to ban permission if they want to ban an immune player + if (!(args.Player is TSRestPlayer) && !args.Player.RealPlayer) { - var user = TShock.Users.GetUserByName(args.Parameters[1]); - if (user != null) - { - bool force = !args.Player.RealPlayer; - - if (user.Name == args.Player.Name && !force) - { - args.Player.SendErrorMessage("You can't ban yourself!"); - return; - } - - if (TShock.Groups.GetGroupByName(user.Group).HasPermission(Permissions.immunetoban) && !force) - args.Player.SendErrorMessage("You can't ban {0}!", user.Name); - else - { - if (user.KnownIps == null) - { - args.Player.SendErrorMessage("Cannot ban {0} because they have no IPs to ban.", user.Name); - return; - } - var knownIps = JsonConvert.DeserializeObject>(user.KnownIps); - TShock.Bans.AddBan(knownIps.Last(), user.Name, user.UUID, reason, false, args.Player.User.Name); - if (String.IsNullOrWhiteSpace(args.Player.User.Name)) - { - if (args.Silent) - { - args.Player.SendInfoMessage("{0} was {1}banned for '{2}'.", user.Name, force ? "Force " : "", reason); - } - else - { - TSPlayer.All.SendInfoMessage("{0} was {1}banned for '{2}'.", user.Name, force ? "Force " : "", reason); - } - } - else - { - if (args.Silent) - { - args.Player.SendInfoMessage("{0}banned {1} for '{2}'.", force ? "Force " : "", user.Name, reason); - } - else - { - TSPlayer.All.SendInfoMessage("{0} {1}banned {2} for '{3}'.", args.Player.Name, force ? "Force " : "", user.Name, reason); - } - } - } - } - else - args.Player.SendErrorMessage("Invalid player or account!"); + callerIsEffectiveRoot = true; } - else if (players.Count > 1) + + // The ban reason the ban is going to have + string banReason = "Unknown."; + + // The default ban length + // 0 is permanent ban, otherwise temp ban + int banLengthInSeconds = 0; + + // Figure out if param 2 is a time or 0 or garbage + if (args.Parameters.Count >= 3) + { + bool parsedOkay = false; + if (!(args.Parameters[2] == "0")) + { + parsedOkay = TShock.Utils.TryParseTime(args.Parameters[2], out banLengthInSeconds); + } else { + parsedOkay = true; + } + + if (!parsedOkay) + { + args.Player.SendErrorMessage("Invalid time format. Example: 10d+5h+3m-2s."); + args.Player.SendErrorMessage("Use 0 (zero) for a permanent ban."); + return; + } + } + + // If a reason exists, use the given reason. + if (args.Parameters.Count > 3) + { + banReason = String.Join(" ", args.Parameters.Skip(3)); + } + + // Bad case: Players contains more than 1 person so we can't ban them + if (players.Count > 1) + { TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); - else - { - if (!TShock.Utils.Ban(players[0], reason, !args.Player.RealPlayer, args.Player.User.Name)) - args.Player.SendErrorMessage("You can't ban {0}!", players[0].Name); - } - } - #endregion - return; - case "addip": - #region Add IP ban - { - if (args.Parameters.Count < 2) - { - args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}ban addip [reason]", Specifier); return; } - string ip = args.Parameters[1]; - string reason = args.Parameters.Count > 2 - ? String.Join(" ", args.Parameters.GetRange(2, args.Parameters.Count - 2)) - : "Manually added IP address ban."; - TShock.Bans.AddBan(ip, "", "", reason, false, args.Player.User.Name); - args.Player.SendSuccessMessage("Banned IP {0}.", ip); - } - #endregion - return; - case "addtemp": - #region Add temp ban - { - if (args.Parameters.Count < 3) + // Good case: Online ban for matching character. + if (players.Count == 1) { - args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}ban addtemp