Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added AccountGroupUpdate hook, when trying to change a user group. #2947

Open
wants to merge 8 commits into
base: general-devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion TShockAPI/Commands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,7 @@ private static void ManageUsers(CommandArgs args)

try
{
TShock.UserAccounts.SetUserGroup(account, args.Parameters[2]);
TShock.UserAccounts.SetUserGroup(args.Player, account, args.Parameters[2]);
TShock.Log.ConsoleInfo(GetString("{0} changed account {1} to group {2}.", args.Player.Name, account.Name, args.Parameters[2]));
args.Player.SendSuccessMessage(GetString("Account {0} has been changed to group {1}.", account.Name, args.Parameters[2]));

Expand All @@ -1193,6 +1193,10 @@ private static void ManageUsers(CommandArgs args)
{
args.Player.SendErrorMessage(GetString($"User {account.Name} does not exist."));
}
catch (UserGroupUpdateLockedException)
{
args.Player.SendErrorMessage(GetString("Hook blocked the attempt to change the user group."));
}
catch (UserAccountManagerException e)
{
args.Player.SendErrorMessage(GetString($"User {account.Name} could not be added. Check console for details."));
Expand Down
53 changes: 51 additions & 2 deletions TShockAPI/DB/UserManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ You should have received a copy of the GNU General Public License
using System.Text.RegularExpressions;
using BCrypt.Net;
using System.Security.Cryptography;
using TShockAPI.Hooks;

namespace TShockAPI.DB
{
Expand Down Expand Up @@ -166,7 +167,41 @@ public void SetUserGroup(UserAccount account, string group)
if (null == grp)
throw new GroupNotExistsException(group);

if (_database.Query("UPDATE Users SET UserGroup = @0 WHERE Username = @1;", group, account.Name) == 0)
if (AccountHooks.OnAccountGroupUpdate(account, ref grp))
throw new UserGroupUpdateLockedException(account.Name);

if (_database.Query("UPDATE Users SET UserGroup = @0 WHERE Username = @1;", grp.Name, account.Name) == 0)
throw new UserAccountNotExistException(account.Name);

try
{
// Update player group reference for any logged in player
foreach (var player in TShock.Players.Where(p => p != null && p.Account != null && p.Account.Name == account.Name))
{
player.Group = grp;
}
}
catch (Exception ex)
{
throw new UserAccountManagerException(GetString("SetUserGroup SQL returned an error"), ex);
}
}
/// <summary>
/// Sets the group for a given username
/// </summary>
/// <param name="author">Who changes the group</param>
/// <param name="account">The user account</param>
/// <param name="group">The user account group to be set</param>
public void SetUserGroup(TSPlayer author, UserAccount account, string group)
{
Group grp = TShock.Groups.GetGroupByName(group);
if (null == grp)
throw new GroupNotExistsException(group);

if (AccountHooks.OnAccountGroupUpdate(account, author, ref grp))
throw new UserGroupUpdateLockedException(account.Name);

if (_database.Query("UPDATE Users SET UserGroup = @0 WHERE Username = @1;", grp.Name, account.Name) == 0)
throw new UserAccountNotExistException(account.Name);

try
Expand Down Expand Up @@ -619,14 +654,28 @@ public UserAccountExistsException(string name)
public class UserAccountNotExistException : UserAccountManagerException
{
/// <summary>Creates a new UserAccountNotExistException object, with the user account name in the message.</summary>
/// <param name="name">The user account name to be pasesd in the message.</param>
/// <param name="name">The user account name to be passed in the message.</param>
/// <returns>A new UserAccountNotExistException object with a message containing the user account name that does not exist.</returns>
public UserAccountNotExistException(string name)
: base(GetString($"User account {name} does not exist"))
{
}
}

/// <summary>The UserGroupUpdateLockedException used when the user group update failed and the request failed as a result.</summary>.
[Serializable]
public class UserGroupUpdateLockedException : UserAccountManagerException
{
/// <summary>Creates a new UserGroupUpdateLockedException object.</summary>
/// <param name="name">The name of the user who failed to change the group.</param>
/// <returns>New UserGroupUpdateLockedException object with a message containing the name of the user account that failed to change the group.</returns>
public UserGroupUpdateLockedException(string name) :
base(GetString($"Unable to update group of user {name}."))
{
}
}


/// <summary>A GroupNotExistsException, used when a group does not exist.</summary>
[Serializable]
public class GroupNotExistsException : UserAccountManagerException
Expand Down
46 changes: 46 additions & 0 deletions TShockAPI/Hooks/AccountHooks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

using System.ComponentModel;
using TShockAPI.DB;
namespace TShockAPI.Hooks
{
Expand All @@ -39,6 +40,31 @@ public AccountCreateEventArgs(UserAccount account)
}
}

public class AccountGroupUpdateEventArgs : HandledEventArgs
{
public string AccountName { get; private set; }
public Group Group { get; set; }

public AccountGroupUpdateEventArgs(string accountName, Group group)
{
this.AccountName = accountName;
this.Group = group;
}
}

public class AccountGroupUpdateByPlayerEventArgs : AccountGroupUpdateEventArgs
{
/// <summary>
/// The player who updated the user's group
/// </summary>
public TSPlayer Player { get; private set; }

public AccountGroupUpdateByPlayerEventArgs(TSPlayer player, string accountName, Group group) : base(accountName, group)
{
this.Player = player;
}
}

public class AccountHooks
{
public delegate void AccountCreateD(AccountCreateEventArgs e);
Expand All @@ -62,5 +88,25 @@ public static void OnAccountDelete(UserAccount u)

AccountDelete(new AccountDeleteEventArgs(u));
}

public delegate void AccountGroupUpdateD(AccountGroupUpdateEventArgs e);
public static event AccountGroupUpdateD AccountGroupUpdate;

public static bool OnAccountGroupUpdate(UserAccount account, TSPlayer author, ref Group group)
{
AccountGroupUpdateEventArgs args = new AccountGroupUpdateByPlayerEventArgs(author, account.Name, group);
AccountGroupUpdate?.Invoke(args);
group = args.Group;

return args.Handled;
}
public static bool OnAccountGroupUpdate(UserAccount account, ref Group group)
{
AccountGroupUpdateEventArgs args = new AccountGroupUpdateEventArgs(account.Name, group);
AccountGroupUpdate?.Invoke(args);
group = args.Group;

return args.Handled;
}
}
}
3 changes: 2 additions & 1 deletion TShockAPI/Rest/RestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,8 @@ private object UserUpdateV2(RestRequestArgs args)
{
try
{
TShock.UserAccounts.SetUserGroup(account, group);
TShock.UserAccounts.SetUserGroup(new TSRestPlayer(args.TokenData.Username, TShock.Groups.GetGroupByName(args.TokenData.UserGroupName)),
account, group);
response.Add("group-response", "Group updated successfully");
}
catch (Exception e)
Expand Down
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ Use past tense when adding new entries; sign your name off when you add or chang
* Added a method `TSPlayer.GiveItem`, which has `TShockAPI.NetItem` structure in its arguments. (@AgaSpace)
* Added a property `TSPlayer.Hostile`, which gets pvp player mode. (@AgaSpace)
* Fixed typo in `/gbuff`. (@sgkoishi, #2955)
* Added a hook `AccountHooks.AccountGroupUpdate`, which is called when you change the user group. (@AgaSpace)

## TShock 5.2
* An additional option `pvpwithnoteam` is added at `PvPMode` to enable PVP with no team. (@CelestialAnarchy, #2617, @ATFGK)
Expand Down