From 0753e6d2136231d0c0b456891ad874d352be07f3 Mon Sep 17 00:00:00 2001 From: Leo Li Date: Sun, 23 Jul 2017 20:42:42 -0700 Subject: [PATCH 1/8] 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 02806a24297e22763fb47f509e17576dc08ad980 Mon Sep 17 00:00:00 2001 From: ProfessorXZ Date: Thu, 21 Sep 2017 10:51:37 +0200 Subject: [PATCH 2/8] 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 3/8] 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 4/8] 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 5/8] 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 6/8] 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 7f9d76f71fe3d9f6d154b102263d995a09e5586a Mon Sep 17 00:00:00 2001 From: Innectic Date: Fri, 6 Oct 2017 12:52:33 -0700 Subject: [PATCH 7/8] 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 8/8] 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