/* 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.Diagnostics; using System.Net; using System.Threading; using Microsoft.Xna.Framework; using Terraria; namespace TShockAPI { public class Commands { public delegate void CommandDelegate(CommandArgs args); public static List commands = new List(); public struct CommandArgs { public string Message; public int PlayerX; public int PlayerY; public int PlayerID; /// /// Parameters passed to the arguement. Does not include the command name. /// IE '/kick "jerk face"' will only have 1 argument /// public List Parameters; public CommandArgs(string message, int x, int y, int id, List args) { Message = message; PlayerX = x; PlayerY = y; PlayerID = id; Parameters = args; } } public class Command { private string name; private string permission; private CommandDelegate command; public Command(string cmdName, string permissionNeeded, CommandDelegate cmd) { name = cmdName; permission = permissionNeeded; command = cmd; } public bool Run(string msg, TSPlayer ply, List parms) { if (!ply.group.HasPermission(permission)) { return false; } CommandArgs args = new CommandArgs(); args.Message = msg; args.PlayerX = (int)ply.GetPlayer().position.X; args.PlayerY = (int)ply.GetPlayer().position.Y; args.PlayerID = ply.GetPlayerID(); args.Parameters = parms; command(args); return true; } public string Name() { return name; } public bool CanRun(TSPlayer ply) { if (!ply.group.HasPermission(permission)) { return false; } return true; } } /// /// Parses a string of parameters into a list. Handles quotes. /// /// /// public 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; } static char GetEscape(char c) { switch (c) { case '\\': return '\\'; case '"': return '"'; case 't': return '\t'; default: return c; } } static bool IsWhiteSpace(char c) { return c == ' ' || c == '\t' || c == '\n'; } public static void InitCommands() { commands.Add(new Command("kick", "kick", Kick)); commands.Add(new Command("ban", "ban", Ban)); commands.Add(new Command("banip", "ban", BanIP)); commands.Add(new Command("unban", "unban", UnBan)); commands.Add(new Command("unbanip", "unbanip", UnBanIP)); commands.Add(new Command("off", "maintenance", Off)); commands.Add(new Command("off-nosave", "maintenance", OffNoSave)); commands.Add(new Command("checkupdates", "maintenance", CheckUpdates)); commands.Add(new Command("dropmeteor", "causeevents", DropMeteor)); commands.Add(new Command("star", "causeevents", Star)); commands.Add(new Command("bloodmoon", "causeevents", Bloodmoon)); commands.Add(new Command("invade", "causeevents", Invade)); commands.Add(new Command("eater", "spawnboss", Eater)); commands.Add(new Command("eye", "spawnboss", Eye)); commands.Add(new Command("skeletron", "spawnboss", Skeletron)); commands.Add(new Command("hardcore", "spawnboss", Hardcore)); commands.Add(new Command("spawnmob", "spawnmob", SpawnMob)); commands.Add(new Command("home", "tp", Home)); commands.Add(new Command("spawn", "tp", Spawn)); commands.Add(new Command("tp", "tp", TP)); commands.Add(new Command("tphere", "tp", TPHere)); commands.Add(new Command("reload", "cfg", Reload)); commands.Add(new Command("debug-config", "cfg", DebugConfiguration)); commands.Add(new Command("password", "cfg", Password)); commands.Add(new Command("save", "cfg", Save)); commands.Add(new Command("maxspawns", "cfg", MaxSpawns)); commands.Add(new Command("spawnrate", "cfg", SpawnRate)); commands.Add(new Command("time", "cfg", Time)); commands.Add(new Command("slap", "pvpfun", Slap)); commands.Add(new Command("protectspawn", "editspawn", ProtectSpawn)); commands.Add(new Command("help", "", Help)); commands.Add(new Command("playing", "", Playing)); commands.Add(new Command("online", "", Playing)); commands.Add(new Command("who", "", Playing)); commands.Add(new Command("auth", "", AuthToken)); commands.Add(new Command("me", "", ThirdPerson)); commands.Add(new Command("p", "", PartyChat)); if (ConfigurationManager.distributationAgent != "terraria-online") { commands.Add(new Command("kill", "kill", Kill)); commands.Add(new Command("butcher", "cheat", Butcher)); commands.Add(new Command("i", "cheat", Item)); commands.Add(new Command("item", "cheat", Item)); commands.Add(new Command("give", "cheat", Give)); commands.Add(new Command("heal", "cheat", Heal)); } } #region Command Methods public static void CheckUpdates(CommandArgs args) { ThreadPool.QueueUserWorkItem(UpdateManager.CheckUpdate); } public static void PartyChat(CommandArgs args) { int playerTeam = Main.player[args.PlayerID].team; if (playerTeam != 0) { string msg = string.Format("<{0}> {1}", Main.player[args.PlayerID].name, args.Message.Remove(0, 2)); for (int i = 0; i < Main.player.Length; i++) { if (Main.player[i].team == Main.player[args.PlayerID].team) { Tools.SendMessage(i, msg, Main.teamColor[playerTeam].R, Main.teamColor[playerTeam].G, Main.teamColor[playerTeam].B); } } } else { Tools.SendMessage(args.PlayerID, "You are not in a party!", 255f, 240f, 20f); } } public static void ThirdPerson(CommandArgs args) { string msg = args.Message.Remove(0, 3); Tools.Broadcast(string.Format("*{0} {1}", Tools.FindPlayer(args.PlayerID), msg, 205, 133, 63)); } public static void Playing(CommandArgs args) { Tools.SendMessage(args.PlayerID, string.Format("Current players: {0}.", Tools.GetPlayers()), 255f, 240f, 20f); } public static void DebugConfiguration(CommandArgs args) { int ply = args.PlayerID; Tools.SendMessage(ply, "TShock Config:"); string lineOne = string.Format("BanCheater : {0}, KickCheater : {1}, BanGriefer : {2}, KickGriefer : {3}", ConfigurationManager.banCheater, ConfigurationManager.kickCheater, ConfigurationManager.banGriefer, ConfigurationManager.kickGriefer); Tools.SendMessage(ply, lineOne, Color.Yellow); string lineTwo = string.Format("BanTnt : {0}, KickTnt : {1}, BanBoom : {2}, KickBoom : {3}", ConfigurationManager.banTnt, ConfigurationManager.kickTnt, ConfigurationManager.banBoom, ConfigurationManager.kickBoom); Tools.SendMessage(ply, lineTwo, Color.Yellow); string lineThree = string.Format("InvMultiplier : {0}, ProtectS : {1}, ProtectR : {2}, DMS : {3}, SpawnRate {4}", ConfigurationManager.invasionMultiplier, ConfigurationManager.spawnProtect, ConfigurationManager.spawnProtectRadius, ConfigurationManager.defaultMaxSpawns, ConfigurationManager.defaultSpawnRate); Tools.SendMessage(ply, lineThree, Color.Yellow); string lineFour = string.Format("MaxSlots : {0}, RangeChecks : {1}, SpamChecks : {2}", ConfigurationManager.maxSlots, ConfigurationManager.rangeChecks, ConfigurationManager.spamChecks); Tools.SendMessage(ply, lineFour, Color.Yellow); } public static void Kick(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count < 1) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /kick [reason]", Color.Red); return; } if (args.Parameters[0].Length == 0) { Tools.SendMessage(adminplr, "Missing player name", Color.Red); return; } string plStr = args.Parameters[0]; int player = Tools.FindPlayer(plStr); if (player == -1) Tools.SendMessage(adminplr, "Invalid player!", Color.Red); else if (player == -2) Tools.SendMessage(adminplr, "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(player, reason)) { Tools.SendMessage(adminplr, "You can't kick another admin!", Color.Red); } } } public static void Ban(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count < 1) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /ban [reason]", Color.Red); return; } if (args.Parameters[0].Length == 0) { Tools.SendMessage(adminplr, "Missing player name", Color.Red); return; } string plStr = args.Parameters[0]; int player = Tools.FindPlayer(plStr); if (player == -1) Tools.SendMessage(adminplr, "Invalid player!", Color.Red); else if (player == -2) Tools.SendMessage(adminplr, "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(player, reason)) { Tools.SendMessage(adminplr, "You can't ban another admin!", Color.Red); } } } public static void BanIP(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count < 1) { Tools.SendMessage(adminplr, "Syntax: /banip [reason]", Color.Red); return; } if (args.Parameters[0].Length == 0) { Tools.SendMessage(adminplr, "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); } public static void UnBan(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count < 1) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /unban ", Color.Red); return; } if (args.Parameters[0].Length == 0) { Tools.SendMessage(adminplr, "Missing player name", Color.Red); return; } string plStr = args.Parameters[0]; var ban = TShock.Bans.GetBanByName(plStr); if (ban != null) { TShock.Bans.RemoveBan(ban); Tools.SendMessage(adminplr, string.Format("Unbanned {0} ({1})!", ban.Name, ban.IP), Color.Red); } else { Tools.SendMessage(adminplr, "Invalid player!", Color.Red); } } public static void UnBanIP(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count < 1) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /unbanip ", Color.Red); return; } if (args.Parameters[0].Length == 0) { Tools.SendMessage(adminplr, "Missing ip", Color.Red); return; } string plStr = args.Parameters[0]; var ban = TShock.Bans.GetBanByIp(plStr); if (ban != null) { TShock.Bans.RemoveBan(ban); Tools.SendMessage(adminplr, string.Format("Unbanned {0} ({1})!", ban.Name, ban.IP), Color.Red); } else { Tools.SendMessage(adminplr, "Invalid player!", Color.Red); } } public static void Off(CommandArgs args) { for (int player = 0; player < Main.maxPlayers; player++) { if (Main.player[player].active) { Tools.ForceKick(player, "Server shutting down!"); } } WorldGen.saveWorld(); Netplay.disconnect = true; } public static void OffNoSave(CommandArgs args) { Netplay.disconnect = true; } public static void Reload(CommandArgs args) { FileTools.SetupConfig(); Tools.SendMessage(args.PlayerID, "Configuration reload complete. Some changes may require server restart."); } public static void DropMeteor(CommandArgs args) { WorldGen.spawnMeteor = false; WorldGen.dropMeteor(); } public 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); } public static void Bloodmoon(CommandArgs args) { int ply = args.PlayerID; Tools.Broadcast(string.Format("{0} turned on blood moon.", Tools.FindPlayer(ply))); Main.bloodMoon = true; Main.time = 0; Main.dayTime = false; NetMessage.SendData(18, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); NetMessage.syncPlayers(); } public static void Eater(CommandArgs args) { int x = args.PlayerX; int y = args.PlayerY; int ply = args.PlayerID; Tools.NewNPC((int)ConfigurationManager.NPCList.WORLD_EATER, x, y, ply); Tools.Broadcast(string.Format("{0} has spawned an eater of worlds!", Tools.FindPlayer(ply))); } public static void Eye(CommandArgs args) { int x = args.PlayerX; int y = args.PlayerY; int ply = args.PlayerID; Tools.NewNPC((int)ConfigurationManager.NPCList.EYE, x, y, ply); Tools.Broadcast(string.Format("{0} has spawned an eye!", Tools.FindPlayer(ply))); } public static void Skeletron(CommandArgs args) { int x = args.PlayerX; int y = args.PlayerY; int ply = args.PlayerID; Tools.NewNPC((int)ConfigurationManager.NPCList.SKELETRON, x, y, ply); Tools.Broadcast(string.Format("{0} has spawned skeletron!", Tools.FindPlayer(ply))); } public static void Hardcore(CommandArgs args) { int x = args.PlayerX; int y = args.PlayerY; int ply = args.PlayerID; for (int i = 0; i <= 2; i++) { Tools.NewNPC(i, x, y, ply); } Tools.Broadcast(string.Format("{0} has spawned all 3 bosses!", Tools.FindPlayer(ply))); } public static void Invade(CommandArgs args) { int ply = args.PlayerID; if (Main.invasionSize <= 0) { Tools.Broadcast(string.Format("{0} has started an invasion.", Tools.FindPlayer(ply))); TShock.StartInvasion(); } else { Tools.Broadcast(string.Format("{0} has ended an invasion.", Tools.FindPlayer(ply))); Main.invasionSize = 0; } } public static void Password(CommandArgs args) { int ply = args.PlayerID; string passwd = args.Message.Remove(0, 9).Trim(); Netplay.password = passwd; Tools.SendMessage(ply, string.Format("Server password changed to: {0}", passwd)); } public static void Save(CommandArgs args) { int ply = args.PlayerID; WorldGen.saveWorld(); Tools.SendMessage(ply, "World saved."); } public static void Home(CommandArgs args) { int ply = args.PlayerID; TShock.Teleport(ply, Main.player[args.PlayerID].SpawnX * 16 + 8 - Main.player[ply].width / 2, Main.player[args.PlayerID].SpawnY * 16 - Main.player[ply].height); Tools.SendMessage(ply, "Teleported to your spawnpoint."); } public static void Spawn(CommandArgs args) { int ply = args.PlayerID; TShock.Teleport(ply, Main.spawnTileX * 16 + 8 - Main.player[ply].width / 2, Main.spawnTileY * 16 - Main.player[ply].height); Tools.SendMessage(ply, "Teleported to the map's spawnpoint."); } public static void AuthToken(CommandArgs args) { if (ConfigurationManager.authToken == 0) { return; } int givenCode = Convert.ToInt32(args.Parameters[0]); if (givenCode == ConfigurationManager.authToken) { TextWriter tw = new StreamWriter(FileTools.SaveDir + "users.txt", true); tw.Write("\n" + Tools.GetRealIP( Convert.ToString(Netplay.serverSock[args.PlayerID].tcpClient.Client.RemoteEndPoint)) + " superadmin"); Tools.SendMessage(args.PlayerID, "SuperAdmin authenticated. Please re-connect using the same IP."); ConfigurationManager.authToken = 0; tw.Close(); } } public static void TP(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count < 1) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /tp ", Color.Red); return; } string plStr = String.Join(" ", args.Parameters); int player = Tools.FindPlayer(plStr); if (player == -1) Tools.SendMessage(adminplr, "Invalid player!", Color.Red); else if (player == -2) Tools.SendMessage(adminplr, "More than one player matched!", Color.Red); else { TShock.Teleport(adminplr, Main.player[player].position.X, Main.player[player].position.Y); Tools.SendMessage(adminplr, string.Format("Teleported to {0}", Tools.FindPlayer(player))); } } public static void TPHere(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count < 1) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /tphere ", Color.Red); return; } string plStr = String.Join(" ", args.Parameters); int player = Tools.FindPlayer(plStr); if (player == -1) Tools.SendMessage(adminplr, "Invalid player!", Color.Red); else if (player == -2) Tools.SendMessage(adminplr, "More than one player matched!", Color.Red); else { TShock.Teleport(player, Main.player[adminplr].position.X, Main.player[adminplr].position.Y); Tools.SendMessage(player, string.Format("You were teleported to {0}.", Tools.FindPlayer(adminplr))); Tools.SendMessage(adminplr, string.Format("You brought {0} here.", Tools.FindPlayer(player))); } } public static void SpawnMob(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count < 1 || args.Parameters.Count > 2) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /spawnmob [amount]", Color.Red); return; } if (args.Parameters[0].Length == 0) { Tools.SendMessage(adminplr, "Missing mob name/id", Color.Red); return; } int x = args.PlayerX; int y = args.PlayerY; int type = -1; int amount = 1; if (!int.TryParse(args.Parameters[0], out type)) type = TShock.GetNPCID(args.Parameters[0]); if (args.Parameters.Count == 2 && !int.TryParse(args.Parameters[1], out amount)) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /spawnmob [amount]", Color.Red); return; } if (type >= 1 && type < Main.maxNPCTypes) { int npcid = -1; for (int i = 0; i < amount; i++) npcid = NPC.NewNPC(x, y, type, 0); Tools.Broadcast(string.Format("{0} was spawned {1} time(s).", Main.npc[npcid].name, amount)); } else Tools.SendMessage(adminplr, "Invalid mob type!", Color.Red); } public static void Item(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count < 1) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /item ", Color.Red); return; } if (args.Parameters[0].Length == 0) { Tools.SendMessage(adminplr, "Missing item name/id", Color.Red); return; } int type = -1; if (!int.TryParse(args.Parameters[0], out type)) type = TShock.GetItemID(String.Join(" ", args.Parameters)); if (type < 1 || type >= Main.maxItemTypes) { Tools.SendMessage(adminplr, "Invalid item type!", Color.Red); return; } bool flag = false; for (int i = 0; i < 40; i++) { if (!Main.player[adminplr].inventory[i].active) { //Main.player[ply].inventory[i].SetDefaults(type); //Main.player[ply].inventory[i].stack = Main.player[ply].inventory[i].maxStack; int id = Terraria.Item.NewItem(0, 0, 0, 0, type, 1, true); Main.item[id].position.X = args.PlayerX; Main.item[id].position.Y = args.PlayerY; Main.item[id].stack = Main.item[id].maxStack; //TShock.SendDataAll(21, -1, "", id); NetMessage.SendData(21, -1, -1, "", id, 0f, 0f, 0f); Tools.SendMessage(adminplr, string.Format("Got some {0}.", Main.item[id].name)); //TShock.UpdateInventories(); flag = true; break; } } if (!flag) Tools.SendMessage(adminplr, "You don't have free slots!", Color.Red); } public static void Give(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count != 2) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /give ", Color.Red); return; } if (args.Parameters[0].Length == 0) { Tools.SendMessage(adminplr, "Missing item name/id", Color.Red); return; } if (args.Parameters[1].Length == 0) { Tools.SendMessage(adminplr, "Missing player name", Color.Red); return; } int type = -1; if (!int.TryParse(args.Parameters[0], out type)) type = TShock.GetItemID(args.Parameters[0]); if (type < 1 || type >= Main.maxItemTypes) { Tools.SendMessage(args.PlayerID, "Invalid item type!", Color.Red); return; } string plStr = args.Parameters[1]; int player = Tools.FindPlayer(plStr); if (player == -1) Tools.SendMessage(adminplr, "Invalid player!", Color.Red); else if (player == -2) Tools.SendMessage(adminplr, "More than one player matched!", Color.Red); else { bool flag = false; for (int i = 0; i < 40; i++) { if (!Main.player[player].inventory[i].active) { //Main.player[player].inventory[i].SetDefaults(type); //Main.player[player].inventory[i].stack = Main.player[player].inventory[i].maxStack; int id = Terraria.Item.NewItem(0, 0, 0, 0, type, 1, true); Main.item[id].position.X = Main.player[player].position.X; Main.item[id].position.Y = Main.player[player].position.Y; Main.item[id].stack = Main.item[id].maxStack; //TShock.SendDataAll(21, -1, "", id); NetMessage.SendData(21, -1, -1, "", id, 0f, 0f, 0f); Tools.SendMessage(adminplr, string.Format("Gave {0} some {1}.", Tools.FindPlayer(player), Main.item[id].name)); Tools.SendMessage(player, string.Format("{0} gave you some {1}.", Tools.FindPlayer(adminplr), Main.item[id].name)); //TShock.UpdateInventories(); flag = true; break; } } if (!flag) Tools.SendMessage(args.PlayerID, "Player does not have free slots!", Color.Red); } } public static void Heal(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count > 0) { string plStr = String.Join(" ", args.Parameters); int player = Tools.FindPlayer(plStr); if (player == -1) Tools.SendMessage(adminplr, "Invalid player!", Color.Red); else if (player == -2) Tools.SendMessage(adminplr, "More than one player matched!", Color.Red); else { DropHearts((int)Main.player[player].position.X, (int)Main.player[player].position.Y, 20); Tools.SendMessage(adminplr, string.Format("You just healed {0}", Tools.FindPlayer(player))); Tools.SendMessage(player, string.Format("{0} just healed you!", Tools.FindPlayer(adminplr))); } } else { DropHearts(args.PlayerX, args.PlayerY, 20); Tools.SendMessage(adminplr, "You just got healed!"); } } private static void DropHearts(int x, int y, int count) { for (int i = 0; i < count; i++) { int itemid = Terraria.Item.NewItem(1, 1, 1, 1, 58); Main.item[itemid].position.X = x; Main.item[itemid].position.Y = y; NetMessage.SendData(21, -1, -1, "", itemid, 0f, 0f, 0f); } } public static void Butcher(CommandArgs args) { int killcount = 0; for (int i = 0; i < Main.npc.Length; i++) { if (Main.npc[i].townNPC || !Main.npc[i].active) continue; else { Main.npc[i].StrikeNPC(99999, 90f, 1); NetMessage.SendData(28, -1, -1, "", i, 99999, 90f, 1); killcount++; } } Tools.Broadcast(string.Format("Killed {0} NPCs.", killcount)); } public static void MaxSpawns(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count != 1) { Tools.SendMessage(adminplr, "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; ConfigurationManager.defaultMaxSpawns = amount; Tools.Broadcast(string.Format("{0} changed the maximum spawns to: {1}", Tools.FindPlayer(adminplr), amount)); } public static void SpawnRate(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count != 1) { Tools.SendMessage(adminplr, "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; ConfigurationManager.defaultSpawnRate = amount; Tools.Broadcast(string.Format("{0} changed the spawn rate to: {1}", Tools.FindPlayer(adminplr), amount)); } public static void Help(CommandArgs args) { int ply = args.PlayerID; Tools.SendMessage(ply, "TShock Commands:"); int page = 1; if (args.Parameters.Count > 0) int.TryParse(args.Parameters[0], out page); List cmdlist = new List(); for (int j = 0; j < commands.Count; j++) { if (commands[j].CanRun(TShock.players[ply])) { cmdlist.Add(commands[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) { Tools.SendMessage(ply, sb.ToString(), Color.Yellow); break; } if ((j + 1) % 5 == 0) { Tools.SendMessage(ply, sb.ToString(), Color.Yellow); sb.Clear(); } } } if (cmdlist.Count > (15 * page)) { Tools.SendMessage(ply, string.Format("Type /help {0} for more commands.", (page + 1)), Color.Yellow); } } public static void Time(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count != 1) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /time ", Color.Red); return; } switch (args.Parameters[0]) { case "day": Main.time = 0; Main.dayTime = true; NetMessage.SendData(18, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); NetMessage.syncPlayers(); Tools.Broadcast(string.Format("{0} set time to day.", Tools.FindPlayer(args.PlayerID))); break; case "night": Main.time = 0; Main.dayTime = false; NetMessage.SendData(18, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); NetMessage.syncPlayers(); Tools.Broadcast(string.Format("{0} set time to night.", Tools.FindPlayer(args.PlayerID))); break; case "dusk": Main.dayTime = false; Main.time = 0.0; NetMessage.SendData(18, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); NetMessage.syncPlayers(); Tools.Broadcast(string.Format("{0} set time to dusk.", Tools.FindPlayer(args.PlayerID))); break; case "noon": Main.dayTime = true; Main.time = 27000.0; NetMessage.SendData(18, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); NetMessage.syncPlayers(); Tools.Broadcast(string.Format("{0} set time to noon.", Tools.FindPlayer(args.PlayerID))); break; case "midnight": Main.dayTime = false; Main.time = 16200.0; NetMessage.SendData(18, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); NetMessage.syncPlayers(); Tools.Broadcast(string.Format("{0} set time to midnight.", Tools.FindPlayer(args.PlayerID))); break; default: Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /time ", Color.Red); break; } } public static void Kill(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count < 1) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /kill ", Color.Red); return; } string plStr = String.Join(" ", args.Parameters); int player = Tools.FindPlayer(plStr); if (player == -1) Tools.SendMessage(adminplr, "Invalid player!", Color.Red); else if (player == -2) Tools.SendMessage(adminplr, "More than one player matched!", Color.Red); else if (player == adminplr) Tools.SendMessage(adminplr, "Can't kill yourself!", Color.Red); else { Tools.SendMessage(adminplr, string.Format("You just killed {0}!", Tools.FindPlayer(player))); Tools.SendMessage(player, string.Format("{0} just killed you!", Tools.FindPlayer(adminplr))); TShock.KillMe(player); } } public static void Slap(CommandArgs args) { int adminplr = args.PlayerID; if (args.Parameters.Count < 1 || args.Parameters.Count > 2) { Tools.SendMessage(adminplr, "Invalid syntax! Proper syntax: /slap [dmg]", Color.Red); return; } if (args.Parameters[0].Length == 0) { Tools.SendMessage(adminplr, "Missing player name", Color.Red); return; } string plStr = args.Parameters[0]; int player = Tools.FindPlayer(plStr); if (player == -1) Tools.SendMessage(adminplr, "Invalid player!", Color.Red); else if (player == -2) Tools.SendMessage(adminplr, "More than one player matched!", Color.Red); else { int damage = 5; if (args.Parameters.Count == 2) { int.TryParse(args.Parameters[1], out damage); } NetMessage.SendData(26, -1, -1, "", player, ((new Random()).Next(-1, 1)), damage, (float)0); Tools.Broadcast(string.Format("{0} slapped {1} for {2} damage.", Tools.FindPlayer(adminplr), Tools.FindPlayer(player), damage)); } } public static void ProtectSpawn(CommandArgs args) { ConfigurationManager.spawnProtect = (ConfigurationManager.spawnProtect == false); Tools.SendMessage(args.PlayerID, string.Format("Spawn is now {0}.", (ConfigurationManager.spawnProtect ? "protected" : "open"))); } public 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")); for (int player = 0; player < Main.maxPlayers; player++) { if (Main.player[player].active) { Tools.ForceKick(player, "Server shutting down for update!"); } } WorldGen.saveWorld(); Netplay.disconnect = true; } #endregion Command Methods } }