/*
TShock, a server mod for Terraria
Copyright (C) 2011 The TShock Team
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 .
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;
using System.Diagnostics;
using System.Net;
using System.Threading;
using Microsoft.Xna.Framework;
using Terraria;
using TShockAPI.DB;
namespace TShockAPI
{
public delegate void CommandDelegate(CommandArgs args);
public class CommandArgs : EventArgs
{
public string Message { get; private set; }
public TSPlayer Player { get; private set; }
///
/// Parameters passed to the arguement. Does not include the command name.
/// IE '/kick "jerk face"' will only have 1 argument
///
public List Parameters { get; private set; }
public Player TPlayer
{
get { return Player.TPlayer; }
}
public CommandArgs(string message, TSPlayer ply, List args)
{
Message = message;
Player = ply;
Parameters = args;
}
}
public class Command
{
public string Name { get { return Names[0]; } }
public List Names { get; protected set; }
public bool DoLog { get; set; }
private string permission;
private CommandDelegate command;
public Command(string permissionneeded, CommandDelegate cmd, params string[] names)
: this(cmd, names)
{
permission = permissionneeded;
}
public Command(CommandDelegate cmd, params string[] names)
{
if (names == null || names.Length < 1)
throw new NotSupportedException();
permission = null;
Names = new List(names);
command = cmd;
DoLog = true;
}
public bool Run(string msg, TSPlayer ply, List parms)
{
if (!ply.Group.HasPermission(permission))
return false;
try
{
command(new CommandArgs(msg, ply, parms));
}
catch (Exception e)
{
ply.SendMessage("Command failed, check logs for more details.");
Log.Error(e.ToString());
}
return true;
}
public bool HasAlias(string name)
{
return Names.Contains(name);
}
public bool CanRun(TSPlayer ply)
{
return ply.Group.HasPermission(permission);
}
}
public static class Commands
{
public static List ChatCommands = new List();
public static void InitCommands()
{
ChatCommands.Add(new Command("kick", Kick, "kick"));
ChatCommands.Add(new Command("ban", Ban, "ban"));
ChatCommands.Add(new Command("ban", BanIP, "banip"));
ChatCommands.Add(new Command("unban", UnBan, "unban"));
ChatCommands.Add(new Command("unban", UnBanIP, "unbanip"));
ChatCommands.Add(new Command("maintenance", ClearBans, "clearbans"));
ChatCommands.Add(new Command("whitelist", Whitelist, "whitelist"));
ChatCommands.Add(new Command("maintenance", Off, "off"));
ChatCommands.Add(new Command("maintenance", OffNoSave, "off-nosave"));
ChatCommands.Add(new Command("maintenance", CheckUpdates, "checkupdates"));
ChatCommands.Add(new Command("causeevents", DropMeteor, "dropmeteor"));
ChatCommands.Add(new Command("causeevents", Star, "star"));
ChatCommands.Add(new Command("causeevents", Bloodmoon, "bloodmoon"));
ChatCommands.Add(new Command("causeevents", Invade, "invade"));
ChatCommands.Add(new Command("spawnboss", Eater, "eater"));
ChatCommands.Add(new Command("spawnboss", Eye, "eye"));
ChatCommands.Add(new Command("spawnboss", King, "king"));
ChatCommands.Add(new Command("spawnboss", Skeletron, "skeletron"));
ChatCommands.Add(new Command("spawnboss", Hardcore, "hardcore"));
ChatCommands.Add(new Command("spawnmob", SpawnMob, "spawnmob", "sm"));
ChatCommands.Add(new Command("tp", Home, "home"));
ChatCommands.Add(new Command("tp", Spawn, "spawn"));
ChatCommands.Add(new Command("tp", TP, "tp"));
ChatCommands.Add(new Command("tphere", TPHere, "tphere"));
ChatCommands.Add(new Command("warp", UseWarp, "warp"));
ChatCommands.Add(new Command("managewarp", SetWarp, "setwarp"));
ChatCommands.Add(new Command("managewarp", DeleteWarp, "delwarp"));
ChatCommands.Add(new Command("cfg", SetSpawn, "setspawn"));
ChatCommands.Add(new Command("cfg", Reload, "reload"));
ChatCommands.Add(new Command("cfg", DebugConfiguration, "debug-config"));
ChatCommands.Add(new Command("cfg", Password, "password"));
ChatCommands.Add(new Command("cfg", Save, "save"));
ChatCommands.Add(new Command("cfg", MaxSpawns, "maxspawns"));
ChatCommands.Add(new Command("cfg", SpawnRate, "spawnrate"));
ChatCommands.Add(new Command("time", Time, "time"));
ChatCommands.Add(new Command("pvpfun", Slap, "slap"));
ChatCommands.Add(new Command("editspawn", ToggleAntiBuild, "antibuild"));
ChatCommands.Add(new Command("editspawn", ProtectSpawn, "protectspawn"));
ChatCommands.Add(new Command("editspawn", Region, "region"));
ChatCommands.Add(new Command("editspawn", DebugRegions, "debugreg"));
ChatCommands.Add(new Command(Help, "help"));
ChatCommands.Add(new Command(Playing, "playing", "online", "who"));
ChatCommands.Add(new Command(AuthToken, "auth"));
ChatCommands.Add(new Command(ThirdPerson, "me"));
ChatCommands.Add(new Command(PartyChat, "p"));
ChatCommands.Add(new Command(Rules, "rules"));
ChatCommands.Add(new Command("logs", DisplayLogs, "displaylogs"));
ChatCommands.Add(new Command(PasswordUser, "password") { DoLog = false });
ChatCommands.Add(new Command(RegisterUser, "register") { DoLog = false });
ChatCommands.Add(new Command("root-only", ManageUsers, "user") { DoLog = false });
ChatCommands.Add(new Command("root-only", GrabUserIP, "ip"));
ChatCommands.Add(new Command("root-only", AuthVerify, "auth-verify"));
ChatCommands.Add(new Command(AttemptLogin, "login") { DoLog = false });
ChatCommands.Add(new Command("cfg", Broadcast, "broadcast", "bc"));
ChatCommands.Add(new Command("whisper", Whisper, "whisper", "w", "tell"));
ChatCommands.Add(new Command("whisper", Reply, "reply", "r"));
ChatCommands.Add(new Command("annoy", Annoy, "annoy"));
ChatCommands.Add(new Command("cfg", ConvertWaR, "convert"));
if (TShock.Config.DistributationAgent != "terraria-online")
{
ChatCommands.Add(new Command("kill", Kill, "kill"));
ChatCommands.Add(new Command("butcher", Butcher, "butcher"));
ChatCommands.Add(new Command("item", Item, "item", "i"));
ChatCommands.Add(new Command("item", Give, "give"));
ChatCommands.Add(new Command("heal", Heal, "heal"));
}
}
public static bool HandleCommand(TSPlayer player, string text)
{
string cmdText = text.Remove(0, 1);
var args = ParseParameters(cmdText);
if (args.Count < 1)
return false;
string cmdName = args[0];
args.RemoveAt(0);
Command cmd = ChatCommands.FirstOrDefault(c => c.HasAlias(cmdName));
if (cmd == null)
return false;
if (!cmd.CanRun(player))
{
Tools.SendLogs(string.Format("{0} tried to execute {1}", player.Name, cmd.Name), Color.Red);
player.SendMessage("You do not have access to that command.", Color.Red);
}
else
{
if (cmd.DoLog)
Tools.SendLogs(string.Format("{0} executed: /{1}", player.Name, cmdText), Color.Red);
cmd.Run(cmdText, player, args);
}
return true;
}
///
/// Parses a string of parameters into a list. Handles quotes.
///
///
///
private static List ParseParameters(string str)
{
var ret = new List();
var sb = new StringBuilder();
bool instr = false;
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
if (instr)
{
if (c == '\\')
{
if (i + 1 >= str.Length)
break;
c = GetEscape(str[++i]);
}
else if (c == '"')
{
ret.Add(sb.ToString());
sb.Clear();
instr = false;
continue;
}
sb.Append(c);
}
else
{
if (IsWhiteSpace(c))
{
if (sb.Length > 0)
{
ret.Add(sb.ToString());
sb.Clear();
}
}
else if (c == '"')
{
if (sb.Length > 0)
{
ret.Add(sb.ToString());
sb.Clear();
}
instr = true;
}
else
{
sb.Append(c);
}
}
}
if (sb.Length > 0)
ret.Add(sb.ToString());
return ret;
}
private static char GetEscape(char c)
{
switch (c)
{
case '\\':
return '\\';
case '"':
return '"';
case 't':
return '\t';
default:
return c;
}
}
private static bool IsWhiteSpace(char c)
{
return c == ' ' || c == '\t' || c == '\n';
}
#region Account commands
public static void AttemptLogin(CommandArgs args)
{
if (args.Player.LoginAttempts > TShock.Config.MaximumLoginAttempts && (TShock.Config.MaximumLoginAttempts != -1))
{
Log.Warn(args.Player.IP + "(" + args.Player.Name + ") had " + TShock.Config.MaximumLoginAttempts + " or more invalid login attempts and was kicked automatically.");
Tools.Kick(args.Player, "Too many invalid login attempts.");
}
if (args.Parameters.Count != 2)
{
args.Player.SendMessage("Syntax: /login [username] [password]");
args.Player.SendMessage("If you forgot your password, there is no way to recover it.");
return;
}
try
{
string encrPass = Tools.HashPassword(args.Parameters[1]);
string[] exr = TShock.Users.FetchHashedPasswordAndGroup(args.Parameters[0]);
if (exr[0].ToUpper() == encrPass.ToUpper())
{
args.Player.Group = Tools.GetGroup(exr[1]);
args.Player.UserAccountName = args.Parameters[0];
args.Player.UserID = TShock.Users.GetUserID(args.Player.UserAccountName);
args.Player.IsLoggedIn = true;
args.Player.SendMessage("Authenticated as " + args.Parameters[0] + " successfully.", Color.LimeGreen);
Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + args.Parameters[0]);
return;
}
else
{
Log.Warn(args.Player.IP + " failed to authenticate as user: " + args.Parameters[0]);
args.Player.LoginAttempts++;
return;
}
}
catch (Exception)
{
args.Player.SendMessage("There was an error processing your request. Maybe your account doesn't exist?", Color.Red);
return;
}
}
private static void PasswordUser(CommandArgs args)
{
try
{
if (args.Player.IsLoggedIn && args.Parameters.Count == 2)
{
var user = TShock.Users.GetUserByName(args.Player.UserAccountName);
string encrPass = Tools.HashPassword(args.Parameters[0]);
string[] exr = TShock.Users.FetchHashedPasswordAndGroup(args.Player.UserAccountName);
if (exr[0].ToUpper() == encrPass.ToUpper())
{
args.Player.SendMessage("You changed your password!", Color.Green);
TShock.Users.SetUserPassword(user, args.Parameters[1]); // SetUserPassword will hash it for you.
Log.ConsoleInfo(args.Player.IP + " named " + args.Player.Name + " changed the password of Account " + user.Name);
}
else
{
args.Player.SendMessage("You failed to change your password!", Color.Red);
Log.ConsoleError(args.Player.IP + " named " + args.Player.Name + " failed to change password for Account: " + user.Name);
}
}
else
{
args.Player.SendMessage("Not Logged in or Invalid syntax! Proper syntax: /password ", Color.Red);
}
}
catch (UserManagerException ex)
{
args.Player.SendMessage("Sorry, an error occured: " + ex.Message, Color.Green);
Log.ConsoleError("RegisterUser returned an error: " + ex.ToString());
}
}
private static void RegisterUser(CommandArgs args)
{
try
{
if (args.Parameters.Count == 2)
{
var user = new User();
user.Name = args.Parameters[0].ToLower();
user.Password = args.Parameters[1];
user.Group = "default"; // FIXME -- we should get this from the DB.
if (TShock.Users.GetUserByName(user.Name) == null) // Cheap way of checking for existance of a user
{
args.Player.SendMessage("Account " + user.Name + " has been registered.", Color.Green);
TShock.Users.AddUser(user);
Log.ConsoleInfo(args.Player.Name + " registered an Account: " + user.Name);
}
else
{
args.Player.SendMessage("Account " + user.Name + " has already been registered.", Color.Green);
Log.ConsoleInfo(args.Player.Name + " failed to register an existing Account: " + user.Name);
}
}
else
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /register ", Color.Red);
}
}
catch (UserManagerException ex)
{
args.Player.SendMessage("Sorry, an error occured: " + ex.Message, Color.Green);
Log.ConsoleError("RegisterUser returned an error: " + ex.ToString());
}
}
//Todo: Add separate help text for '/user add' and '/user del'. Also add '/user addip' and '/user delip'
private static void ManageUsers(CommandArgs args)
{
if (args.Parameters.Count < 2)
{
args.Player.SendMessage("Syntax: /user [group]");
args.Player.SendMessage("Note: Passwords are stored with SHA512 hashing. To reset a user's password, remove and re-add them.");
return;
}
string subcmd = args.Parameters[0];
if (subcmd == "add")
{
var namepass = args.Parameters[1].Split(':');
var user = new User();
try
{
if (args.Parameters.Count > 2)
{
if (namepass.Length == 2)
{
user.Name = namepass[0].ToLower();
user.Password = namepass[1];
user.Group = args.Parameters[2];
}
else if (namepass.Length == 1)
{
user.Address = namepass[0];
user.Group = args.Parameters[2];
user.Name = user.Address;
}
if (!string.IsNullOrEmpty(user.Address))
{
args.Player.SendMessage("IP address admin added. If they're logged in, tell them to rejoin.", Color.Green);
args.Player.SendMessage("WARNING: This is insecure! It would be better to use a user account instead.", Color.Red);
TShock.Users.AddUser(user);
Log.ConsoleInfo(args.Player.Name + " added IP " + user.Address + " to group " + user.Group);
}
else
{
args.Player.SendMessage("Account " + user.Name + " has been added to group " + user.Group + "!", Color.Green);
TShock.Users.AddUser(user);
Log.ConsoleInfo(args.Player.Name + " added Account " + user.Name + " to group " + user.Group);
}
}
else
{
args.Player.SendMessage("Invalid syntax. Try /user help.", Color.Red);
}
}
catch (UserManagerException ex)
{
args.Player.SendMessage(ex.Message, Color.Green);
Log.ConsoleError(ex.ToString());
}
}
else if (subcmd == "del" && args.Parameters.Count == 2)
{
var user = new User();
if (args.Parameters[1].Contains("."))
user.Address = args.Parameters[1];
else
user.Name = args.Parameters[1];
try
{
TShock.Users.RemoveUser(user);
args.Player.SendMessage("Account removed successfully.", Color.Green);
Log.ConsoleInfo(args.Player.Name + " successfully deleted account: " + args.Parameters[1]);
}
catch (UserManagerException ex)
{
args.Player.SendMessage(ex.Message, Color.Red);
Log.ConsoleError(ex.ToString());
}
}
else
{
args.Player.SendMessage("Invalid syntax. Try /user help.", Color.Red);
}
}
#endregion
#region Player Management Commands
private static void GrabUserIP(CommandArgs args)
{
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /ip ", Color.Red);
return;
}
var players = Tools.FindPlayer(args.Parameters[0]);
if (players.Count > 1)
{
args.Player.SendMessage("More than one player matched your query.", Color.Red);
return;
}
try
{
args.Player.SendMessage(players[0].IP, Color.Green);
}
catch (Exception)
{
args.Player.SendMessage("Invalid player.", Color.Red);
}
}
private static void Kick(CommandArgs args)
{
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /kick [reason]", Color.Red);
return;
}
if (args.Parameters[0].Length == 0)
{
args.Player.SendMessage("Missing player name", Color.Red);
return;
}
string plStr = args.Parameters[0];
var players = Tools.FindPlayer(plStr);
if (players.Count == 0)
{
args.Player.SendMessage("Invalid player!", Color.Red);
}
else if (players.Count > 1)
{
args.Player.SendMessage("More than one player matched!", Color.Red);
}
else
{
string reason = args.Parameters.Count > 1 ? String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1)) : "Misbehaviour.";
if (!Tools.Kick(players[0], reason))
{
args.Player.SendMessage("You can't kick another admin!", Color.Red);
}
}
}
private static void Ban(CommandArgs args)
{
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /ban [reason]", Color.Red);
return;
}
if (args.Parameters[0].Length == 0)
{
args.Player.SendMessage("Missing player name", Color.Red);
return;
}
string plStr = args.Parameters[0];
var players = Tools.FindPlayer(plStr);
if (players.Count == 0)
{
args.Player.SendMessage("Invalid player!", Color.Red);
}
else if (players.Count > 1)
{
args.Player.SendMessage("More than one player matched!", Color.Red);
}
else
{
string reason = args.Parameters.Count > 1 ? String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1)) : "Misbehaviour.";
if (!Tools.Ban(players[0], reason))
{
args.Player.SendMessage("You can't ban another admin!", Color.Red);
}
}
}
private static void BanIP(CommandArgs args)
{
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Syntax: /banip [reason]", Color.Red);
return;
}
if (args.Parameters[0].Length == 0)
{
args.Player.SendMessage("Missing IP address", Color.Red);
return;
}
string ip = args.Parameters[0];
string reason = args.Parameters.Count > 1 ? String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1)) : "Manually added IP address ban.";
TShock.Bans.AddBan(ip, "", reason);
}
private static void UnBan(CommandArgs args)
{
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /unban ", Color.Red);
return;
}
if (args.Parameters[0].Length == 0)
{
args.Player.SendMessage("Missing player name", Color.Red);
return;
}
string plStr = args.Parameters[0];
var ban = TShock.Bans.GetBanByName(plStr);
if (ban != null)
{
if (TShock.Bans.RemoveBan(ban.IP))
args.Player.SendMessage(string.Format("Unbanned {0} ({1})!", ban.Name, ban.IP), Color.Red);
else
args.Player.SendMessage(string.Format("Failed to Unbanned {0} ({1})!", ban.Name, ban.IP), Color.Red);
}
else
{
args.Player.SendMessage("Invalid player!", Color.Red);
}
}
static int ClearBansCode = -1;
private static void ClearBans(CommandArgs args)
{
if (args.Parameters.Count < 1 && ClearBansCode == -1)
{
ClearBansCode = new Random().Next(0, short.MaxValue);
args.Player.SendMessage("ClearBans Code: " + ClearBansCode, Color.Red);
return;
}
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /clearbans ");
return;
}
int num;
if (!int.TryParse(args.Parameters[0], out num))
{
args.Player.SendMessage("Invalid syntax! Expecting number");
return;
}
if (num == ClearBansCode)
{
ClearBansCode = -1;
if (TShock.Bans.ClearBans())
{
Log.ConsoleInfo("Bans cleared");
args.Player.SendMessage("Bans cleared");
}
else
{
args.Player.SendMessage("Failed to clear bans");
}
}
else
{
args.Player.SendMessage("Incorrect clear code");
}
}
private static void UnBanIP(CommandArgs args)
{
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /unbanip ", Color.Red);
return;
}
if (args.Parameters[0].Length == 0)
{
args.Player.SendMessage("Missing ip", Color.Red);
return;
}
string plStr = args.Parameters[0];
var ban = TShock.Bans.GetBanByIp(plStr);
if (ban != null)
{
if (TShock.Bans.RemoveBan(ban.IP))
args.Player.SendMessage(string.Format("Unbanned {0} ({1})!", ban.Name, ban.IP), Color.Red);
else
args.Player.SendMessage(string.Format("Failed to Unbanned {0} ({1})!", ban.Name, ban.IP), Color.Red);
}
else
{
args.Player.SendMessage("Invalid player!", Color.Red);
}
}
public static void Whitelist(CommandArgs args)
{
if (args.Parameters.Count == 1)
{
TextWriter tw = new StreamWriter(FileTools.WhitelistPath, true);
tw.WriteLine(args.Parameters[0]);
tw.Close();
args.Player.SendMessage("Added " + args.Parameters[0] + " to the whitelist.");
}
}
public static void DisplayLogs(CommandArgs args)
{
args.Player.DisplayLogs = (!args.Player.DisplayLogs);
args.Player.SendMessage("You now " + (args.Player.DisplayLogs ? "receive" : "stopped receiving") + " logs");
}
#endregion Player Management Commands
#region Server Maintenence Commands
public static void ConvertWaR(CommandArgs args)
{
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("This command will dump all users from both Regions and Warps.");
args.Player.SendMessage("This command will also change all Worlds to reference this WorldID.");
args.Player.SendMessage("You must manually fix multi-world configurations.");
args.Player.SendMessage("To confirm this: /convert yes");
}
else if (args.Parameters[0] == "yes")
{
TShock.Warps.ConvertDB();
TShock.Regions.ConvertDB();
args.Player.SendMessage("Convert complete. You need to re-allow users after they register.");
}
}
private static void Broadcast(CommandArgs args)
{
string message = "";
for (int i = 0; i < args.Parameters.Count; i++)
{
message += " " + args.Parameters[i];
}
Tools.Broadcast("(Server Broadcast)" + message, Color.Red);
return;
}
private static void Off(CommandArgs args)
{
Tools.ForceKickAll("Server shutting down!");
WorldGen.saveWorld();
Netplay.disconnect = true;
}
private static void OffNoSave(CommandArgs args)
{
Tools.ForceKickAll("Server shutting down!");
Netplay.disconnect = true;
}
private static void CheckUpdates(CommandArgs args)
{
ThreadPool.QueueUserWorkItem(UpdateManager.CheckUpdate);
}
private static void UpdateNow(CommandArgs args)
{
Process TServer = Process.GetCurrentProcess();
StreamWriter sw = new StreamWriter("pid");
sw.Write(TServer.Id);
sw.Close();
sw = new StreamWriter("pn");
sw.Write(TServer.ProcessName + " " + Environment.CommandLine);
sw.Close();
WebClient client = new WebClient();
client.Headers.Add("user-agent", "TShock");
byte[] updatefile = client.DownloadData("http://tsupdate.shankshock.com/UpdateTShock.exe");
BinaryWriter bw = new BinaryWriter(new FileStream("UpdateTShock.exe", FileMode.Create));
bw.Write(updatefile);
bw.Close();
Process.Start(new ProcessStartInfo("UpdateTShock.exe"));
Tools.ForceKickAll("Server shutting down for update!");
WorldGen.saveWorld();
Netplay.disconnect = true;
}
#endregion Server Maintenence Commands
#region Cause Events and Spawn Monsters Commands
private static void DropMeteor(CommandArgs args)
{
WorldGen.spawnMeteor = false;
WorldGen.dropMeteor();
}
private static void Star(CommandArgs args)
{
int penis56 = 12;
int penis57 = Main.rand.Next(Main.maxTilesX - 50) + 100;
penis57 *= 0x10;
int penis58 = Main.rand.Next((int)(Main.maxTilesY * 0.05)) * 0x10;
Vector2 vector = new Vector2(penis57, penis58);
float speedX = Main.rand.Next(-100, 0x65);
float speedY = Main.rand.Next(200) + 100;
float penis61 = (float)Math.Sqrt(((speedX * speedX) + (speedY * speedY)));
penis61 = (penis56) / penis61;
speedX *= penis61;
speedY *= penis61;
Projectile.NewProjectile(vector.X, vector.Y, speedX, speedY, 12, 0x3e8, 10f, Main.myPlayer);
}
private static void Bloodmoon(CommandArgs args)
{
TSPlayer.Server.SetBloodMoon(true);
Tools.Broadcast(string.Format("{0} turned on blood moon.", args.Player.Name));
}
private static void Invade(CommandArgs args)
{
if (Main.invasionSize <= 0)
{
Tools.Broadcast(string.Format("{0} has started an invasion.", args.Player.Name));
TShock.StartInvasion();
}
else
{
Tools.Broadcast(string.Format("{0} has ended an invasion.", args.Player.Name));
Main.invasionSize = 0;
}
}
private static void Eater(CommandArgs args)
{
if (args.Parameters.Count > 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /eater [amount]", Color.Red);
return;
}
int amount = 1;
if (args.Parameters.Count == 1 && !int.TryParse(args.Parameters[0], out amount))
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /eater [amount]", Color.Red);
return;
}
NPC eater = Tools.GetNPCById(13);
TSPlayer.Server.SpawnNPC(eater.type, eater.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
Tools.Broadcast(string.Format("{0} has spawned eater of worlds {1} times!", args.Player.Name, amount));
}
private static void Eye(CommandArgs args)
{
if (args.Parameters.Count > 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /eye [amount]", Color.Red);
return;
}
int amount = 1;
if (args.Parameters.Count == 1 && !int.TryParse(args.Parameters[0], out amount))
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /eye [amount]", Color.Red);
return;
}
NPC eye = Tools.GetNPCById(4);
TSPlayer.Server.SetTime(false, 0.0);
TSPlayer.Server.SpawnNPC(eye.type, eye.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
Tools.Broadcast(string.Format("{0} has spawned eye {1} times!", args.Player.Name, amount));
}
private static void King(CommandArgs args)
{
if (args.Parameters.Count > 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /king [amount]", Color.Red);
return;
}
int amount = 1;
if (args.Parameters.Count == 1 && !int.TryParse(args.Parameters[0], out amount))
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /king [amount]", Color.Red);
return;
}
NPC king = Tools.GetNPCById(50);
TSPlayer.Server.SpawnNPC(king.type, king.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
Tools.Broadcast(string.Format("{0} has spawned king slime {1} times!", args.Player.Name, amount));
}
private static void Skeletron(CommandArgs args)
{
if (args.Parameters.Count > 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /skeletron [amount]", Color.Red);
return;
}
int amount = 1;
if (args.Parameters.Count == 1 && !int.TryParse(args.Parameters[0], out amount))
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /skeletron [amount]", Color.Red);
return;
}
NPC skeletron = Tools.GetNPCById(35);
TSPlayer.Server.SetTime(false, 0.0);
TSPlayer.Server.SpawnNPC(skeletron.type, skeletron.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
Tools.Broadcast(string.Format("{0} has spawned skeletron {1} times!", args.Player.Name, amount));
}
private static void Hardcore(CommandArgs args)
{
if (args.Parameters.Count > 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /hardcore [amount]", Color.Red);
return;
}
int amount = 1;
if (args.Parameters.Count == 1 && !int.TryParse(args.Parameters[0], out amount))
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /hardcore [amount]", Color.Red);
return;
}
NPC eater = Tools.GetNPCById(13);
NPC eye = Tools.GetNPCById(4);
NPC king = Tools.GetNPCById(50);
NPC skeletron = Tools.GetNPCById(35);
TSPlayer.Server.SetTime(false, 0.0);
TSPlayer.Server.SpawnNPC(eater.type, eater.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
TSPlayer.Server.SpawnNPC(eye.type, eye.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
TSPlayer.Server.SpawnNPC(king.type, king.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
TSPlayer.Server.SpawnNPC(skeletron.type, skeletron.name, amount, (int)args.Player.TileX, (int)args.Player.TileY);
Tools.Broadcast(string.Format("{0} has spawned all bosses {1} times!", args.Player.Name, amount));
}
private static void SpawnMob(CommandArgs args)
{
if (args.Parameters.Count < 1 || args.Parameters.Count > 2)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /spawnmob [amount]", Color.Red);
return;
}
if (args.Parameters[0].Length == 0)
{
args.Player.SendMessage("Missing mob name/id", Color.Red);
return;
}
int amount = 1;
if (args.Parameters.Count == 2 && !int.TryParse(args.Parameters[1], out amount))
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /spawnmob [amount]", Color.Red);
return;
}
var npcs = Tools.GetNPCByIdOrName(args.Parameters[0]);
if (npcs.Count == 0)
{
args.Player.SendMessage("Invalid mob type!", Color.Red);
}
else if (npcs.Count > 1)
{
args.Player.SendMessage(string.Format("More than one ({0}) mob matched!", npcs.Count), Color.Red);
}
else
{
var npc = npcs[0];
if (npc.type >= 1 && npc.type < Main.maxNPCTypes)
{
TSPlayer.Server.SpawnNPC(npc.type, npc.name, amount, (int)args.Player.TileX, (int)args.Player.TileY, 50, 20);
Tools.Broadcast(string.Format("{0} was spawned {1} time(s).", npc.name, amount));
}
else
args.Player.SendMessage("Invalid mob type!", Color.Red);
}
}
#endregion Cause Events and Spawn Monsters Commands
#region Teleport Commands
private static void Home(CommandArgs args)
{
if (!args.Player.RealPlayer)
{
args.Player.SendMessage("You cannot use teleport commands!");
return;
}
args.Player.Spawn();
args.Player.SendMessage("Teleported to your spawnpoint.");
}
private static void Spawn(CommandArgs args)
{
if (!args.Player.RealPlayer)
{
args.Player.SendMessage("You cannot use teleport commands!");
return;
}
if (args.Player.Teleport(Main.spawnTileX, Main.spawnTileY))
args.Player.SendMessage("Teleported to the map's spawnpoint.");
}
private static void TP(CommandArgs args)
{
if (!args.Player.RealPlayer)
{
args.Player.SendMessage("You cannot use teleport commands!");
return;
}
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /tp ", Color.Red);
return;
}
string plStr = String.Join(" ", args.Parameters);
var players = Tools.FindPlayer(plStr);
if (players.Count == 0)
args.Player.SendMessage("Invalid player!", Color.Red);
else if (players.Count > 1)
args.Player.SendMessage("More than one player matched!", Color.Red);
else
{
var plr = players[0];
if (args.Player.Teleport(plr.TileX, plr.TileY + 3))
args.Player.SendMessage(string.Format("Teleported to {0}", plr.Name));
}
}
private static void TPHere(CommandArgs args)
{
if (!args.Player.RealPlayer)
{
args.Player.SendMessage("You cannot use teleport commands!");
return;
}
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /tphere ", Color.Red);
return;
}
string plStr = String.Join(" ", args.Parameters);
if (plStr == "all" || plStr == "*")
{
args.Player.SendMessage(string.Format("You brought all players here."));
for (int i = 0; i < Main.maxPlayers; i++)
{
if (Main.player[i].active && (Main.player[i] != args.TPlayer))
{
if (TShock.Players[i].Teleport(args.Player.TileX, args.Player.TileY + 3))
TShock.Players[i].SendMessage(string.Format("You were teleported to {0}.", args.Player.Name));
}
}
return;
}
var players = Tools.FindPlayer(plStr);
if (players.Count == 0)
{
args.Player.SendMessage("Invalid player!", Color.Red);
}
else if (players.Count > 1)
{
args.Player.SendMessage("More than one player matched!", Color.Red);
}
else
{
var plr = players[0];
if (plr.Teleport(args.Player.TileX, args.Player.TileY + 3))
{
plr.SendMessage(string.Format("You were teleported to {0}.", args.Player.Name));
args.Player.SendMessage(string.Format("You brought {0} here.", plr.Name));
}
}
}
private static void SetWarp(CommandArgs args)
{
if (args.Parameters.Count > 0)
{
string warpName = String.Join(" ", args.Parameters);
if (warpName.Equals("list"))
{
args.Player.SendMessage("Name reserved, use a different name", Color.Red);
}
else if (TShock.Warps.AddWarp(args.Player.TileX, args.Player.TileY, warpName, Main.worldName))
{
args.Player.SendMessage("Set warp " + warpName, Color.Yellow);
}
else
{
args.Player.SendMessage("Warp " + warpName + " already exists", Color.Red);
}
}
else
args.Player.SendMessage("Invalid syntax! Proper syntax: /setwarp [name]", Color.Red);
}
private static void DeleteWarp(CommandArgs args)
{
if (args.Parameters.Count > 0)
{
string warpName = String.Join(" ", args.Parameters);
if (TShock.Warps.RemoveWarp(warpName))
args.Player.SendMessage("Deleted warp " + warpName, Color.Yellow);
else
args.Player.SendMessage("Could not find specified warp", Color.Red);
}
else
args.Player.SendMessage("Invalid syntax! Proper syntax: /delwarp [name]", Color.Red);
}
private static void UseWarp(CommandArgs args)
{
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /warp [name] or /warp list ", Color.Red);
return;
}
if (args.Parameters[0].Equals("list"))
{
//How many warps per page
const int pagelimit = 15;
//How many warps per line
const int perline = 5;
//Pages start at 0 but are displayed and parsed at 1
int page = 0;
if (args.Parameters.Count > 1)
{
if (!int.TryParse(args.Parameters[1], out page) || page < 1)
{
args.Player.SendMessage(string.Format("Invalid page number ({0})", page), Color.Red);
return;
}
page--; //Substract 1 as pages are parsed starting at 1 and not 0
}
var warps = TShock.Warps.ListAllWarps(Main.worldName);
//Check if they are trying to access a page that doesn't exist.
int pagecount = warps.Count / pagelimit;
if (page > pagecount)
{
args.Player.SendMessage(string.Format("Page number exceeds pages ({0}/{1})", page + 1, pagecount + 1), Color.Red);
return;
}
//Display the current page and the number of pages.
args.Player.SendMessage(string.Format("Current Warps ({0}/{1}):", page + 1, pagecount + 1), Color.Green);
//Add up to pagelimit names to a list
var nameslist = new List();
for (int i = 0; i < pagelimit && i + (page * pagelimit) < warps.Count; i++)
{
nameslist.Add(warps[i].WarpName);
}
//convert the list to an array for joining
var names = nameslist.ToArray();
for (int i = 0; i < names.Length; i += perline)
{
args.Player.SendMessage(string.Join(", ", names, i, Math.Min(names.Length - i, perline)), Color.Yellow);
}
if (page < pagecount)
{
args.Player.SendMessage(string.Format("Type /warp list {0} for more warps.", (page + 1)), Color.Yellow);
}
}
else
{
string warpName = String.Join(" ", args.Parameters);
var warp = TShock.Warps.FindWarp(warpName);
if (warp.WarpPos != Vector2.Zero)
{
if (args.Player.Teleport((int)warp.WarpPos.X, (int)warp.WarpPos.Y + 3))
args.Player.SendMessage("Warped to " + warpName, Color.Yellow);
}
else
{
args.Player.SendMessage("Specified warp not found", Color.Red);
}
}
}
#endregion Teleport Commands
#region Server Config Commands
private static void SetSpawn(CommandArgs args)
{
Main.spawnTileX = args.Player.TileX + 1;
Main.spawnTileY = args.Player.TileY + 3;
Tools.Broadcast("Server map saving, potential lag spike");
Thread SaveWorld = new Thread(Tools.SaveWorld);
SaveWorld.Start();
}
private static void DebugConfiguration(CommandArgs args)
{
args.Player.SendMessage("TShock Config:");
string lineOne = string.Format("BanCheater : {0}, KickCheater : {1}, BanGriefer : {2}, KickGriefer : {3}",
TShock.Config.BanCheaters, TShock.Config.KickCheaters,
TShock.Config.BanGriefers, TShock.Config.KickGriefers);
args.Player.SendMessage(lineOne, Color.Yellow);
string lineTwo = string.Format("BanTnt : {0}, KickTnt : {1}, BanBoom : {2}, KickBoom : {3}",
TShock.Config.BanKillTileAbusers, TShock.Config.KickKillTileAbusers,
TShock.Config.BanExplosives, TShock.Config.KickExplosives);
args.Player.SendMessage(lineTwo, Color.Yellow);
string lineThree = string.Format("RangeChecks : {0}, DisableBuild : {1}, ProtectSpawn : {2}, ProtectRadius : {3}",
TShock.Config.RangeChecks, TShock.Config.DisableBuild,
TShock.Config.SpawnProtection, TShock.Config.SpawnProtectionRadius);
args.Player.SendMessage(lineThree, Color.Yellow);
string lineFour = string.Format("MaxSlots : {0}, SpamChecks : {1}, InvMultiplier : {2}, DMS : {3}, SpawnRate {4}",
TShock.Config.MaxSlots, TShock.Config.SpamChecks,
TShock.Config.InvasionMultiplier, TShock.Config.DefaultMaximumSpawns,
TShock.Config.DefaultSpawnRate);
args.Player.SendMessage(lineFour, Color.Yellow);
}
private static void Reload(CommandArgs args)
{
FileTools.SetupConfig();
args.Player.SendMessage("Configuration reload complete. Some changes may require server restart.");
}
private static void Password(CommandArgs args)
{
if (args.Parameters.Count != 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /password \"\"", Color.Red);
return;
}
string passwd = args.Parameters[0];
Netplay.password = passwd;
args.Player.SendMessage(string.Format("Server password changed to: {0}", passwd));
}
private static void Save(CommandArgs args)
{
Tools.Broadcast("Server map saving, potential lag spike");
Thread SaveWorld = new Thread(Tools.SaveWorld);
SaveWorld.Start();
}
private static void MaxSpawns(CommandArgs args)
{
if (args.Parameters.Count != 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /maxspawns ", Color.Red);
return;
}
int amount = Convert.ToInt32(args.Parameters[0]);
int.TryParse(args.Parameters[0], out amount);
NPC.defaultMaxSpawns = amount;
TShock.Config.DefaultMaximumSpawns = amount;
Tools.Broadcast(string.Format("{0} changed the maximum spawns to: {1}", args.Player.Name, amount));
}
private static void SpawnRate(CommandArgs args)
{
if (args.Parameters.Count != 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /spawnrate ", Color.Red);
return;
}
int amount = Convert.ToInt32(args.Parameters[0]);
int.TryParse(args.Parameters[0], out amount);
NPC.defaultSpawnRate = amount;
TShock.Config.DefaultSpawnRate = amount;
Tools.Broadcast(string.Format("{0} changed the spawn rate to: {1}", args.Player.Name, amount));
}
#endregion Server Config Commands
#region Time/PvpFun Commands
private static void Time(CommandArgs args)
{
if (args.Parameters.Count != 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /time ", Color.Red);
return;
}
switch (args.Parameters[0])
{
case "day":
TSPlayer.Server.SetTime(true, 150.0);
Tools.Broadcast(string.Format("{0} set time to day.", args.Player.Name));
break;
case "night":
TSPlayer.Server.SetTime(false, 0.0);
Tools.Broadcast(string.Format("{0} set time to night.", args.Player.Name));
break;
case "dusk":
TSPlayer.Server.SetTime(false, 0.0);
Tools.Broadcast(string.Format("{0} set time to dusk.", args.Player.Name));
break;
case "noon":
TSPlayer.Server.SetTime(true, 27000.0);
Tools.Broadcast(string.Format("{0} set time to noon.", args.Player.Name));
break;
case "midnight":
TSPlayer.Server.SetTime(false, 16200.0);
Tools.Broadcast(string.Format("{0} set time to midnight.", args.Player.Name));
break;
default:
args.Player.SendMessage("Invalid syntax! Proper syntax: /time ", Color.Red);
break;
}
}
private static void Slap(CommandArgs args)
{
if (args.Parameters.Count < 1 || args.Parameters.Count > 2)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /slap [dmg]", Color.Red);
return;
}
if (args.Parameters[0].Length == 0)
{
args.Player.SendMessage("Missing player name", Color.Red);
return;
}
string plStr = args.Parameters[0];
var players = Tools.FindPlayer(plStr);
if (players.Count == 0)
{
args.Player.SendMessage("Invalid player!", Color.Red);
}
else if (players.Count > 1)
{
args.Player.SendMessage("More than one player matched!", Color.Red);
}
else
{
var plr = players[0];
int damage = 5;
if (args.Parameters.Count == 2)
{
int.TryParse(args.Parameters[1], out damage);
}
if (!args.Player.Group.HasPermission("kill"))
{
damage = Tools.Clamp(damage, 15, 0);
}
plr.DamagePlayer(damage);
Tools.Broadcast(string.Format("{0} slapped {1} for {2} damage.",
args.Player.Name, plr.Name, damage));
Log.Info(args.Player.Name + " slapped " + plr.Name + " with " + damage + " damage.");
}
}
#endregion Time/PvpFun Commands
#region World Protection Commands
private static void ToggleAntiBuild(CommandArgs args)
{
TShock.Config.DisableBuild = (TShock.Config.DisableBuild == false);
Tools.Broadcast(string.Format("Anti-build is now {0}.", (TShock.Config.DisableBuild ? "on" : "off")));
}
private static void ProtectSpawn(CommandArgs args)
{
TShock.Config.SpawnProtection = (TShock.Config.SpawnProtection == false);
Tools.Broadcast(string.Format("Spawn is now {0}.", (TShock.Config.SpawnProtection ? "protected" : "open")));
}
private static void DebugRegions(CommandArgs args)
{
foreach (Region r in TShock.Regions.Regions)
{
args.Player.SendMessage(r.RegionName + ": P: " + r.DisableBuild + " X: " + r.RegionArea.X + " Y: " + r.RegionArea.Y + " W: " + r.RegionArea.Width + " H: " + r.RegionArea.Height);
foreach (int s in r.RegionAllowedIDs)
{
args.Player.SendMessage(r.RegionName + ": " + s);
}
}
}
private static void Region(CommandArgs args)
{
string cmd = "help";
if (args.Parameters.Count > 0)
{
cmd = args.Parameters[0].ToLower();
}
switch (cmd)
{
case "set":
{
if (args.Parameters.Count == 2)
{
if (args.Parameters[1] == "1")
{
args.Player.TempArea.X = args.Player.TileX;
args.Player.TempArea.Y = args.Player.TileY;
args.Player.SendMessage("Set Temp Point 1", Color.Yellow);
}
else if (args.Parameters[1] == "2")
{
if (args.Player.TempArea.X != 0)
{
if (args.Player.TileX > args.Player.TempArea.X && args.Player.TileY > args.Player.TempArea.Y)
{
args.Player.TempArea.Width = args.Player.TileX - args.Player.TempArea.X;
args.Player.TempArea.Height = (args.Player.TileY + 3) - args.Player.TempArea.Y;
args.Player.SendMessage("Set Temp Point 2", Color.Yellow);
}
else
{
args.Player.SendMessage("Point 2 must be below and right of Point 1", Color.Yellow);
args.Player.SendMessage("Use /region clear to start again", Color.Yellow);
}
}
else
{
args.Player.SendMessage("You have not set Point 1 yet", Color.Red);
}
}
else
args.Player.SendMessage("Invalid syntax! Proper syntax: /region set [1/2]", Color.Red);
}
else
args.Player.SendMessage("Invalid syntax! Proper syntax: /region set [1/2]", Color.Red);
break;
}
case "define":
{
if (args.Parameters.Count > 1)
{
if (!args.Player.TempArea.IsEmpty)
{
string regionName = String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1));
if (TShock.Regions.AddRegion(args.Player.TempArea.X, args.Player.TempArea.Y,
args.Player.TempArea.Width, args.Player.TempArea.Height,
regionName, Main.worldName))
{
args.Player.TempArea = Rectangle.Empty;
args.Player.SendMessage("Set region " + regionName, Color.Yellow);
}
else
{
args.Player.SendMessage("Region " + regionName + " already exists", Color.Red);
}
}
else
args.Player.SendMessage("Points not set up yet", Color.Red);
}
else
args.Player.SendMessage("Invalid syntax! Proper syntax: /region define [name]", Color.Red);
break;
}
case "protect":
{
if (args.Parameters.Count == 3)
{
string regionName = args.Parameters[1];
if (args.Parameters[2].ToLower() == "true")
{
if (TShock.Regions.SetRegionState(regionName, true))
args.Player.SendMessage("Protected region " + regionName, Color.Yellow);
else
args.Player.SendMessage("Could not find specified region", Color.Red);
}
else if (args.Parameters[2].ToLower() == "false")
{
if (TShock.Regions.SetRegionState(regionName, false))
args.Player.SendMessage("Unprotected region " + regionName, Color.Yellow);
else
args.Player.SendMessage("Could not find specified region", Color.Red);
}
else
args.Player.SendMessage("Invalid syntax! Proper syntax: /region protect [name] [true/false]", Color.Red);
}
else
args.Player.SendMessage("Invalid syntax! Proper syntax: /region protect [name] [true/false]", Color.Red);
break;
}
case "delete":
{
if (args.Parameters.Count > 1)
{
string regionName = String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1));
if (TShock.Regions.DeleteRegion(regionName))
args.Player.SendMessage("Deleted region " + regionName, Color.Yellow);
else
args.Player.SendMessage("Could not find specified region", Color.Red);
}
else
args.Player.SendMessage("Invalid syntax! Proper syntax: /region delete [name]", Color.Red);
break;
}
case "clear":
{
args.Player.TempArea = Rectangle.Empty;
args.Player.SendMessage("Cleared temp area", Color.Yellow);
break;
}
case "allow":
{
if (args.Parameters.Count > 2)
{
string playerName = args.Parameters[1];
string regionName = "";
User playerID;
for (int i = 2; i < args.Parameters.Count; i++)
{
if (regionName == "")
{
regionName = args.Parameters[2];
}
else
{
regionName = regionName + " " + args.Parameters[i];
}
}
if ((playerID = TShock.Users.GetUserByName(playerName)) != null)
{
if (TShock.Regions.AddNewUser(regionName, playerName))
{
args.Player.SendMessage("Added user " + playerName + " to " + regionName, Color.Yellow);
}
else
args.Player.SendMessage("Region " + regionName + " not found", Color.Red);
}
else
{
args.Player.SendMessage("Player " + playerName + " not found", Color.Red);
}
}
else
args.Player.SendMessage("Invalid syntax! Proper syntax: /region allow [name] [region]", Color.Red);
break;
}
case "list":
{
//How many regions per page
const int pagelimit = 15;
//How many regions per line
const int perline = 5;
//Pages start at 0 but are displayed and parsed at 1
int page = 0;
if (args.Parameters.Count > 1)
{
if (!int.TryParse(args.Parameters[1], out page) || page < 1)
{
args.Player.SendMessage(string.Format("Invalid page number ({0})", page), Color.Red);
return;
}
page--; //Substract 1 as pages are parsed starting at 1 and not 0
}
var regions = TShock.Regions.ListAllRegions(Main.worldName);
//Check if they are trying to access a page that doesn't exist.
int pagecount = regions.Count / pagelimit;
if (page > pagecount)
{
args.Player.SendMessage(string.Format("Page number exceeds pages ({0}/{1})", page + 1, pagecount + 1), Color.Red);
return;
}
//Display the current page and the number of pages.
args.Player.SendMessage(string.Format("Current Regions ({0}/{1}):", page + 1, pagecount + 1), Color.Green);
//Add up to pagelimit names to a list
var nameslist = new List();
for (int i = 0; i < pagelimit && i + (page * pagelimit) < regions.Count; i++)
{
nameslist.Add(regions[i].RegionName);
}
//convert the list to an array for joining
var names = nameslist.ToArray();
for (int i = 0; i < names.Length; i += perline)
{
args.Player.SendMessage(string.Join(", ", names, i, Math.Min(names.Length - i, perline)), Color.Yellow);
}
if (page < pagecount)
{
args.Player.SendMessage(string.Format("Type /region list {0} for more regions.", (page + 1)), Color.Yellow);
}
break;
}
case "help":
default:
{
args.Player.SendMessage("Avialable region commands:", Color.Green);
args.Player.SendMessage("/region set [1/2] /region define [name] /region protect [name] [true/false]", Color.Yellow);
args.Player.SendMessage("/region delete [name] /region clear (temporary region)", Color.Yellow);
args.Player.SendMessage("/region allow [name] [regionname]", Color.Yellow);
break;
}
}
}
#endregion World Protection Commands
#region General Commands
private static void Help(CommandArgs args)
{
args.Player.SendMessage("TShock Commands:");
int page = 1;
if (args.Parameters.Count > 0)
int.TryParse(args.Parameters[0], out page);
var cmdlist = new List();
for (int j = 0; j < ChatCommands.Count; j++)
{
if (ChatCommands[j].CanRun(args.Player))
{
cmdlist.Add(ChatCommands[j]);
}
}
var sb = new StringBuilder();
if (cmdlist.Count > (15 * (page - 1)))
{
for (int j = (15 * (page - 1)); j < (15 * page); j++)
{
if (sb.Length != 0)
sb.Append(", ");
sb.Append("/").Append(cmdlist[j].Name);
if (j == cmdlist.Count - 1)
{
args.Player.SendMessage(sb.ToString(), Color.Yellow);
break;
}
if ((j + 1) % 5 == 0)
{
args.Player.SendMessage(sb.ToString(), Color.Yellow);
sb.Clear();
}
}
}
if (cmdlist.Count > (15 * page))
{
args.Player.SendMessage(string.Format("Type /help {0} for more commands.", (page + 1)), Color.Yellow);
}
}
private static void Playing(CommandArgs args)
{
args.Player.SendMessage(string.Format("Current players: {0}.", Tools.GetPlayers()), 255, 240, 20);
}
private static void AuthToken(CommandArgs args)
{
if (TShock.AuthToken == 0)
{
args.Player.SendMessage("Auth is disabled. This incident has been logged.", Color.Red);
Log.Warn(args.Player.IP + " attempted to use /auth even though it's disabled.");
return;
}
int givenCode = Convert.ToInt32(args.Parameters[0]);
if (givenCode == TShock.AuthToken && args.Player.Group.Name != "superadmin")
{
try
{
TShock.Users.AddUser(new User(args.Player.IP, "", "", "superadmin"));
args.Player.Group = Tools.GetGroup("superadmin");
args.Player.SendMessage("This IP address is now superadmin. Please perform the following command:");
args.Player.SendMessage("/user add : superadmin");
args.Player.SendMessage("Creates: with the password as part of the superadmin group.");
args.Player.SendMessage("Please use /login to login from now on.");
args.Player.SendMessage("If you understand, please /login now, and type /auth-verify");
}
catch (UserManagerException ex)
{
Log.ConsoleError(ex.ToString());
args.Player.SendMessage(ex.Message);
}
return;
}
if (args.Player.Group.Name == "superadmin")
{
args.Player.SendMessage("Please disable the auth system! If you need help, consult the forums. http://tshock.co/");
args.Player.SendMessage("This IP address is now superadmin. Please perform the following command:");
args.Player.SendMessage("/user add : superadmin");
args.Player.SendMessage("Creates: with the password as part of the superadmin group.");
args.Player.SendMessage("Please use /login to login from now on.");
args.Player.SendMessage("If you understand, please /login now, and type /auth-verify");
return;
}
args.Player.SendMessage("Incorrect auth code. This incident has been logged.");
Log.Warn(args.Player.IP + " attempted to use an incorrect auth code.");
}
private static void AuthVerify(CommandArgs args)
{
if (TShock.AuthToken == 0)
{
args.Player.SendMessage("It appears that you have already turned off the auth token.");
args.Player.SendMessage("If this is a mistake, delete auth.lck.");
return;
}
if (!args.Player.IsLoggedIn)
{
args.Player.SendMessage("You must be logged in to disable the auth system.");
args.Player.SendMessage("This is a security measure designed to prevent insecure administration setups.");
args.Player.SendMessage("Please re-run /auth and read the instructions!");
args.Player.SendMessage("If you're still confused, consult the forums. http://tshock.co/");
return;
}
args.Player.SendMessage("Your new account has been verified, and the /auth system has been turned off.");
args.Player.SendMessage("You can always use the /user command to manage players. Don't just delete the auth.lck.");
args.Player.SendMessage("Thankyou for using TShock! http://tshock.co/ & http://github.com/TShock/TShock");
FileTools.CreateFile(Path.Combine(TShock.SavePath, "auth.lck"));
File.Delete(Path.Combine(TShock.SavePath, "authcode.txt"));
TShock.AuthToken = 0;
}
private static void ThirdPerson(CommandArgs args)
{
if (args.Parameters.Count == 0)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /me ", Color.Red);
return;
}
Tools.Broadcast(string.Format("*{0} {1}", args.Player.Name, String.Join(" ", args.Parameters)), 205, 133, 63);
}
private static void PartyChat(CommandArgs args)
{
if (args.Parameters.Count == 0)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /p ", Color.Red);
return;
}
int playerTeam = args.Player.Team;
if (playerTeam != 0)
{
string msg = string.Format("<{0}> {1}", args.Player.Name, String.Join(" ", args.Parameters));
foreach (TSPlayer player in TShock.Players)
{
if (player != null && player.Active && player.Team == playerTeam)
player.SendMessage(msg, Main.teamColor[playerTeam].R, Main.teamColor[playerTeam].G, Main.teamColor[playerTeam].B);
}
}
else
{
args.Player.SendMessage("You are not in a party!", 255, 240, 20);
}
}
private static void Rules(CommandArgs args)
{
Tools.ShowFileToUser(args.Player, "rules.txt");
}
private static void Whisper(CommandArgs args)
{
if (args.Parameters.Count < 2)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /whisper ", Color.Red);
return;
}
var players = Tools.FindPlayer(args.Parameters[0]);
if (players.Count == 0)
{
args.Player.SendMessage("Invalid player!", Color.Red);
}
else if (players.Count > 1)
{
args.Player.SendMessage("More than one player matched!", Color.Red);
}
else
{
var plr = players[0];
var msg = string.Join(" ", args.Parameters.ToArray(), 1, args.Parameters.Count - 1);
plr.SendMessage("(Whisper From)" + "<" + args.Player.Name + ">" + msg, Color.MediumPurple);
args.Player.SendMessage("(Whisper To)" + "<" + plr.Name + ">" + msg, Color.MediumPurple);
plr.LastWhisper = args.Player;
args.Player.LastWhisper = plr;
}
}
private static void Reply(CommandArgs args)
{
if (args.Player.LastWhisper != null)
{
var msg = string.Join(" ", args.Parameters);
args.Player.LastWhisper.SendMessage("(Whisper From)" + "<" + args.Player.Name + ">" + msg, Color.MediumPurple);
args.Player.SendMessage("(Whisper To)" + "<" + args.Player.LastWhisper.Name + ">" + msg, Color.MediumPurple);
}
else
args.Player.SendMessage("You haven't previously received any whispers. Please use /whisper to whisper to other people.", Color.Red);
}
private static void Annoy(CommandArgs args)
{
if (args.Parameters.Count != 2)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /annoy ", Color.Red);
return;
}
int annoy = 5;
int.TryParse(args.Parameters[1], out annoy);
var players = Tools.FindPlayer(args.Parameters[0]);
if (players.Count == 0)
args.Player.SendMessage("Invalid player!", Color.Red);
else if (players.Count > 1)
args.Player.SendMessage("More than one player matched!", Color.Red);
else
{
var ply = players[0];
args.Player.SendMessage("Annoying " + ply.Name + " for " + annoy.ToString() + " seconds.");
(new Thread(new ParameterizedThreadStart(ply.Whoopie))).Start(annoy);
}
}
#endregion General Commands
#region Cheat Commands
private static void Kill(CommandArgs args)
{
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /kill ", Color.Red);
return;
}
string plStr = String.Join(" ", args.Parameters);
var players = Tools.FindPlayer(plStr);
if (players.Count == 0)
{
args.Player.SendMessage("Invalid player!", Color.Red);
}
else if (players.Count > 1)
{
args.Player.SendMessage("More than one player matched!", Color.Red);
}
else
{
var plr = players[0];
plr.DamagePlayer(999999);
args.Player.SendMessage(string.Format("You just killed {0}!", plr.Name));
plr.SendMessage(string.Format("{0} just killed you!", args.Player.Name));
}
}
private static void Butcher(CommandArgs args)
{
if (args.Parameters.Count > 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /butcher [killFriendly(true/false)]", Color.Red);
return;
}
bool killFriendly = true;
if (args.Parameters.Count == 1)
bool.TryParse(args.Parameters[0], out killFriendly);
int killcount = 0;
for (int i = 0; i < Main.npc.Length; i++)
{
if (Main.npc[i].active && !Main.npc[i].townNPC && (!Main.npc[i].friendly || killFriendly))
{
TSPlayer.Server.StrikeNPC(i, 99999, 90f, 1);
killcount++;
}
}
Tools.Broadcast(string.Format("Killed {0} NPCs.", killcount));
}
private static void Item(CommandArgs args)
{
if (args.Parameters.Count < 1)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /item - [item amount]", Color.Red);
return;
}
if (args.Parameters[0].Length == 0)
{
args.Player.SendMessage("Missing item name/id", Color.Red);
return;
}
int itemAmount = 0;
int.TryParse(args.Parameters[args.Parameters.Count - 1], out itemAmount);
var items = Tools.GetItemByIdOrName(args.Parameters[0]);
if (items.Count == 0)
{
args.Player.SendMessage("Invalid item type!", Color.Red);
}
else if (items.Count > 1)
{
args.Player.SendMessage(string.Format("More than one ({0}) item matched!", items.Count), Color.Red);
}
else
{
var item = items[0];
if (item.type >= 1 && item.type < Main.maxItemTypes)
{
if (args.Player.InventorySlotAvailable || item.name.Contains("Coin"))
{
if (itemAmount == 0 || itemAmount > item.maxStack)
itemAmount = item.maxStack;
args.Player.GiveItem(item.type, item.name, item.width, item.height, itemAmount);
args.Player.SendMessage(string.Format("Gave {0} {1}(s).", itemAmount.ToString(), item.name));
}
else
{
args.Player.SendMessage("You don't have free slots!", Color.Red);
}
}
else
{
args.Player.SendMessage("Invalid item type!", Color.Red);
}
}
}
private static void Give(CommandArgs args)
{
if (args.Parameters.Count < 2)
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /give
- [item amount]", Color.Red);
return;
}
if (args.Parameters[0].Length == 0)
{
args.Player.SendMessage("Missing item name/id", Color.Red);
return;
}
if (args.Parameters[1].Length == 0)
{
args.Player.SendMessage("Missing player name", Color.Red);
return;
}
int itemAmount = 0;
int.TryParse(args.Parameters[args.Parameters.Count - 1], out itemAmount);
var items = Tools.GetItemByIdOrName(args.Parameters[0]);
if (items.Count == 0)
{
args.Player.SendMessage("Invalid item type!", Color.Red);
}
else if (items.Count > 1)
{
args.Player.SendMessage(string.Format("More than one ({0}) item matched!", items.Count), Color.Red);
}
else
{
var item = items[0];
if (item.type >= 1 && item.type < Main.maxItemTypes)
{
string plStr = args.Parameters[1];
var players = Tools.FindPlayer(plStr);
if (players.Count == 0)
{
args.Player.SendMessage("Invalid player!", Color.Red);
}
else if (players.Count > 1)
{
args.Player.SendMessage("More than one player matched!", Color.Red);
}
else
{
var plr = players[0];
if (plr.InventorySlotAvailable || item.name.Contains("Coin"))
{
if (itemAmount == 0 || itemAmount > item.maxStack)
itemAmount = item.maxStack;
plr.GiveItem(item.type, item.name, item.width, item.height, itemAmount);
args.Player.SendMessage(string.Format("Gave {0} {1} {2}(s).", plr.Name, itemAmount.ToString(), item.name));
plr.SendMessage(string.Format("{0} gave you {1} {2}(s).", args.Player.Name, itemAmount.ToString(), item.name));
}
else
{
args.Player.SendMessage("Player does not have free slots!", Color.Red);
}
}
}
else
{
args.Player.SendMessage("Invalid item type!", Color.Red);
}
}
}
private static void Heal(CommandArgs args)
{
TSPlayer playerToHeal;
if (args.Parameters.Count > 0)
{
string plStr = String.Join(" ", args.Parameters);
var players = Tools.FindPlayer(plStr);
if (players.Count == 0)
{
args.Player.SendMessage("Invalid player!", Color.Red);
return;
}
else if (players.Count > 1)
{
args.Player.SendMessage("More than one player matched!", Color.Red);
return;
}
else
{
playerToHeal = players[0];
}
}
else if (!args.Player.RealPlayer)
{
args.Player.SendMessage("You cant heal yourself!");
return;
}
else
{
playerToHeal = args.Player;
}
Item heart = Tools.GetItemById(58);
Item star = Tools.GetItemById(184);
for (int i = 0; i < 20; i++)
playerToHeal.GiveItem(heart.type, heart.name, heart.width, heart.height, heart.maxStack);
for (int i = 0; i < 10; i++)
playerToHeal.GiveItem(star.type, star.name, star.width, star.height, star.maxStack);
if (playerToHeal == args.Player)
{
args.Player.SendMessage("You just got healed!");
}
else
{
args.Player.SendMessage(string.Format("You just healed {0}", playerToHeal.Name));
playerToHeal.SendMessage(string.Format("{0} just healed you!", args.Player.Name));
}
}
#endregion Cheat Comamnds
}
}