Skip to content

Instantly share code, notes, and snippets.

@hakusaro
Last active October 10, 2022 08:41
Show Gist options
  • Save hakusaro/735d9a7f1dcd652d9e6fe8f10aa50842 to your computer and use it in GitHub Desktop.
Save hakusaro/735d9a7f1dcd652d9e6fe8f10aa50842 to your computer and use it in GitHub Desktop.
EasyCommands vs OldCommands alternatives
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2019 Pryaxis & TShock Contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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 EasyCommands;
using EasyCommands.Commands;
using System;
using System.Linq;
using TShockAPI;
using TShockAPI.DB;
using TShockCommands.Annotations;
namespace TShockCommands.Commands;
[Command("user")]
[HelpText("Manages user accounts.")]
[CommandPermissions(Permissions.user)]
class UserCommands : CommandCallbacks<TSPlayer>
{
[SubCommand(SubCommandType.Default)]
public void Default() => Help();
[SubCommand("help")]
public void Help()
{
Sender.SendInfoMessage("Use command help:");
Sender.SendInfoMessage("{0}user add username password group -- Adds a specified user", TextOptions.CommandPrefix);
Sender.SendInfoMessage("{0}user del username -- Removes a specified user", TextOptions.CommandPrefix);
Sender.SendInfoMessage("{0}user password username newpassword -- Changes a user's password", TextOptions.CommandPrefix);
Sender.SendInfoMessage("{0}user group username newgroup -- Changes a user's group", TextOptions.CommandPrefix);
}
[SubCommand]
public void Add(string username, string password, string group)
{
var account = new UserAccount();
account.Name = username;
try
{
account.CreateBCryptHash(password);
}
catch (ArgumentOutOfRangeException)
{
Sender.SendErrorMessage("Password must be greater than or equal to " + TShock.Config.Settings.MinimumPasswordLength + " characters.");
return;
}
account.Group = group;
try
{
TShock.UserAccounts.AddUserAccount(account);
Sender.SendSuccessMessage("Account " + account.Name + " has been added to group " + account.Group + "!");
TShock.Log.ConsoleInfo(Sender.Name + " added Account " + account.Name + " to group " + account.Group);
}
catch (GroupNotExistsException)
{
Sender.SendErrorMessage("Group " + account.Group + " does not exist!");
}
catch (UserAccountExistsException)
{
Sender.SendErrorMessage("User " + account.Name + " already exists!");
}
catch (UserAccountManagerException e)
{
Sender.SendErrorMessage("User " + account.Name + " could not be added, check console for details.");
TShock.Log.ConsoleError(e.ToString());
}
}
[SubCommand("del", "delete")]
public void Delete(string username)
{
var account = new UserAccount();
account.Name = username;
try
{
TShock.UserAccounts.RemoveUserAccount(account);
Sender.SendSuccessMessage("Account removed successfully.");
TShock.Log.ConsoleInfo(Sender.Name + " successfully deleted account: " + username + ".");
}
catch (UserAccountNotExistException)
{
Sender.SendErrorMessage("The user " + account.Name + " does not exist! Deleted nobody!");
}
catch (UserAccountManagerException ex)
{
Sender.SendErrorMessage(ex.Message);
TShock.Log.ConsoleError(ex.ToString());
}
}
[SubCommand]
public void Password(string username, string newpassword)
{
var account = new UserAccount();
account.Name = username;
try
{
TShock.UserAccounts.SetUserAccountPassword(account, newpassword);
TShock.Log.ConsoleInfo(Sender.Name + " changed the password of account " + account.Name);
Sender.SendSuccessMessage("Password change succeeded for " + account.Name + ".");
}
catch (UserAccountNotExistException)
{
Sender.SendErrorMessage("User " + account.Name + " does not exist!");
}
catch (UserAccountManagerException e)
{
Sender.SendErrorMessage("Password change for " + account.Name + " failed! Check console!");
TShock.Log.ConsoleError(e.ToString());
}
catch (ArgumentOutOfRangeException)
{
Sender.SendErrorMessage("Password must be greater than or equal to " + TShock.Config.Settings.MinimumPasswordLength + " characters.");
}
}
[SubCommand]
public void Group(string username, string newgroup/*, CommandArgs args*/)
{
var account = new UserAccount();
account.Name = username;
try
{
TShock.UserAccounts.SetUserGroup(account, newgroup);
TShock.Log.ConsoleInfo(Sender.Name + " changed account " + account.Name + " to group " + newgroup + ".");
Sender.SendSuccessMessage("Account " + account.Name + " has been changed to group " + newgroup + "!");
//send message to player with matching account name
var player = TShock.Players.FirstOrDefault(p => p != null && p.Account?.Name == account.Name);
if (player != null /*&& !args.Silent*/)
player.SendSuccessMessage($"{Sender.Name} has changed your group to {newgroup}");
}
catch (GroupNotExistsException)
{
Sender.SendErrorMessage("That group does not exist!");
}
catch (UserAccountNotExistException)
{
Sender.SendErrorMessage("User " + account.Name + " does not exist!");
}
catch (UserAccountManagerException e)
{
Sender.SendErrorMessage("User " + account.Name + " could not be added. Check console for details.");
TShock.Log.ConsoleError(e.ToString());
}
}
}
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2019 Pryaxis & TShock Contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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 Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using Terraria;
using Terraria.ID;
using Terraria.Localization;
using TShockAPI.DB;
using TerrariaApi.Server;
using TShockAPI.Hooks;
using Terraria.GameContent.Events;
using Microsoft.Xna.Framework;
using TShockAPI.Localization;
using System.Text.RegularExpressions;
using Terraria.DataStructures;
using Terraria.GameContent.Creative;
namespace TShockAPI
{
public delegate void CommandDelegate(CommandArgs args);
public class CommandArgs : EventArgs
{
public string Message { get; private set; }
public TSPlayer Player { get; private set; }
public bool Silent { get; private set; }
/// <summary>
/// Parameters passed to the argument. Does not include the command name.
/// IE '/kick "jerk face"' will only have 1 argument
/// </summary>
public List<string> Parameters { get; private set; }
public Player TPlayer
{
get { return Player.TPlayer; }
}
public CommandArgs(string message, TSPlayer ply, List<string> args)
{
Message = message;
Player = ply;
Parameters = args;
Silent = false;
}
public CommandArgs(string message, bool silent, TSPlayer ply, List<string> args)
{
Message = message;
Player = ply;
Parameters = args;
Silent = silent;
}
}
public class Command
{
/// <summary>
/// Gets or sets whether to allow non-players to use this command.
/// </summary>
public bool AllowServer { get; set; }
/// <summary>
/// Gets or sets whether to do logging of this command.
/// </summary>
public bool DoLog { get; set; }
/// <summary>
/// Gets or sets the help text of this command.
/// </summary>
public string HelpText { get; set; }
/// <summary>
/// Gets or sets an extended description of this command.
/// </summary>
public string[] HelpDesc { get; set; }
/// <summary>
/// Gets the name of the command.
/// </summary>
public string Name { get { return Names[0]; } }
/// <summary>
/// Gets the names of the command.
/// </summary>
public List<string> Names { get; protected set; }
/// <summary>
/// Gets the permissions of the command.
/// </summary>
public List<string> Permissions { get; protected set; }
private CommandDelegate commandDelegate;
public CommandDelegate CommandDelegate
{
get { return commandDelegate; }
set
{
if (value == null)
throw new ArgumentNullException();
commandDelegate = value;
}
}
public Command(List<string> permissions, CommandDelegate cmd, params string[] names)
: this(cmd, names)
{
Permissions = permissions;
}
public Command(string permissions, CommandDelegate cmd, params string[] names)
: this(cmd, names)
{
Permissions = new List<string> { permissions };
}
public Command(CommandDelegate cmd, params string[] names)
{
if (cmd == null)
throw new ArgumentNullException("cmd");
if (names == null || names.Length < 1)
throw new ArgumentException("names");
AllowServer = true;
CommandDelegate = cmd;
DoLog = true;
HelpText = "No help available.";
HelpDesc = null;
Names = new List<string>(names);
Permissions = new List<string>();
}
public bool Run(string msg, bool silent, TSPlayer ply, List<string> parms)
{
if (!CanRun(ply))
return false;
try
{
CommandDelegate(new CommandArgs(msg, silent, ply, parms));
}
catch (Exception e)
{
ply.SendErrorMessage("Command failed, check logs for more details.");
TShock.Log.Error(e.ToString());
}
return true;
}
public bool Run(string msg, TSPlayer ply, List<string> parms)
{
return Run(msg, false, ply, parms);
}
public bool HasAlias(string name)
{
return Names.Contains(name);
}
public bool CanRun(TSPlayer ply)
{
if (Permissions == null || Permissions.Count < 1)
return true;
foreach (var Permission in Permissions)
{
if (ply.HasPermission(Permission))
return true;
}
return false;
}
}
public static class Commands
{
public static List<Command> ChatCommands = new List<Command>();
public static ReadOnlyCollection<Command> TShockCommands = new ReadOnlyCollection<Command>(new List<Command>());
/// <summary>
/// The command specifier, defaults to "/"
/// </summary>
public static string Specifier
{
get { return string.IsNullOrWhiteSpace(TShock.Config.Settings.CommandSpecifier) ? "/" : TShock.Config.Settings.CommandSpecifier; }
}
/// <summary>
/// The silent command specifier, defaults to "."
/// </summary>
public static string SilentSpecifier
{
get { return string.IsNullOrWhiteSpace(TShock.Config.Settings.CommandSilentSpecifier) ? "." : TShock.Config.Settings.CommandSilentSpecifier; }
}
private delegate void AddChatCommand(string permission, CommandDelegate command, params string[] names);
public static void InitCommands()
{
List<Command> tshockCommands = new List<Command>(100);
add(new Command(Permissions.user, ManageUsers, "user")
{
DoLog = false,
HelpText = "Manages user accounts."
});
TShockCommands = new ReadOnlyCollection<Command>(tshockCommands);
}
// ...
// Unrelated code removed for brevity
// ...
private static void ManageUsers(CommandArgs args)
{
// This guy needs to be here so that people don't get exceptions when they type /user
if (args.Parameters.Count < 1)
{
args.Player.SendErrorMessage("Invalid user syntax. Try {0}user help.", Specifier);
return;
}
string subcmd = args.Parameters[0];
// Add requires a username, password, and a group specified.
if (subcmd == "add" && args.Parameters.Count == 4)
{
var account = new UserAccount();
account.Name = args.Parameters[1];
try
{
account.CreateBCryptHash(args.Parameters[2]);
}
catch (ArgumentOutOfRangeException)
{
args.Player.SendErrorMessage("Password must be greater than or equal to " + TShock.Config.Settings.MinimumPasswordLength + " characters.");
return;
}
account.Group = args.Parameters[3];
try
{
TShock.UserAccounts.AddUserAccount(account);
args.Player.SendSuccessMessage("Account " + account.Name + " has been added to group " + account.Group + "!");
TShock.Log.ConsoleInfo(args.Player.Name + " added Account " + account.Name + " to group " + account.Group);
}
catch (GroupNotExistsException)
{
args.Player.SendErrorMessage("Group " + account.Group + " does not exist!");
}
catch (UserAccountExistsException)
{
args.Player.SendErrorMessage("User " + account.Name + " already exists!");
}
catch (UserAccountManagerException e)
{
args.Player.SendErrorMessage("User " + account.Name + " could not be added, check console for details.");
TShock.Log.ConsoleError(e.ToString());
}
}
// User deletion requires a username
else if (subcmd == "del" && args.Parameters.Count == 2)
{
var account = new UserAccount();
account.Name = args.Parameters[1];
try
{
TShock.UserAccounts.RemoveUserAccount(account);
args.Player.SendSuccessMessage("Account removed successfully.");
TShock.Log.ConsoleInfo(args.Player.Name + " successfully deleted account: " + args.Parameters[1] + ".");
}
catch (UserAccountNotExistException)
{
args.Player.SendErrorMessage("The user " + account.Name + " does not exist! Deleted nobody!");
}
catch (UserAccountManagerException ex)
{
args.Player.SendErrorMessage(ex.Message);
TShock.Log.ConsoleError(ex.ToString());
}
}
// Password changing requires a username, and a new password to set
else if (subcmd == "password" && args.Parameters.Count == 3)
{
var account = new UserAccount();
account.Name = args.Parameters[1];
try
{
TShock.UserAccounts.SetUserAccountPassword(account, args.Parameters[2]);
TShock.Log.ConsoleInfo(args.Player.Name + " changed the password of account " + account.Name);
args.Player.SendSuccessMessage("Password change succeeded for " + account.Name + ".");
}
catch (UserAccountNotExistException)
{
args.Player.SendErrorMessage("User " + account.Name + " does not exist!");
}
catch (UserAccountManagerException e)
{
args.Player.SendErrorMessage("Password change for " + account.Name + " failed! Check console!");
TShock.Log.ConsoleError(e.ToString());
}
catch (ArgumentOutOfRangeException)
{
args.Player.SendErrorMessage("Password must be greater than or equal to " + TShock.Config.Settings.MinimumPasswordLength + " characters.");
}
}
// Group changing requires a username or IP address, and a new group to set
else if (subcmd == "group" && args.Parameters.Count == 3)
{
var account = new UserAccount();
account.Name = args.Parameters[1];
try
{
TShock.UserAccounts.SetUserGroup(account, args.Parameters[2]);
TShock.Log.ConsoleInfo(args.Player.Name + " changed account " + account.Name + " to group " + args.Parameters[2] + ".");
args.Player.SendSuccessMessage("Account " + account.Name + " has been changed to group " + args.Parameters[2] + "!");
//send message to player with matching account name
var player = TShock.Players.FirstOrDefault(p => p != null && p.Account?.Name == account.Name);
if (player != null && !args.Silent)
player.SendSuccessMessage($"{args.Player.Name} has changed your group to {args.Parameters[2]}");
}
catch (GroupNotExistsException)
{
args.Player.SendErrorMessage("That group does not exist!");
}
catch (UserAccountNotExistException)
{
args.Player.SendErrorMessage("User " + account.Name + " does not exist!");
}
catch (UserAccountManagerException e)
{
args.Player.SendErrorMessage("User " + account.Name + " could not be added. Check console for details.");
TShock.Log.ConsoleError(e.ToString());
}
}
else if (subcmd == "help")
{
args.Player.SendInfoMessage("Use command help:");
args.Player.SendInfoMessage("{0}user add username password group -- Adds a specified user", Specifier);
args.Player.SendInfoMessage("{0}user del username -- Removes a specified user", Specifier);
args.Player.SendInfoMessage("{0}user password username newpassword -- Changes a user's password", Specifier);
args.Player.SendInfoMessage("{0}user group username newgroup -- Changes a user's group", Specifier);
}
else
{
args.Player.SendErrorMessage("Invalid user syntax. Try {0}user help.", Specifier);
}
}
// ...
// Unrelated commands removed for brevity
// ...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment