diff --git a/TShockAPI/BackupManager.cs b/TShockAPI/BackupManager.cs index 50f8e2cc..4cf79cff 100644 --- a/TShockAPI/BackupManager.cs +++ b/TShockAPI/BackupManager.cs @@ -24,81 +24,79 @@ using Terraria; namespace TShockAPI { - public class BackupManager - { - public string BackupPath { get; set; } - public int Interval { get; set; } - public int KeepFor { get; set; } + public class BackupManager + { + public string BackupPath { get; set; } + public int Interval { get; set; } + public int KeepFor { get; set; } - DateTime lastbackup = DateTime.UtcNow; - public BackupManager(string path) - { - BackupPath = path; - } + private DateTime lastbackup = DateTime.UtcNow; - public bool IsBackupTime - { - get - { - return (Interval > 0) && ((DateTime.UtcNow - lastbackup).TotalMinutes >= Interval); - } - } + public BackupManager(string path) + { + BackupPath = path; + } - public void Backup() - { - lastbackup = DateTime.UtcNow; - ThreadPool.QueueUserWorkItem(DoBackup); - ThreadPool.QueueUserWorkItem(DeleteOld); - } + public bool IsBackupTime + { + get { return (Interval > 0) && ((DateTime.UtcNow - lastbackup).TotalMinutes >= Interval); } + } - void DoBackup(object o) - { - try - { - string worldname = Main.worldPathName; - string name = Path.GetFileName(worldname); + public void Backup() + { + lastbackup = DateTime.UtcNow; + ThreadPool.QueueUserWorkItem(DoBackup); + ThreadPool.QueueUserWorkItem(DeleteOld); + } - Main.worldPathName = Path.Combine(BackupPath, string.Format("{0}.{1:dd.MM.yy-HH.mm.ss}.bak", name, DateTime.UtcNow)); + private void DoBackup(object o) + { + try + { + string worldname = Main.worldPathName; + string name = Path.GetFileName(worldname); - string worldpath = Path.GetDirectoryName(Main.worldPathName); - if (worldpath != null && !Directory.Exists(worldpath)) - Directory.CreateDirectory(worldpath); + Main.worldPathName = Path.Combine(BackupPath, string.Format("{0}.{1:dd.MM.yy-HH.mm.ss}.bak", name, DateTime.UtcNow)); - TShock.Utils.Broadcast("Server map saving, potential lag spike"); - Console.WriteLine("Backing up world..."); + string worldpath = Path.GetDirectoryName(Main.worldPathName); + if (worldpath != null && !Directory.Exists(worldpath)) + Directory.CreateDirectory(worldpath); - Thread SaveWorld = new Thread(TShock.Utils.SaveWorld); - SaveWorld.Start(); + TShock.Utils.Broadcast("Server map saving, potential lag spike"); + Console.WriteLine("Backing up world..."); - while (SaveWorld.ThreadState == ThreadState.Running) - Thread.Sleep(50); - Console.WriteLine("World backed up"); - Console.ForegroundColor = ConsoleColor.Gray; - Log.Info(string.Format("World backed up ({0})", Main.worldPathName)); + Thread SaveWorld = new Thread(TShock.Utils.SaveWorld); + SaveWorld.Start(); - Main.worldPathName = worldname; - } - catch (Exception ex) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine("Backup failed"); - Console.ForegroundColor = ConsoleColor.Gray; - Log.Error("Backup failed"); - Log.Error(ex.ToString()); - } - } + while (SaveWorld.ThreadState == ThreadState.Running) + Thread.Sleep(50); + Console.WriteLine("World backed up"); + Console.ForegroundColor = ConsoleColor.Gray; + Log.Info(string.Format("World backed up ({0})", Main.worldPathName)); - void DeleteOld(object o) - { - if (KeepFor <= 0) - return; - foreach (var fi in new DirectoryInfo(BackupPath).GetFiles("*.bak")) - { - if ((DateTime.UtcNow - fi.LastWriteTimeUtc).TotalMinutes > KeepFor) - { - fi.Delete(); - } - } - } - } -} + Main.worldPathName = worldname; + } + catch (Exception ex) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Backup failed"); + Console.ForegroundColor = ConsoleColor.Gray; + Log.Error("Backup failed"); + Log.Error(ex.ToString()); + } + } + + private void DeleteOld(object o) + { + if (KeepFor <= 0) + return; + foreach (var fi in new DirectoryInfo(BackupPath).GetFiles("*.bak")) + { + if ((DateTime.UtcNow - fi.LastWriteTimeUtc).TotalMinutes > KeepFor) + { + fi.Delete(); + } + } + } + } +} \ No newline at end of file diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index c06a18e9..90283e82 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -30,615 +30,628 @@ 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 delegate void CommandDelegate(CommandArgs args); - public Player TPlayer - { - get { return Player.TPlayer; } - } + public class CommandArgs : EventArgs + { + public string Message { get; private set; } + public TSPlayer Player { get; private set; } - 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; } - public string Permission { get; protected set; } - private CommandDelegate command; + /// + /// 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 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 Player TPlayer + { + get { return Player.TPlayer; } + } - public bool Run(string msg, TSPlayer ply, List parms) - { - if (!ply.Group.HasPermission(Permission)) - return false; + public CommandArgs(string message, TSPlayer ply, List args) + { + Message = message; + Player = ply; + Parameters = args; + } + } - try - { - command(new CommandArgs(msg, ply, parms)); - } - catch (Exception e) - { - ply.SendMessage("Command failed, check logs for more details."); - Log.Error(e.ToString()); - } + public class Command + { + public string Name + { + get { return Names[0]; } + } - return true; - } + public List Names { get; protected set; } + public bool DoLog { get; set; } + public string Permission { get; protected set; } + private CommandDelegate command; - public bool HasAlias(string name) - { - return Names.Contains(name); - } + public Command(string permissionneeded, CommandDelegate cmd, params string[] names) + : this(cmd, names) + { + Permission = permissionneeded; + } - public bool CanRun(TSPlayer ply) - { - return ply.Group.HasPermission(Permission); - } - } - public static class Commands - { - public static List ChatCommands = new List(); + 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; + } - delegate void AddChatCommand(string permission, CommandDelegate command, params string[] names); - public static void InitCommands() - { - //When adding new perm in here, add new perm to CommandList in DBEditor - AddChatCommand add = (p, c, n) => ChatCommands.Add(new Command(p, c, n)); - add(Permissions.kick, Kick, "kick"); - add(Permissions.ban, Ban, "ban"); - add(Permissions.ban, BanIP, "banip"); - add(Permissions.ban, UnBan, "unban"); - add(Permissions.ban, UnBanIP, "unbanip"); - add(Permissions.maintenance, ClearBans, "clearbans"); - add(Permissions.whitelist, Whitelist, "whitelist"); - add(Permissions.maintenance, Off, "off", "exit"); - add(Permissions.maintenance, OffNoSave, "off-nosave", "exit-nosave"); - add(Permissions.maintenance, CheckUpdates, "checkupdates"); - add(Permissions.causeevents, DropMeteor, "dropmeteor"); - add(Permissions.causeevents, Star, "star"); - add(Permissions.causeevents, Fullmoon, "fullmoon"); - add(Permissions.causeevents, Bloodmoon, "bloodmoon"); - add(Permissions.causeevents, Invade, "invade"); - add(Permissions.spawnboss, Eater, "eater"); - add(Permissions.spawnboss, Eye, "eye"); - add(Permissions.spawnboss, King, "king"); - add(Permissions.spawnboss, Skeletron, "skeletron"); - add(Permissions.spawnboss, WoF, "wof", "wallofflesh"); - add(Permissions.spawnboss, Twins, "twins"); - add(Permissions.spawnboss, Destroyer, "destroyer"); - add(Permissions.spawnboss, SkeletronPrime, "skeletronp", "prime"); - add(Permissions.spawnboss, Hardcore, "hardcore"); - add(Permissions.spawnmob, SpawnMob, "spawnmob", "sm"); - add(Permissions.tp, Home, "home"); - add(Permissions.tp, Spawn, "spawn"); - add(Permissions.tp, TP, "tp"); - add(Permissions.tphere, TPHere, "tphere"); - add(Permissions.tphere, SendWarp, "sendwarp", "sw"); - add(Permissions.tpallow, TPAllow, "tpallow"); - add(Permissions.warp, UseWarp, "warp"); - add(Permissions.managewarp, SetWarp, "setwarp"); - add(Permissions.managewarp, DeleteWarp, "delwarp"); - add(Permissions.managewarp, HideWarp, "hidewarp"); - add(Permissions.managegroup, AddGroup, "addgroup"); - add(Permissions.managegroup, DeleteGroup, "delgroup"); - add(Permissions.managegroup, ModifyGroup, "modgroup"); - add(Permissions.manageitem, AddItem, "additem"); - add(Permissions.manageitem, DeleteItem, "delitem"); - add(Permissions.cfg, SetSpawn, "setspawn"); - add(Permissions.cfg, Reload, "reload"); - add(Permissions.cfg, ServerPassword, "serverpassword"); - add(Permissions.cfg, Save, "save"); - add(Permissions.cfg, Settle, "settle"); - add(Permissions.cfg, MaxSpawns, "maxspawns"); - add(Permissions.cfg, SpawnRate, "spawnrate"); - add(Permissions.time, Time, "time"); - add(Permissions.pvpfun, Slap, "slap"); - add(Permissions.editspawn, ToggleAntiBuild, "antibuild"); - add(Permissions.editspawn, ProtectSpawn, "protectspawn"); - add(Permissions.manageregion, Region, "region"); - add(Permissions.manageregion, DebugRegions, "debugreg"); - add(null, Help, "help"); - add(null, Playing, "playing", "online", "who", "version"); - add(null, AuthToken, "auth"); - add(Permissions.cantalkinthird, ThirdPerson, "me"); - add(Permissions.canpartychat, PartyChat, "p"); - add(null, Motd, "motd"); - add(null, Rules, "rules"); - add(Permissions.mute, Mute, "mute", "unmute"); - add(Permissions.logs, DisplayLogs, "displaylogs"); - ChatCommands.Add(new Command(Permissions.canchangepassword, PasswordUser, "password") { DoLog = false }); - ChatCommands.Add(new Command(Permissions.canregister, RegisterUser, "register") { DoLog = false }); - ChatCommands.Add(new Command(Permissions.rootonly, ManageUsers, "user") { DoLog = false }); - add(Permissions.rootonly, GrabUserUserInfo, "userinfo", "ui"); - add(Permissions.rootonly, AuthVerify, "auth-verify"); - ChatCommands.Add(new Command(Permissions.canlogin, AttemptLogin, "login") { DoLog = false }); - add(Permissions.cfg, Broadcast, "broadcast", "bc"); - add(Permissions.whisper, Whisper, "whisper", "w", "tell"); - add(Permissions.whisper, Reply, "reply", "r"); - add(Permissions.annoy, Annoy, "annoy"); - add(Permissions.cfg, ConvertWaR, "convert"); - add(Permissions.kill, Kill, "kill"); - add(Permissions.butcher, Butcher, "butcher"); - add(Permissions.item, Item, "item", "i"); - add(Permissions.item, Give, "give"); - add(Permissions.clearitems, ClearItems, "clearitems"); - add(Permissions.heal, Heal, "heal"); - add(Permissions.buff, Buff, "buff"); - add(Permissions.buffplayer, GBuff, "gbuff", "buffplayer"); - add(Permissions.grow, Grow, "grow"); - add(Permissions.hardmode, StartHardMode, "hardmode"); - add(Permissions.hardmode, DisableHardMode, "stophardmode", "disablehardmode"); - add(Permissions.cfg, ServerInfo, "stats"); - add(Permissions.converthardmode, ConvertCorruption, "convertcorruption"); - add(Permissions.converthardmode, ConvertHallow, "converthallow"); - } + public bool Run(string msg, TSPlayer ply, List parms) + { + if (!ply.Group.HasPermission(Permission)) + return false; - public static bool HandleCommand(TSPlayer player, string text) - { - string cmdText = text.Remove(0, 1); + try + { + command(new CommandArgs(msg, ply, parms)); + } + catch (Exception e) + { + ply.SendMessage("Command failed, check logs for more details."); + Log.Error(e.ToString()); + } - var args = ParseParameters(cmdText); - if (args.Count < 1) - return false; + return true; + } - string cmdName = args[0]; - args.RemoveAt(0); + public bool HasAlias(string name) + { + return Names.Contains(name); + } - Command cmd = ChatCommands.FirstOrDefault(c => c.HasAlias(cmdName)); + public bool CanRun(TSPlayer ply) + { + return ply.Group.HasPermission(Permission); + } + } - if (cmd == null) - { - player.SendMessage("Invalid Command Entered. Type /help for a list of valid Commands.", Color.Red); - return true; - } + public static class Commands + { + public static List ChatCommands = new List(); - if (!cmd.CanRun(player)) - { - TShock.Utils.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) - TShock.Utils.SendLogs(string.Format("{0} executed: /{1}", player.Name, cmdText), Color.Red); - cmd.Run(cmdText, player, args); - } - return true; - } + private delegate void AddChatCommand(string permission, CommandDelegate command, params string[] names); - /// - /// 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]; + public static void InitCommands() + { + //When adding new perm in here, add new perm to CommandList in DBEditor + AddChatCommand add = (p, c, n) => ChatCommands.Add(new Command(p, c, n)); + add(Permissions.kick, Kick, "kick"); + add(Permissions.ban, Ban, "ban"); + add(Permissions.ban, BanIP, "banip"); + add(Permissions.ban, UnBan, "unban"); + add(Permissions.ban, UnBanIP, "unbanip"); + add(Permissions.maintenance, ClearBans, "clearbans"); + add(Permissions.whitelist, Whitelist, "whitelist"); + add(Permissions.maintenance, Off, "off", "exit"); + add(Permissions.maintenance, OffNoSave, "off-nosave", "exit-nosave"); + add(Permissions.maintenance, CheckUpdates, "checkupdates"); + add(Permissions.causeevents, DropMeteor, "dropmeteor"); + add(Permissions.causeevents, Star, "star"); + add(Permissions.causeevents, Fullmoon, "fullmoon"); + add(Permissions.causeevents, Bloodmoon, "bloodmoon"); + add(Permissions.causeevents, Invade, "invade"); + add(Permissions.spawnboss, Eater, "eater"); + add(Permissions.spawnboss, Eye, "eye"); + add(Permissions.spawnboss, King, "king"); + add(Permissions.spawnboss, Skeletron, "skeletron"); + add(Permissions.spawnboss, WoF, "wof", "wallofflesh"); + add(Permissions.spawnboss, Twins, "twins"); + add(Permissions.spawnboss, Destroyer, "destroyer"); + add(Permissions.spawnboss, SkeletronPrime, "skeletronp", "prime"); + add(Permissions.spawnboss, Hardcore, "hardcore"); + add(Permissions.spawnmob, SpawnMob, "spawnmob", "sm"); + add(Permissions.tp, Home, "home"); + add(Permissions.tp, Spawn, "spawn"); + add(Permissions.tp, TP, "tp"); + add(Permissions.tphere, TPHere, "tphere"); + add(Permissions.tphere, SendWarp, "sendwarp", "sw"); + add(Permissions.tpallow, TPAllow, "tpallow"); + add(Permissions.warp, UseWarp, "warp"); + add(Permissions.managewarp, SetWarp, "setwarp"); + add(Permissions.managewarp, DeleteWarp, "delwarp"); + add(Permissions.managewarp, HideWarp, "hidewarp"); + add(Permissions.managegroup, AddGroup, "addgroup"); + add(Permissions.managegroup, DeleteGroup, "delgroup"); + add(Permissions.managegroup, ModifyGroup, "modgroup"); + add(Permissions.manageitem, AddItem, "additem"); + add(Permissions.manageitem, DeleteItem, "delitem"); + add(Permissions.cfg, SetSpawn, "setspawn"); + add(Permissions.cfg, Reload, "reload"); + add(Permissions.cfg, ServerPassword, "serverpassword"); + add(Permissions.cfg, Save, "save"); + add(Permissions.cfg, Settle, "settle"); + add(Permissions.cfg, MaxSpawns, "maxspawns"); + add(Permissions.cfg, SpawnRate, "spawnrate"); + add(Permissions.time, Time, "time"); + add(Permissions.pvpfun, Slap, "slap"); + add(Permissions.editspawn, ToggleAntiBuild, "antibuild"); + add(Permissions.editspawn, ProtectSpawn, "protectspawn"); + add(Permissions.manageregion, Region, "region"); + add(Permissions.manageregion, DebugRegions, "debugreg"); + add(null, Help, "help"); + add(null, Playing, "playing", "online", "who", "version"); + add(null, AuthToken, "auth"); + add(Permissions.cantalkinthird, ThirdPerson, "me"); + add(Permissions.canpartychat, PartyChat, "p"); + add(null, Motd, "motd"); + add(null, Rules, "rules"); + add(Permissions.mute, Mute, "mute", "unmute"); + add(Permissions.logs, DisplayLogs, "displaylogs"); + ChatCommands.Add(new Command(Permissions.canchangepassword, PasswordUser, "password") {DoLog = false}); + ChatCommands.Add(new Command(Permissions.canregister, RegisterUser, "register") {DoLog = false}); + ChatCommands.Add(new Command(Permissions.rootonly, ManageUsers, "user") {DoLog = false}); + add(Permissions.rootonly, GrabUserUserInfo, "userinfo", "ui"); + add(Permissions.rootonly, AuthVerify, "auth-verify"); + ChatCommands.Add(new Command(Permissions.canlogin, AttemptLogin, "login") {DoLog = false}); + add(Permissions.cfg, Broadcast, "broadcast", "bc"); + add(Permissions.whisper, Whisper, "whisper", "w", "tell"); + add(Permissions.whisper, Reply, "reply", "r"); + add(Permissions.annoy, Annoy, "annoy"); + add(Permissions.cfg, ConvertWaR, "convert"); + add(Permissions.kill, Kill, "kill"); + add(Permissions.butcher, Butcher, "butcher"); + add(Permissions.item, Item, "item", "i"); + add(Permissions.item, Give, "give"); + add(Permissions.clearitems, ClearItems, "clearitems"); + add(Permissions.heal, Heal, "heal"); + add(Permissions.buff, Buff, "buff"); + add(Permissions.buffplayer, GBuff, "gbuff", "buffplayer"); + add(Permissions.grow, Grow, "grow"); + add(Permissions.hardmode, StartHardMode, "hardmode"); + add(Permissions.hardmode, DisableHardMode, "stophardmode", "disablehardmode"); + add(Permissions.cfg, ServerInfo, "stats"); + add(Permissions.converthardmode, ConvertCorruption, "convertcorruption"); + add(Permissions.converthardmode, ConvertHallow, "converthallow"); + } - 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()); + public static bool HandleCommand(TSPlayer player, string text) + { + string cmdText = text.Remove(0, 1); - return ret; - } + var args = ParseParameters(cmdText); + if (args.Count < 1) + return false; - private static char GetEscape(char c) - { - switch (c) - { - case '\\': - return '\\'; - case '"': - return '"'; - case 't': - return '\t'; - default: - return c; - } - } + string cmdName = args[0]; + args.RemoveAt(0); - private static bool IsWhiteSpace(char c) - { - return c == ' ' || c == '\t' || c == '\n'; - } + Command cmd = ChatCommands.FirstOrDefault(c => c.HasAlias(cmdName)); - #region Account commands + if (cmd == null) + { + player.SendMessage("Invalid Command Entered. Type /help for a list of valid Commands.", Color.Red); + return true; + } - public static void AttemptLogin(CommandArgs args) - { + if (!cmd.CanRun(player)) + { + TShock.Utils.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) + TShock.Utils.SendLogs(string.Format("{0} executed: /{1}", player.Name, cmdText), Color.Red); + cmd.Run(cmdText, player, args); + } + return true; + } - 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."); - TShock.Utils.Kick(args.Player, "Too many invalid login attempts."); - } + /// + /// 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 (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 = TShock.Utils.HashPassword(args.Parameters[1]); - var user = TShock.Users.GetUserByName(args.Parameters[0]); - if (user == null) - { - args.Player.SendMessage("User by that name does not exist"); - } - else if (user.Password.ToUpper() == encrPass.ToUpper()) - { - args.Player.PlayerData = TShock.InventoryDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Parameters[0])); + 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()); - if (TShock.Config.ServerSideInventory) - { - if (args.Player.Group.HasPermission(Permissions.bypassinventorychecks)) - { - args.Player.IgnoreActionsForClearingTrashCan = false; - } - else if (!TShock.CheckInventory(args.Player)) - { - args.Player.SendMessage("Login Failed, Please fix the above errors then /login again.", Color.Cyan); - args.Player.IgnoreActionsForClearingTrashCan = true; - return; - } - } + return ret; + } - if (args.Player.Group.HasPermission(Permissions.ignorestackhackdetection)) - args.Player.IgnoreActionsForCheating = "none"; + private static char GetEscape(char c) + { + switch (c) + { + case '\\': + return '\\'; + case '"': + return '"'; + case 't': + return '\t'; + default: + return c; + } + } - if (args.Player.Group.HasPermission(Permissions.usebanneditem)) - args.Player.IgnoreActionsForDisabledArmor = "none"; - - args.Player.Group = TShock.Utils.GetGroup(user.Group); - args.Player.UserAccountName = args.Parameters[0]; - args.Player.UserID = TShock.Users.GetUserID(args.Player.UserAccountName); - args.Player.IsLoggedIn = true; - args.Player.IgnoreActionsForInventory = "none"; + private static bool IsWhiteSpace(char c) + { + return c == ' ' || c == '\t' || c == '\n'; + } - args.Player.PlayerData.CopyInventory(args.Player); - TShock.InventoryDB.InsertPlayerData(args.Player); + #region Account commands - args.Player.SendMessage("Authenticated as " + args.Parameters[0] + " successfully.", Color.LimeGreen); - Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + args.Parameters[0]); - } - else - { - args.Player.SendMessage("Incorrect password", Color.LimeGreen); - Log.Warn(args.Player.IP + " failed to authenticate as user: " + args.Parameters[0]); - args.Player.LoginAttempts++; - } - } - catch (Exception ex) - { - args.Player.SendMessage("There was an error processing your request.", Color.Red); - Log.Error(ex.ToString()); - } + 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."); + TShock.Utils.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 = TShock.Utils.HashPassword(args.Parameters[1]); + var user = TShock.Users.GetUserByName(args.Parameters[0]); + if (user == null) + { + args.Player.SendMessage("User by that name does not exist"); + } + else if (user.Password.ToUpper() == encrPass.ToUpper()) + { + args.Player.PlayerData = TShock.InventoryDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Parameters[0])); - 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 = TShock.Utils.HashPassword(args.Parameters[0]); - if (user.Password.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); - } - } + if (TShock.Config.ServerSideInventory) + { + if (args.Player.Group.HasPermission(Permissions.bypassinventorychecks)) + { + args.Player.IgnoreActionsForClearingTrashCan = false; + } + else if (!TShock.CheckInventory(args.Player)) + { + args.Player.SendMessage("Login Failed, Please fix the above errors then /login again.", Color.Cyan); + args.Player.IgnoreActionsForClearingTrashCan = true; + return; + } + } - private static void RegisterUser(CommandArgs args) - { - try - { - var user = new User(); + if (args.Player.Group.HasPermission(Permissions.ignorestackhackdetection)) + args.Player.IgnoreActionsForCheating = "none"; - if (args.Parameters.Count == 1) - { - user.Name = args.Player.Name; - user.Password = args.Parameters[0]; - } - else if (args.Parameters.Count == 2 && TShock.Config.AllowRegisterAnyUsername) - { - user.Name = args.Parameters[0]; - user.Password = args.Parameters[1]; - } - else - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /register ", Color.Red); - return; - } + if (args.Player.Group.HasPermission(Permissions.usebanneditem)) + args.Player.IgnoreActionsForDisabledArmor = "none"; - user.Group = TShock.Config.DefaultRegistrationGroupName; // FIXME -- we should get this from the DB. + args.Player.Group = TShock.Utils.GetGroup(user.Group); + args.Player.UserAccountName = args.Parameters[0]; + args.Player.UserID = TShock.Users.GetUserID(args.Player.UserAccountName); + args.Player.IsLoggedIn = true; + args.Player.IgnoreActionsForInventory = "none"; - 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); - args.Player.SendMessage("Your password is " + user.Password); - 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); - } - } - catch (UserManagerException ex) - { - args.Player.SendMessage("Sorry, an error occured: " + ex.Message, Color.Green); - Log.ConsoleError("RegisterUser returned an error: " + ex); - } - } + args.Player.PlayerData.CopyInventory(args.Player); + TShock.InventoryDB.InsertPlayerData(args.Player); - //Todo: Add separate help text for '/user add' and '/user del'. Also add '/user addip' and '/user delip' + args.Player.SendMessage("Authenticated as " + args.Parameters[0] + " successfully.", Color.LimeGreen); + Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + args.Parameters[0]); + } + else + { + args.Player.SendMessage("Incorrect password", Color.LimeGreen); + Log.Warn(args.Player.IP + " failed to authenticate as user: " + args.Parameters[0]); + args.Player.LoginAttempts++; + } + } + catch (Exception ex) + { + args.Player.SendMessage("There was an error processing your request.", Color.Red); + Log.Error(ex.ToString()); + } + } - private static void ManageUsers(CommandArgs args) - { - // This guy needs to go away for the help later on to take effect. + 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 = TShock.Utils.HashPassword(args.Parameters[0]); + if (user.Password.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); + } + } - //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; - //} + private static void RegisterUser(CommandArgs args) + { + try + { + var user = new User(); - // This guy needs to be here so that people don't get exceptions when they type /user - if (args.Parameters.Count < 1) - { - args.Player.SendMessage("Invalid user syntax. Try /user help.", Color.Red); - return; - } + if (args.Parameters.Count == 1) + { + user.Name = args.Player.Name; + user.Password = args.Parameters[0]; + } + else if (args.Parameters.Count == 2 && TShock.Config.AllowRegisterAnyUsername) + { + user.Name = args.Parameters[0]; + user.Password = args.Parameters[1]; + } + else + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /register ", Color.Red); + return; + } - string subcmd = args.Parameters[0]; + user.Group = TShock.Config.DefaultRegistrationGroupName; // FIXME -- we should get this from the DB. - // Add requires a username:password pair/ip address and a group specified. - if (subcmd == "add") - { - var namepass = args.Parameters[1].Split(':'); - var user = new User(); + 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); + args.Player.SendMessage("Your password is " + user.Password); + 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); + } + } + catch (UserManagerException ex) + { + args.Player.SendMessage("Sorry, an error occured: " + ex.Message, Color.Green); + Log.ConsoleError("RegisterUser returned an error: " + ex); + } + } - try - { - if (args.Parameters.Count > 2) - { - if (namepass.Length == 2) - { - user.Name = namepass[0]; - 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()); - } - } - // User deletion requires a username - 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]; + //Todo: Add separate help text for '/user add' and '/user del'. Also add '/user addip' and '/user delip' - 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()); - } - } - // Password changing requires a username, and a new password to set - else if (subcmd == "password") - { - var user = new User(); - user.Name = args.Parameters[1]; + private static void ManageUsers(CommandArgs args) + { + // This guy needs to go away for the help later on to take effect. - try - { + //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; + //} - if (args.Parameters.Count == 3) - { - args.Player.SendMessage("Changed the password of " + user.Name + "!", Color.Green); - TShock.Users.SetUserPassword(user, args.Parameters[2]); - Log.ConsoleInfo(args.Player.Name + " changed the password of Account " + user.Name); - } - else - { - args.Player.SendMessage("Invalid user password syntax. Try /user help.", Color.Red); - } - } - catch (UserManagerException ex) - { - args.Player.SendMessage(ex.Message, Color.Green); - Log.ConsoleError(ex.ToString()); - } - } - // Group changing requires a username or IP address, and a new group to set - else if (subcmd == "group") - { - var user = new User(); - if (args.Parameters[1].Contains(".")) - user.Address = args.Parameters[1]; - else - user.Name = args.Parameters[1]; + // This guy needs to be here so that people don't get exceptions when they type /user + if (args.Parameters.Count < 1) + { + args.Player.SendMessage("Invalid user syntax. Try /user help.", Color.Red); + return; + } - try - { + string subcmd = args.Parameters[0]; - if (args.Parameters.Count == 3) - { - if (!string.IsNullOrEmpty(user.Address)) - { - args.Player.SendMessage("IP Address " + user.Address + " has been changed to group " + args.Parameters[2] + "!", Color.Green); - TShock.Users.SetUserGroup(user, args.Parameters[2]); - Log.ConsoleInfo(args.Player.Name + " changed IP Address " + user.Address + " to group " + args.Parameters[2]); - } - else - { - args.Player.SendMessage("Account " + user.Name + " has been changed to group " + args.Parameters[2] + "!", Color.Green); - TShock.Users.SetUserGroup(user, args.Parameters[2]); - Log.ConsoleInfo(args.Player.Name + " changed Account " + user.Name + " to group " + args.Parameters[2]); - } - } - else - { - args.Player.SendMessage("Invalid user group syntax. Try /user help.", Color.Red); - } - } - catch (UserManagerException ex) - { - args.Player.SendMessage(ex.Message, Color.Green); - Log.ConsoleError(ex.ToString()); - } - } - else if (subcmd == "help") - { - args.Player.SendMessage("Help for user subcommands:"); - args.Player.SendMessage("/user add username:password group -- Adds a specified user"); - args.Player.SendMessage("/user del username -- Removes a specified user"); - args.Player.SendMessage("/user password username newpassword -- Changes a user's password"); - args.Player.SendMessage("/user group username newgroup -- Changes a user's group"); - } - else - { - args.Player.SendMessage("Invalid user syntax. Try /user help.", Color.Red); - } - } - #endregion + // Add requires a username:password pair/ip address and a group specified. + 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]; + 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()); + } + } + // User deletion requires a username + 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()); + } + } + // Password changing requires a username, and a new password to set + else if (subcmd == "password") + { + var user = new User(); + user.Name = args.Parameters[1]; + + try + { + if (args.Parameters.Count == 3) + { + args.Player.SendMessage("Changed the password of " + user.Name + "!", Color.Green); + TShock.Users.SetUserPassword(user, args.Parameters[2]); + Log.ConsoleInfo(args.Player.Name + " changed the password of Account " + user.Name); + } + else + { + args.Player.SendMessage("Invalid user password syntax. Try /user help.", Color.Red); + } + } + catch (UserManagerException ex) + { + args.Player.SendMessage(ex.Message, Color.Green); + Log.ConsoleError(ex.ToString()); + } + } + // Group changing requires a username or IP address, and a new group to set + else if (subcmd == "group") + { + var user = new User(); + if (args.Parameters[1].Contains(".")) + user.Address = args.Parameters[1]; + else + user.Name = args.Parameters[1]; + + try + { + if (args.Parameters.Count == 3) + { + if (!string.IsNullOrEmpty(user.Address)) + { + args.Player.SendMessage("IP Address " + user.Address + " has been changed to group " + args.Parameters[2] + "!", + Color.Green); + TShock.Users.SetUserGroup(user, args.Parameters[2]); + Log.ConsoleInfo(args.Player.Name + " changed IP Address " + user.Address + " to group " + args.Parameters[2]); + } + else + { + args.Player.SendMessage("Account " + user.Name + " has been changed to group " + args.Parameters[2] + "!", + Color.Green); + TShock.Users.SetUserGroup(user, args.Parameters[2]); + Log.ConsoleInfo(args.Player.Name + " changed Account " + user.Name + " to group " + args.Parameters[2]); + } + } + else + { + args.Player.SendMessage("Invalid user group syntax. Try /user help.", Color.Red); + } + } + catch (UserManagerException ex) + { + args.Player.SendMessage(ex.Message, Color.Green); + Log.ConsoleError(ex.ToString()); + } + } + else if (subcmd == "help") + { + args.Player.SendMessage("Help for user subcommands:"); + args.Player.SendMessage("/user add username:password group -- Adds a specified user"); + args.Player.SendMessage("/user del username -- Removes a specified user"); + args.Player.SendMessage("/user password username newpassword -- Changes a user's password"); + args.Player.SendMessage("/user group username newgroup -- Changes a user's group"); + } + else + { + args.Player.SendMessage("Invalid user syntax. Try /user help.", Color.Red); + } + } + + #endregion #region Stupid commands + public static void ServerInfo(CommandArgs args) { args.Player.SendMessage("Memory usage: " + Process.GetCurrentProcess().WorkingSet64); @@ -648,1498 +661,1509 @@ namespace TShockAPI args.Player.SendMessage("Proc count: " + Environment.ProcessorCount); args.Player.SendMessage("Machine name: " + Environment.MachineName); } + #endregion #region Player Management Commands private static void GrabUserUserInfo(CommandArgs args) - { - if (args.Parameters.Count < 1) - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /userinfo ", Color.Red); - return; - } - - var players = TShock.Utils.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("IP Address: " + players[0].IP + " Logged In As: " + players[0].UserAccountName, 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 = TShock.Utils.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 (!TShock.Utils.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 = TShock.Utils.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 (!TShock.Utils.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 unban {0} ({1})!", ban.Name, ban.IP), Color.Red); - } - else if (!TShock.Config.EnableBanOnUsernames) - { - ban = TShock.Bans.GetBanByIp(plStr); - - if (ban == null) - args.Player.SendMessage(string.Format("Failed to unban {0}, not found.", args.Parameters[0]), Color.Red); - else 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 unban {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 unban {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) - { - using (var tw = new StreamWriter(FileTools.WhitelistPath, true)) - { - tw.WriteLine(args.Parameters[0]); - } - 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]; - } - - TShock.Utils.Broadcast("(Server Broadcast)" + message, Color.Red); - return; - } - - private static void Off(CommandArgs args) - { - TShock.Utils.ForceKickAll("Server shutting down!"); - WorldGen.saveWorld(); - Netplay.disconnect = true; - } - - private static void OffNoSave(CommandArgs args) - { - TShock.Utils.ForceKickAll("Server shutting down!"); - Netplay.disconnect = true; - } - - private static void CheckUpdates(CommandArgs args) - { - ThreadPool.QueueUserWorkItem(UpdateManager.CheckUpdate); - } - - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] - private static void UpdateNow(CommandArgs args) - { - Process TServer = Process.GetCurrentProcess(); - - using (var sw = new StreamWriter("pid")) - { - sw.Write(TServer.Id); - } - - using (var sw = new StreamWriter("pn")) - { - sw.Write(TServer.ProcessName + " " + Environment.CommandLine); - } - - using (var client = new WebClient()) - { - client.Headers.Add("user-agent", "TShock"); - byte[] updatefile = client.DownloadData("http://tsupdate.shankshock.com/UpdateTShock.exe"); - - using (var bw = new BinaryWriter(new FileStream("UpdateTShock.exe", FileMode.Create))) - { - bw.Write(updatefile); - } - } - - Process.Start(new ProcessStartInfo("UpdateTShock.exe")); - - TShock.Utils.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 Fullmoon(CommandArgs args) - { - TSPlayer.Server.SetFullMoon(true); - TShock.Utils.Broadcast(string.Format("{0} turned on full moon.", args.Player.Name)); - } - - private static void Bloodmoon(CommandArgs args) - { - TSPlayer.Server.SetBloodMoon(true); - TShock.Utils.Broadcast(string.Format("{0} turned on blood moon.", args.Player.Name)); - } - - private static void Invade(CommandArgs args) - { - if (Main.invasionSize <= 0) - { - TShock.Utils.Broadcast(string.Format("{0} has started an invasion.", args.Player.Name)); - TShock.StartInvasion(); - } - else - { - TShock.Utils.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; - } - amount = Math.Min(amount, Main.maxNPCs); - NPC eater = TShock.Utils.GetNPCById(13); - TSPlayer.Server.SpawnNPC(eater.type, eater.name, amount, args.Player.TileX, args.Player.TileY); - TShock.Utils.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; - } - amount = Math.Min(amount, Main.maxNPCs); - NPC eye = TShock.Utils.GetNPCById(4); - TSPlayer.Server.SetTime(false, 0.0); - TSPlayer.Server.SpawnNPC(eye.type, eye.name, amount, args.Player.TileX, args.Player.TileY); - TShock.Utils.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; - } - amount = Math.Min(amount, Main.maxNPCs); - NPC king = TShock.Utils.GetNPCById(50); - TSPlayer.Server.SpawnNPC(king.type, king.name, amount, args.Player.TileX, args.Player.TileY); - TShock.Utils.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; - } - amount = Math.Min(amount, Main.maxNPCs); - NPC skeletron = TShock.Utils.GetNPCById(35); - TSPlayer.Server.SetTime(false, 0.0); - TSPlayer.Server.SpawnNPC(skeletron.type, skeletron.name, amount, args.Player.TileX, args.Player.TileY); - TShock.Utils.Broadcast(string.Format("{0} has spawned skeletron {1} times!", args.Player.Name, amount)); - } - - private static void WoF(CommandArgs args) - { - if (Main.wof >= 0 || (args.Player.Y / 16f < (Main.maxTilesY - 205))) - { - args.Player.SendMessage("Can't spawn Wall of Flesh!", Color.Red); - return; - } - NPC.SpawnWOF(new Vector2(args.Player.X, args.Player.Y)); - TShock.Utils.Broadcast(string.Format("{0} has spawned Wall of Flesh!", args.Player.Name)); - } - - private static void Twins(CommandArgs args) - { - if (args.Parameters.Count > 1) - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /twins [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: /twins [amount]", Color.Red); - return; - } - amount = Math.Min(amount, Main.maxNPCs); - NPC retinazer = TShock.Utils.GetNPCById(125); - NPC spaz = TShock.Utils.GetNPCById(126); - TSPlayer.Server.SetTime(false, 0.0); - TSPlayer.Server.SpawnNPC(retinazer.type, retinazer.name, amount, args.Player.TileX, args.Player.TileY); - TSPlayer.Server.SpawnNPC(spaz.type, spaz.name, amount, args.Player.TileX, args.Player.TileY); - TShock.Utils.Broadcast(string.Format("{0} has spawned the twins {1} times!", args.Player.Name, amount)); - } - - private static void Destroyer(CommandArgs args) - { - if (args.Parameters.Count > 1) - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /destroyer [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: /destroyer [amount]", Color.Red); - return; - } - amount = Math.Min(amount, Main.maxNPCs); - NPC destroyer = TShock.Utils.GetNPCById(134); - TSPlayer.Server.SetTime(false, 0.0); - TSPlayer.Server.SpawnNPC(destroyer.type, destroyer.name, amount, args.Player.TileX, args.Player.TileY); - TShock.Utils.Broadcast(string.Format("{0} has spawned the destroyer {1} times!", args.Player.Name, amount)); - } - - private static void SkeletronPrime(CommandArgs args) - { - if (args.Parameters.Count > 1) - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /prime [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: /prime [amount]", Color.Red); - return; - } - amount = Math.Min(amount, Main.maxNPCs); - NPC prime = TShock.Utils.GetNPCById(127); - TSPlayer.Server.SetTime(false, 0.0); - TSPlayer.Server.SpawnNPC(prime.type, prime.name, amount, args.Player.TileX, args.Player.TileY); - TShock.Utils.Broadcast(string.Format("{0} has spawned skeletron prime {1} times!", args.Player.Name, amount)); - } - - private static void Hardcore(CommandArgs args) // TODO: Add all 8 bosses - { - 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; - } - amount = Math.Min(amount, Main.maxNPCs / 4); - NPC retinazer = TShock.Utils.GetNPCById(125); - NPC spaz = TShock.Utils.GetNPCById(126); - NPC destroyer = TShock.Utils.GetNPCById(134); - NPC prime = TShock.Utils.GetNPCById(127); - NPC eater = TShock.Utils.GetNPCById(13); - NPC eye = TShock.Utils.GetNPCById(4); - NPC king = TShock.Utils.GetNPCById(50); - NPC skeletron = TShock.Utils.GetNPCById(35); - TSPlayer.Server.SetTime(false, 0.0); - TSPlayer.Server.SpawnNPC(retinazer.type, retinazer.name, amount, args.Player.TileX, args.Player.TileY); - TSPlayer.Server.SpawnNPC(spaz.type, spaz.name, amount, args.Player.TileX, args.Player.TileY); - TSPlayer.Server.SpawnNPC(destroyer.type, destroyer.name, amount, args.Player.TileX, args.Player.TileY); - TSPlayer.Server.SpawnNPC(prime.type, prime.name, amount, args.Player.TileX, args.Player.TileY); - TSPlayer.Server.SpawnNPC(eater.type, eater.name, amount, args.Player.TileX, args.Player.TileY); - TSPlayer.Server.SpawnNPC(eye.type, eye.name, amount, args.Player.TileX, args.Player.TileY); - TSPlayer.Server.SpawnNPC(king.type, king.name, amount, args.Player.TileX, args.Player.TileY); - TSPlayer.Server.SpawnNPC(skeletron.type, skeletron.name, amount, args.Player.TileX, args.Player.TileY); - TShock.Utils.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; - } - - amount = Math.Min(amount, Main.maxNPCs); - - var npcs = TShock.Utils.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 && npc.type != 113) //Do not allow WoF to spawn, in certain conditions may cause loops in client - { - TSPlayer.Server.SpawnNPC(npc.type, npc.name, amount, args.Player.TileX, args.Player.TileY, 50, 20); - TShock.Utils.Broadcast(string.Format("{0} was spawned {1} time(s).", npc.name, amount)); - } - else if (npc.type == 113) - args.Player.SendMessage("Sorry, you can't spawn Wall of Flesh! Try /wof instead."); // Maybe perhaps do something with WorldGen.SpawnWoF? - else - args.Player.SendMessage("Invalid mob type!", Color.Red); - } - } - - private static void StartHardMode(CommandArgs args) - { - WorldGen.StartHardmode(); - } - - private static void DisableHardMode(CommandArgs args) - { - Main.hardMode = false; - } - - private static void ConvertCorruption(CommandArgs args) - { - TShock.Utils.Broadcast("Server is might lag for a moment.", Color.Red); - for (int x = 0; x < Main.maxTilesX; x++) - { - for (int y = 0; y < Main.maxTilesY; y++) - { - switch (Main.tile[x, y].type) - { - case 22: - case 25: - Main.tile[x, y].type = 117; - break; - case 23: - Main.tile[x, y].type = 109; - break; - case 32: - Main.tile[x, y].type = 0; - Main.tile[x, y].active = false; - break; - case 24: - Main.tile[x, y].type = 110; - break; - case 112: - Main.tile[x, y].type = 116; - break; - default: - continue; - } - } - } - WorldGen.CountTiles(0); - TSPlayer.All.SendData(PacketTypes.UpdateGoodEvil); - Netplay.ResetSections(); - TShock.Utils.Broadcast("Corruption conversion done."); - } - - private static void ConvertHallow(CommandArgs args) - { - TShock.Utils.Broadcast("Server is might lag for a moment.", Color.Red); - for (int x = 0; x < Main.maxTilesX; x++) - { - for (int y = 0; y < Main.maxTilesY; y++) - { - switch (Main.tile[x, y].type) - { - case 117: - Main.tile[x, y].type = 25; - break; - case 109: - Main.tile[x, y].type = 23; - break; - case 116: - Main.tile[x, y].type = 112; - break; - default: - continue; - } - } - } - WorldGen.CountTiles(0); - TSPlayer.All.SendData(PacketTypes.UpdateGoodEvil); - Netplay.ResetSections(); - TShock.Utils.Broadcast("Hallow conversion done."); - } - - #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 = TShock.Utils.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 if (!players[0].TPAllow && !args.Player.Group.HasPermission(Permissions.tpall)) - { - var plr = players[0]; - args.Player.SendMessage(plr.Name + " Has Selected For Users Not To Teleport To Them"); - plr.SendMessage(args.Player.Name + " Attempted To Teleport To You"); - } - else - { - var plr = players[0]; - if (args.Player.Teleport(plr.TileX, plr.TileY + 3)) - { - args.Player.SendMessage(string.Format("Teleported to {0}", plr.Name)); - if(!args.Player.Group.HasPermission(Permissions.tphide)) - plr.SendMessage(args.Player.Name + " Teleported To You"); - } - } - } - - 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 = TShock.Utils.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 TPAllow(CommandArgs args) - { - if (!args.Player.TPAllow) - args.Player.SendMessage("Other Players Can Now Teleport To You"); - if (args.Player.TPAllow) - args.Player.SendMessage("Other Players Can No Longer Teleport To You"); - args.Player.TPAllow = !args.Player.TPAllow; - } - - private static void SendWarp(CommandArgs args) - { - if (args.Parameters.Count < 2) - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /sendwarp [player] [warpname]", Color.Red); - return; - } - - var foundplr = TShock.Utils.FindPlayer(args.Parameters[0]); - if (foundplr.Count == 0) - { - args.Player.SendMessage("Invalid player!", Color.Red); - return; - } - else if (foundplr.Count > 1) - { - args.Player.SendMessage(string.Format("More than one ({0}) player matched!", args.Parameters.Count), Color.Red); - return; - } - string warpName = String.Join(" ", args.Parameters[1]); - var warp = TShock.Warps.FindWarp(warpName); - var plr = foundplr[0]; - if (warp.WarpPos != Vector2.Zero) - { - if (plr.Teleport((int)warp.WarpPos.X, (int)warp.WarpPos.Y + 3)) - { - plr.SendMessage(string.Format("{0} Warped you to {1}", args.Player.Name, warpName), Color.Yellow); - args.Player.SendMessage(string.Format("You warped {0} to {1}.", plr.Name, warpName), Color.Yellow); - } - } - else - { - args.Player.SendMessage("Specified warp not found", Color.Red); - } - } - - 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.worldID.ToString())) - { - 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 HideWarp(CommandArgs args) - { - if (args.Parameters.Count > 1) - { - string warpName = String.Join(" ", args.Parameters); - bool state = false; - if (Boolean.TryParse(args.Parameters[1], out state)) - { - if (TShock.Warps.HideWarp(args.Parameters[0], state)) - { - if (state) - args.Player.SendMessage("Made warp " + warpName + " private", Color.Yellow); - else - args.Player.SendMessage("Made warp " + warpName + " public", Color.Yellow); - } - else - args.Player.SendMessage("Could not find specified warp", Color.Red); - } - else - args.Player.SendMessage("Invalid syntax! Proper syntax: /hidewarp [name] ", Color.Red); - } - else - args.Player.SendMessage("Invalid syntax! Proper syntax: /hidewarp [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.ListAllPublicWarps(Main.worldID.ToString()); - - //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 = (page * pagelimit); (i < ((page * pagelimit) + pagelimit)) && i < 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 + 2)), 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 Group Management - - private static void AddGroup(CommandArgs args) - { - if (args.Parameters.Count > 0) - { - String groupname = args.Parameters[0]; - args.Parameters.RemoveAt(0); - String permissions = String.Join(",", args.Parameters); - - String response = TShock.Groups.AddGroup(groupname, permissions); - if (response.Length > 0) - args.Player.SendMessage(response, Color.Green); - } - else - { - args.Player.SendMessage("Incorrect format: /addGroup [optional permissions]", Color.Red); - } - } - - private static void DeleteGroup(CommandArgs args) - { - if (args.Parameters.Count > 0) - { - String groupname = args.Parameters[0]; - - String response = TShock.Groups.DeleteGroup(groupname); - if (response.Length > 0) - args.Player.SendMessage(response, Color.Green); - } - else - { - args.Player.SendMessage("Incorrect format: /delGroup ", Color.Red); - } - } - - private static void ModifyGroup(CommandArgs args) - { - if (args.Parameters.Count > 2) - { - String com = args.Parameters[0]; - args.Parameters.RemoveAt(0); - - String groupname = args.Parameters[0]; - args.Parameters.RemoveAt(0); - - if (com.Equals("add")) - { - String response = TShock.Groups.AddPermissions(groupname, args.Parameters); - if (response.Length > 0) - args.Player.SendMessage(response, Color.Green); - return; - } - else if (com.Equals("del") || com.Equals("delete")) - { - String response = TShock.Groups.DeletePermissions(groupname, args.Parameters); - if (response.Length > 0) - args.Player.SendMessage(response, Color.Green); - return; - } - } - args.Player.SendMessage("Incorrect format: /modGroup add|del ", Color.Red); - } - - #endregion Group Management - - #region Item Management - - private static void AddItem(CommandArgs args) - { - if (args.Parameters.Count > 0) - { - var items = TShock.Utils.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) - { - TShock.Itembans.AddNewBan(item.name); - args.Player.SendMessage(item.name + " has been banned.", Color.Green); - } - else - { - args.Player.SendMessage("Invalid item type!", Color.Red); - } - } - } - else - { - args.Player.SendMessage("Invalid use: /addItem \"item name\" or /addItem ##", Color.Red); - } - } - - private static void DeleteItem(CommandArgs args) - { - if (args.Parameters.Count > 0) - { - var items = TShock.Utils.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) - { - TShock.Itembans.RemoveBan(item.name); - args.Player.SendMessage(item.name + " has been unbanned.", Color.Green); - } - else - { - args.Player.SendMessage("Invalid item type!", Color.Red); - } - } - } - else - { - args.Player.SendMessage("Invalid use: /delItem \"item name\" or /delItem ##", Color.Red); - } - } - - #endregion Item Management - - #region Server Config Commands - - private static void SetSpawn(CommandArgs args) - { - Main.spawnTileX = args.Player.TileX + 1; - Main.spawnTileY = args.Player.TileY + 3; - - TShock.Utils.Broadcast("Server map saving, potential lag spike"); - Thread SaveWorld = new Thread(TShock.Utils.SaveWorld); - SaveWorld.Start(); - } - - private static void Reload(CommandArgs args) - { - FileTools.SetupConfig(); - TShock.Groups.LoadPermisions(); - TShock.Regions.ReloadAllRegions(); - args.Player.SendMessage("Configuration, Permissions, and Regions reload complete. Some changes may require server restart."); - } - - private static void ServerPassword(CommandArgs args) - { - if (args.Parameters.Count != 1) - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /password \"\"", Color.Red); - return; - } - string passwd = args.Parameters[0]; - TShock.Config.ServerPassword = passwd; - args.Player.SendMessage(string.Format("Server password changed to: {0}", passwd)); - } - - private static void Save(CommandArgs args) - { - TShock.Utils.Broadcast("Server map saving, potential lag spike"); - Thread SaveWorld = new Thread(TShock.Utils.SaveWorld); - SaveWorld.Start(); - } - - private static void Settle(CommandArgs args) - { - - if (Liquid.panicMode) - { - args.Player.SendMessage("Liquid is already settling!", Color.Red); - return; - } - Liquid.StartPanic(); - TShock.Utils.Broadcast("Settling all liquids..."); - - } - - 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; - TShock.Utils.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; - TShock.Utils.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); - TShock.Utils.Broadcast(string.Format("{0} set time to day.", args.Player.Name)); - break; - case "night": - TSPlayer.Server.SetTime(false, 0.0); - TShock.Utils.Broadcast(string.Format("{0} set time to night.", args.Player.Name)); - break; - case "dusk": - TSPlayer.Server.SetTime(false, 0.0); - TShock.Utils.Broadcast(string.Format("{0} set time to dusk.", args.Player.Name)); - break; - case "noon": - TSPlayer.Server.SetTime(true, 27000.0); - TShock.Utils.Broadcast(string.Format("{0} set time to noon.", args.Player.Name)); - break; - case "midnight": - TSPlayer.Server.SetTime(false, 16200.0); - TShock.Utils.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 = TShock.Utils.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(Permissions.kill)) - { - damage = TShock.Utils.Clamp(damage, 15, 0); - } - plr.DamagePlayer(damage); - TShock.Utils.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); - TShock.Utils.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); - TShock.Utils.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.Name + ": P: " + r.DisableBuild + " X: " + r.Area.X + " Y: " + r.Area.Y + " W: " + r.Area.Width + " H: " + r.Area.Height); - foreach (int s in r.AllowedIDs) - { - args.Player.SendMessage(r.Name + ": " + s); - } - } - } - - private static void Region(CommandArgs args) - { - string cmd = "help"; - if (args.Parameters.Count > 0) - { - cmd = args.Parameters[0].ToLower(); - } - switch (cmd) - { - case "name": - { - { - args.Player.SendMessage("Hit a block to get the name of the region", Color.Yellow); - args.Player.AwaitingName = true; - } - break; - } - case "set": - { - int choice = 0; - if (args.Parameters.Count == 2 && - int.TryParse(args.Parameters[1], out choice) && - choice >= 1 && choice <= 2) - { - args.Player.SendMessage("Hit a block to Set Point " + choice, Color.Yellow); - args.Player.AwaitingTempPoint = choice; - } - 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.TempPoints.Any(p => p == Point.Zero)) - { - string regionName = String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1)); - var x = Math.Min(args.Player.TempPoints[0].X, args.Player.TempPoints[1].X); - var y = Math.Min(args.Player.TempPoints[0].Y, args.Player.TempPoints[1].Y); - var width = Math.Abs(args.Player.TempPoints[0].X - args.Player.TempPoints[1].X); - var height = Math.Abs(args.Player.TempPoints[0].Y - args.Player.TempPoints[1].Y); - - if (TShock.Regions.AddRegion(x, y, width, height, regionName, args.Player.UserAccountName, Main.worldID.ToString())) - { - args.Player.TempPoints[0] = Point.Zero; - args.Player.TempPoints[1] = Point.Zero; - 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.TempPoints[0] = Point.Zero; - args.Player.TempPoints[1] = Point.Zero; - args.Player.SendMessage("Cleared temp area", Color.Yellow); - args.Player.AwaitingTempPoint = 0; - break; - } - case "allow": - { - if (args.Parameters.Count > 2) - { - string playerName = args.Parameters[1]; - string regionName = ""; - - for (int i = 2; i < args.Parameters.Count; i++) - { - if (regionName == "") - { - regionName = args.Parameters[2]; - } - else - { - regionName = regionName + " " + args.Parameters[i]; - } - } - if (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 "remove": - if (args.Parameters.Count > 2) - { - string playerName = args.Parameters[1]; - string regionName = ""; - - for (int i = 2; i < args.Parameters.Count; i++) - { - if (regionName == "") - { - regionName = args.Parameters[2]; - } - else - { - regionName = regionName + " " + args.Parameters[i]; - } - } - if (TShock.Users.GetUserByName(playerName) != null) - { - if (TShock.Regions.RemoveUser(regionName, playerName)) - { - args.Player.SendMessage("Removed user " + playerName + " from " + 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 remove [name] [region]", Color.Red); - break; + { + if (args.Parameters.Count < 1) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /userinfo ", Color.Red); + return; + } + + var players = TShock.Utils.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("IP Address: " + players[0].IP + " Logged In As: " + players[0].UserAccountName, 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 = TShock.Utils.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 (!TShock.Utils.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 = TShock.Utils.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 (!TShock.Utils.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 unban {0} ({1})!", ban.Name, ban.IP), Color.Red); + } + else if (!TShock.Config.EnableBanOnUsernames) + { + ban = TShock.Bans.GetBanByIp(plStr); + + if (ban == null) + args.Player.SendMessage(string.Format("Failed to unban {0}, not found.", args.Parameters[0]), Color.Red); + else 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 unban {0} ({1})!", ban.Name, ban.IP), Color.Red); + } + else + { + args.Player.SendMessage("Invalid player!", Color.Red); + } + } + + private 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 unban {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) + { + using (var tw = new StreamWriter(FileTools.WhitelistPath, true)) + { + tw.WriteLine(args.Parameters[0]); + } + 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]; + } + + TShock.Utils.Broadcast("(Server Broadcast)" + message, Color.Red); + return; + } + + private static void Off(CommandArgs args) + { + TShock.Utils.ForceKickAll("Server shutting down!"); + WorldGen.saveWorld(); + Netplay.disconnect = true; + } + + private static void OffNoSave(CommandArgs args) + { + TShock.Utils.ForceKickAll("Server shutting down!"); + Netplay.disconnect = true; + } + + private static void CheckUpdates(CommandArgs args) + { + ThreadPool.QueueUserWorkItem(UpdateManager.CheckUpdate); + } + + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + private static void UpdateNow(CommandArgs args) + { + Process TServer = Process.GetCurrentProcess(); + + using (var sw = new StreamWriter("pid")) + { + sw.Write(TServer.Id); + } + + using (var sw = new StreamWriter("pn")) + { + sw.Write(TServer.ProcessName + " " + Environment.CommandLine); + } + + using (var client = new WebClient()) + { + client.Headers.Add("user-agent", "TShock"); + byte[] updatefile = client.DownloadData("http://tsupdate.shankshock.com/UpdateTShock.exe"); + + using (var bw = new BinaryWriter(new FileStream("UpdateTShock.exe", FileMode.Create))) + { + bw.Write(updatefile); + } + } + + Process.Start(new ProcessStartInfo("UpdateTShock.exe")); + + TShock.Utils.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 Fullmoon(CommandArgs args) + { + TSPlayer.Server.SetFullMoon(true); + TShock.Utils.Broadcast(string.Format("{0} turned on full moon.", args.Player.Name)); + } + + private static void Bloodmoon(CommandArgs args) + { + TSPlayer.Server.SetBloodMoon(true); + TShock.Utils.Broadcast(string.Format("{0} turned on blood moon.", args.Player.Name)); + } + + private static void Invade(CommandArgs args) + { + if (Main.invasionSize <= 0) + { + TShock.Utils.Broadcast(string.Format("{0} has started an invasion.", args.Player.Name)); + TShock.StartInvasion(); + } + else + { + TShock.Utils.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; + } + amount = Math.Min(amount, Main.maxNPCs); + NPC eater = TShock.Utils.GetNPCById(13); + TSPlayer.Server.SpawnNPC(eater.type, eater.name, amount, args.Player.TileX, args.Player.TileY); + TShock.Utils.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; + } + amount = Math.Min(amount, Main.maxNPCs); + NPC eye = TShock.Utils.GetNPCById(4); + TSPlayer.Server.SetTime(false, 0.0); + TSPlayer.Server.SpawnNPC(eye.type, eye.name, amount, args.Player.TileX, args.Player.TileY); + TShock.Utils.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; + } + amount = Math.Min(amount, Main.maxNPCs); + NPC king = TShock.Utils.GetNPCById(50); + TSPlayer.Server.SpawnNPC(king.type, king.name, amount, args.Player.TileX, args.Player.TileY); + TShock.Utils.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; + } + amount = Math.Min(amount, Main.maxNPCs); + NPC skeletron = TShock.Utils.GetNPCById(35); + TSPlayer.Server.SetTime(false, 0.0); + TSPlayer.Server.SpawnNPC(skeletron.type, skeletron.name, amount, args.Player.TileX, args.Player.TileY); + TShock.Utils.Broadcast(string.Format("{0} has spawned skeletron {1} times!", args.Player.Name, amount)); + } + + private static void WoF(CommandArgs args) + { + if (Main.wof >= 0 || (args.Player.Y/16f < (Main.maxTilesY - 205))) + { + args.Player.SendMessage("Can't spawn Wall of Flesh!", Color.Red); + return; + } + NPC.SpawnWOF(new Vector2(args.Player.X, args.Player.Y)); + TShock.Utils.Broadcast(string.Format("{0} has spawned Wall of Flesh!", args.Player.Name)); + } + + private static void Twins(CommandArgs args) + { + if (args.Parameters.Count > 1) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /twins [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: /twins [amount]", Color.Red); + return; + } + amount = Math.Min(amount, Main.maxNPCs); + NPC retinazer = TShock.Utils.GetNPCById(125); + NPC spaz = TShock.Utils.GetNPCById(126); + TSPlayer.Server.SetTime(false, 0.0); + TSPlayer.Server.SpawnNPC(retinazer.type, retinazer.name, amount, args.Player.TileX, args.Player.TileY); + TSPlayer.Server.SpawnNPC(spaz.type, spaz.name, amount, args.Player.TileX, args.Player.TileY); + TShock.Utils.Broadcast(string.Format("{0} has spawned the twins {1} times!", args.Player.Name, amount)); + } + + private static void Destroyer(CommandArgs args) + { + if (args.Parameters.Count > 1) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /destroyer [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: /destroyer [amount]", Color.Red); + return; + } + amount = Math.Min(amount, Main.maxNPCs); + NPC destroyer = TShock.Utils.GetNPCById(134); + TSPlayer.Server.SetTime(false, 0.0); + TSPlayer.Server.SpawnNPC(destroyer.type, destroyer.name, amount, args.Player.TileX, args.Player.TileY); + TShock.Utils.Broadcast(string.Format("{0} has spawned the destroyer {1} times!", args.Player.Name, amount)); + } + + private static void SkeletronPrime(CommandArgs args) + { + if (args.Parameters.Count > 1) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /prime [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: /prime [amount]", Color.Red); + return; + } + amount = Math.Min(amount, Main.maxNPCs); + NPC prime = TShock.Utils.GetNPCById(127); + TSPlayer.Server.SetTime(false, 0.0); + TSPlayer.Server.SpawnNPC(prime.type, prime.name, amount, args.Player.TileX, args.Player.TileY); + TShock.Utils.Broadcast(string.Format("{0} has spawned skeletron prime {1} times!", args.Player.Name, amount)); + } + + private static void Hardcore(CommandArgs args) // TODO: Add all 8 bosses + { + 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; + } + amount = Math.Min(amount, Main.maxNPCs/4); + NPC retinazer = TShock.Utils.GetNPCById(125); + NPC spaz = TShock.Utils.GetNPCById(126); + NPC destroyer = TShock.Utils.GetNPCById(134); + NPC prime = TShock.Utils.GetNPCById(127); + NPC eater = TShock.Utils.GetNPCById(13); + NPC eye = TShock.Utils.GetNPCById(4); + NPC king = TShock.Utils.GetNPCById(50); + NPC skeletron = TShock.Utils.GetNPCById(35); + TSPlayer.Server.SetTime(false, 0.0); + TSPlayer.Server.SpawnNPC(retinazer.type, retinazer.name, amount, args.Player.TileX, args.Player.TileY); + TSPlayer.Server.SpawnNPC(spaz.type, spaz.name, amount, args.Player.TileX, args.Player.TileY); + TSPlayer.Server.SpawnNPC(destroyer.type, destroyer.name, amount, args.Player.TileX, args.Player.TileY); + TSPlayer.Server.SpawnNPC(prime.type, prime.name, amount, args.Player.TileX, args.Player.TileY); + TSPlayer.Server.SpawnNPC(eater.type, eater.name, amount, args.Player.TileX, args.Player.TileY); + TSPlayer.Server.SpawnNPC(eye.type, eye.name, amount, args.Player.TileX, args.Player.TileY); + TSPlayer.Server.SpawnNPC(king.type, king.name, amount, args.Player.TileX, args.Player.TileY); + TSPlayer.Server.SpawnNPC(skeletron.type, skeletron.name, amount, args.Player.TileX, args.Player.TileY); + TShock.Utils.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; + } + + amount = Math.Min(amount, Main.maxNPCs); + + var npcs = TShock.Utils.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 && npc.type != 113) + //Do not allow WoF to spawn, in certain conditions may cause loops in client + { + TSPlayer.Server.SpawnNPC(npc.type, npc.name, amount, args.Player.TileX, args.Player.TileY, 50, 20); + TShock.Utils.Broadcast(string.Format("{0} was spawned {1} time(s).", npc.name, amount)); + } + else if (npc.type == 113) + args.Player.SendMessage("Sorry, you can't spawn Wall of Flesh! Try /wof instead."); + // Maybe perhaps do something with WorldGen.SpawnWoF? + else + args.Player.SendMessage("Invalid mob type!", Color.Red); + } + } + + private static void StartHardMode(CommandArgs args) + { + WorldGen.StartHardmode(); + } + + private static void DisableHardMode(CommandArgs args) + { + Main.hardMode = false; + } + + private static void ConvertCorruption(CommandArgs args) + { + TShock.Utils.Broadcast("Server is might lag for a moment.", Color.Red); + for (int x = 0; x < Main.maxTilesX; x++) + { + for (int y = 0; y < Main.maxTilesY; y++) + { + switch (Main.tile[x, y].type) + { + case 22: + case 25: + Main.tile[x, y].type = 117; + break; + case 23: + Main.tile[x, y].type = 109; + break; + case 32: + Main.tile[x, y].type = 0; + Main.tile[x, y].active = false; + break; + case 24: + Main.tile[x, y].type = 110; + break; + case 112: + Main.tile[x, y].type = 116; + break; + default: + continue; + } + } + } + WorldGen.CountTiles(0); + TSPlayer.All.SendData(PacketTypes.UpdateGoodEvil); + Netplay.ResetSections(); + TShock.Utils.Broadcast("Corruption conversion done."); + } + + private static void ConvertHallow(CommandArgs args) + { + TShock.Utils.Broadcast("Server is might lag for a moment.", Color.Red); + for (int x = 0; x < Main.maxTilesX; x++) + { + for (int y = 0; y < Main.maxTilesY; y++) + { + switch (Main.tile[x, y].type) + { + case 117: + Main.tile[x, y].type = 25; + break; + case 109: + Main.tile[x, y].type = 23; + break; + case 116: + Main.tile[x, y].type = 112; + break; + default: + continue; + } + } + } + WorldGen.CountTiles(0); + TSPlayer.All.SendData(PacketTypes.UpdateGoodEvil); + Netplay.ResetSections(); + TShock.Utils.Broadcast("Hallow conversion done."); + } + + #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 = TShock.Utils.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 if (!players[0].TPAllow && !args.Player.Group.HasPermission(Permissions.tpall)) + { + var plr = players[0]; + args.Player.SendMessage(plr.Name + " Has Selected For Users Not To Teleport To Them"); + plr.SendMessage(args.Player.Name + " Attempted To Teleport To You"); + } + else + { + var plr = players[0]; + if (args.Player.Teleport(plr.TileX, plr.TileY + 3)) + { + args.Player.SendMessage(string.Format("Teleported to {0}", plr.Name)); + if (!args.Player.Group.HasPermission(Permissions.tphide)) + plr.SendMessage(args.Player.Name + " Teleported To You"); + } + } + } + + 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 = TShock.Utils.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 TPAllow(CommandArgs args) + { + if (!args.Player.TPAllow) + args.Player.SendMessage("Other Players Can Now Teleport To You"); + if (args.Player.TPAllow) + args.Player.SendMessage("Other Players Can No Longer Teleport To You"); + args.Player.TPAllow = !args.Player.TPAllow; + } + + private static void SendWarp(CommandArgs args) + { + if (args.Parameters.Count < 2) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /sendwarp [player] [warpname]", Color.Red); + return; + } + + var foundplr = TShock.Utils.FindPlayer(args.Parameters[0]); + if (foundplr.Count == 0) + { + args.Player.SendMessage("Invalid player!", Color.Red); + return; + } + else if (foundplr.Count > 1) + { + args.Player.SendMessage(string.Format("More than one ({0}) player matched!", args.Parameters.Count), Color.Red); + return; + } + string warpName = String.Join(" ", args.Parameters[1]); + var warp = TShock.Warps.FindWarp(warpName); + var plr = foundplr[0]; + if (warp.WarpPos != Vector2.Zero) + { + if (plr.Teleport((int) warp.WarpPos.X, (int) warp.WarpPos.Y + 3)) + { + plr.SendMessage(string.Format("{0} Warped you to {1}", args.Player.Name, warpName), Color.Yellow); + args.Player.SendMessage(string.Format("You warped {0} to {1}.", plr.Name, warpName), Color.Yellow); + } + } + else + { + args.Player.SendMessage("Specified warp not found", Color.Red); + } + } + + 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.worldID.ToString())) + { + 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 HideWarp(CommandArgs args) + { + if (args.Parameters.Count > 1) + { + string warpName = String.Join(" ", args.Parameters); + bool state = false; + if (Boolean.TryParse(args.Parameters[1], out state)) + { + if (TShock.Warps.HideWarp(args.Parameters[0], state)) + { + if (state) + args.Player.SendMessage("Made warp " + warpName + " private", Color.Yellow); + else + args.Player.SendMessage("Made warp " + warpName + " public", Color.Yellow); + } + else + args.Player.SendMessage("Could not find specified warp", Color.Red); + } + else + args.Player.SendMessage("Invalid syntax! Proper syntax: /hidewarp [name] ", Color.Red); + } + else + args.Player.SendMessage("Invalid syntax! Proper syntax: /hidewarp [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.ListAllPublicWarps(Main.worldID.ToString()); + + //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 = (page*pagelimit); (i < ((page*pagelimit) + pagelimit)) && i < 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 + 2)), 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 Group Management + + private static void AddGroup(CommandArgs args) + { + if (args.Parameters.Count > 0) + { + String groupname = args.Parameters[0]; + args.Parameters.RemoveAt(0); + String permissions = String.Join(",", args.Parameters); + + String response = TShock.Groups.AddGroup(groupname, permissions); + if (response.Length > 0) + args.Player.SendMessage(response, Color.Green); + } + else + { + args.Player.SendMessage("Incorrect format: /addGroup [optional permissions]", Color.Red); + } + } + + private static void DeleteGroup(CommandArgs args) + { + if (args.Parameters.Count > 0) + { + String groupname = args.Parameters[0]; + + String response = TShock.Groups.DeleteGroup(groupname); + if (response.Length > 0) + args.Player.SendMessage(response, Color.Green); + } + else + { + args.Player.SendMessage("Incorrect format: /delGroup ", Color.Red); + } + } + + private static void ModifyGroup(CommandArgs args) + { + if (args.Parameters.Count > 2) + { + String com = args.Parameters[0]; + args.Parameters.RemoveAt(0); + + String groupname = args.Parameters[0]; + args.Parameters.RemoveAt(0); + + if (com.Equals("add")) + { + String response = TShock.Groups.AddPermissions(groupname, args.Parameters); + if (response.Length > 0) + args.Player.SendMessage(response, Color.Green); + return; + } + else if (com.Equals("del") || com.Equals("delete")) + { + String response = TShock.Groups.DeletePermissions(groupname, args.Parameters); + if (response.Length > 0) + args.Player.SendMessage(response, Color.Green); + return; + } + } + args.Player.SendMessage("Incorrect format: /modGroup add|del ", Color.Red); + } + + #endregion Group Management + + #region Item Management + + private static void AddItem(CommandArgs args) + { + if (args.Parameters.Count > 0) + { + var items = TShock.Utils.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) + { + TShock.Itembans.AddNewBan(item.name); + args.Player.SendMessage(item.name + " has been banned.", Color.Green); + } + else + { + args.Player.SendMessage("Invalid item type!", Color.Red); + } + } + } + else + { + args.Player.SendMessage("Invalid use: /addItem \"item name\" or /addItem ##", Color.Red); + } + } + + private static void DeleteItem(CommandArgs args) + { + if (args.Parameters.Count > 0) + { + var items = TShock.Utils.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) + { + TShock.Itembans.RemoveBan(item.name); + args.Player.SendMessage(item.name + " has been unbanned.", Color.Green); + } + else + { + args.Player.SendMessage("Invalid item type!", Color.Red); + } + } + } + else + { + args.Player.SendMessage("Invalid use: /delItem \"item name\" or /delItem ##", Color.Red); + } + } + + #endregion Item Management + + #region Server Config Commands + + private static void SetSpawn(CommandArgs args) + { + Main.spawnTileX = args.Player.TileX + 1; + Main.spawnTileY = args.Player.TileY + 3; + + TShock.Utils.Broadcast("Server map saving, potential lag spike"); + Thread SaveWorld = new Thread(TShock.Utils.SaveWorld); + SaveWorld.Start(); + } + + private static void Reload(CommandArgs args) + { + FileTools.SetupConfig(); + TShock.Groups.LoadPermisions(); + TShock.Regions.ReloadAllRegions(); + args.Player.SendMessage( + "Configuration, Permissions, and Regions reload complete. Some changes may require server restart."); + } + + private static void ServerPassword(CommandArgs args) + { + if (args.Parameters.Count != 1) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /password \"\"", Color.Red); + return; + } + string passwd = args.Parameters[0]; + TShock.Config.ServerPassword = passwd; + args.Player.SendMessage(string.Format("Server password changed to: {0}", passwd)); + } + + private static void Save(CommandArgs args) + { + TShock.Utils.Broadcast("Server map saving, potential lag spike"); + Thread SaveWorld = new Thread(TShock.Utils.SaveWorld); + SaveWorld.Start(); + } + + private static void Settle(CommandArgs args) + { + if (Liquid.panicMode) + { + args.Player.SendMessage("Liquid is already settling!", Color.Red); + return; + } + Liquid.StartPanic(); + TShock.Utils.Broadcast("Settling all liquids..."); + } + + 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; + TShock.Utils.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; + TShock.Utils.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); + TShock.Utils.Broadcast(string.Format("{0} set time to day.", args.Player.Name)); + break; + case "night": + TSPlayer.Server.SetTime(false, 0.0); + TShock.Utils.Broadcast(string.Format("{0} set time to night.", args.Player.Name)); + break; + case "dusk": + TSPlayer.Server.SetTime(false, 0.0); + TShock.Utils.Broadcast(string.Format("{0} set time to dusk.", args.Player.Name)); + break; + case "noon": + TSPlayer.Server.SetTime(true, 27000.0); + TShock.Utils.Broadcast(string.Format("{0} set time to noon.", args.Player.Name)); + break; + case "midnight": + TSPlayer.Server.SetTime(false, 16200.0); + TShock.Utils.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 = TShock.Utils.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(Permissions.kill)) + { + damage = TShock.Utils.Clamp(damage, 15, 0); + } + plr.DamagePlayer(damage); + TShock.Utils.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); + TShock.Utils.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); + TShock.Utils.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.Name + ": P: " + r.DisableBuild + " X: " + r.Area.X + " Y: " + r.Area.Y + " W: " + + r.Area.Width + " H: " + r.Area.Height); + foreach (int s in r.AllowedIDs) + { + args.Player.SendMessage(r.Name + ": " + s); + } + } + } + + private static void Region(CommandArgs args) + { + string cmd = "help"; + if (args.Parameters.Count > 0) + { + cmd = args.Parameters[0].ToLower(); + } + switch (cmd) + { + case "name": + { + { + args.Player.SendMessage("Hit a block to get the name of the region", Color.Yellow); + args.Player.AwaitingName = true; + } + break; + } + case "set": + { + int choice = 0; + if (args.Parameters.Count == 2 && + int.TryParse(args.Parameters[1], out choice) && + choice >= 1 && choice <= 2) + { + args.Player.SendMessage("Hit a block to Set Point " + choice, Color.Yellow); + args.Player.AwaitingTempPoint = choice; + } + 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.TempPoints.Any(p => p == Point.Zero)) + { + string regionName = String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1)); + var x = Math.Min(args.Player.TempPoints[0].X, args.Player.TempPoints[1].X); + var y = Math.Min(args.Player.TempPoints[0].Y, args.Player.TempPoints[1].Y); + var width = Math.Abs(args.Player.TempPoints[0].X - args.Player.TempPoints[1].X); + var height = Math.Abs(args.Player.TempPoints[0].Y - args.Player.TempPoints[1].Y); + + if (TShock.Regions.AddRegion(x, y, width, height, regionName, args.Player.UserAccountName, + Main.worldID.ToString())) + { + args.Player.TempPoints[0] = Point.Zero; + args.Player.TempPoints[1] = Point.Zero; + 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.TempPoints[0] = Point.Zero; + args.Player.TempPoints[1] = Point.Zero; + args.Player.SendMessage("Cleared temp area", Color.Yellow); + args.Player.AwaitingTempPoint = 0; + break; + } + case "allow": + { + if (args.Parameters.Count > 2) + { + string playerName = args.Parameters[1]; + string regionName = ""; + + for (int i = 2; i < args.Parameters.Count; i++) + { + if (regionName == "") + { + regionName = args.Parameters[2]; + } + else + { + regionName = regionName + " " + args.Parameters[i]; + } + } + if (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 "remove": + if (args.Parameters.Count > 2) + { + string playerName = args.Parameters[1]; + string regionName = ""; + + for (int i = 2; i < args.Parameters.Count; i++) + { + if (regionName == "") + { + regionName = args.Parameters[2]; + } + else + { + regionName = regionName + " " + args.Parameters[i]; + } + } + if (TShock.Users.GetUserByName(playerName) != null) + { + if (TShock.Regions.RemoveUser(regionName, playerName)) + { + args.Player.SendMessage("Removed user " + playerName + " from " + 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 remove [name] [region]", Color.Red); + break; case "allowg": { if (args.Parameters.Count > 2) @@ -2210,863 +2234,877 @@ namespace TShockAPI else args.Player.SendMessage("Invalid syntax! Proper syntax: /region removeg [group] [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; + 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 - } + 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.worldID.ToString()); + var regions = TShock.Regions.ListAllRegions(Main.worldID.ToString()); - // Are there even any regions to display? - if (regions.Count == 0) - { - args.Player.SendMessage("There are currently no regions defined.", Color.Red); - return; - } + // Are there even any regions to display? + if (regions.Count == 0) + { + args.Player.SendMessage("There are currently no regions defined.", Color.Red); + return; + } - //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; - } + //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); + //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 = (page * pagelimit); (i < ((page * pagelimit) + pagelimit)) && i < regions.Count; i++) - { - nameslist.Add(regions[i].Name); - } + //Add up to pagelimit names to a list + var nameslist = new List(); + for (int i = (page*pagelimit); (i < ((page*pagelimit) + pagelimit)) && i < regions.Count; i++) + { + nameslist.Add(regions[i].Name); + } - //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); - } + //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 + 2)), Color.Yellow); - } + if (page < pagecount) + { + args.Player.SendMessage(string.Format("Type /region list {0} for more regions.", (page + 2)), Color.Yellow); + } - break; - } - case "info": - { - if (args.Parameters.Count > 1) - { - string regionName = String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1)); - Region r = TShock.Regions.GetRegionByName(regionName); + break; + } + case "info": + { + if (args.Parameters.Count > 1) + { + string regionName = String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1)); + Region r = TShock.Regions.GetRegionByName(regionName); - if (r == null) - { - args.Player.SendMessage("Region {0} does not exist"); - break; - } + if (r == null) + { + args.Player.SendMessage("Region {0} does not exist"); + break; + } - args.Player.SendMessage(r.Name + ": P: " + r.DisableBuild + " X: " + r.Area.X + " Y: " + r.Area.Y + " W: " + r.Area.Width + " H: " + r.Area.Height); - foreach (int s in r.AllowedIDs) - { - var user = TShock.Users.GetUserByID(s); - args.Player.SendMessage(r.Name + ": " + (user != null ? user.Name : "Unknown")); - } - } - else - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /region info [name]", Color.Red); - } + args.Player.SendMessage(r.Name + ": P: " + r.DisableBuild + " X: " + r.Area.X + " Y: " + r.Area.Y + " W: " + + r.Area.Width + " H: " + r.Area.Height); + foreach (int s in r.AllowedIDs) + { + var user = TShock.Users.GetUserByID(s); + args.Player.SendMessage(r.Name + ": " + (user != null ? user.Name : "Unknown")); + } + } + else + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /region info [name]", Color.Red); + } - break; - } - case "resize": - case "expand": - { - if (args.Parameters.Count == 4) - { - int direction; - switch (args.Parameters[2]) - { - case "u": - case "up": - { - direction = 0; - break; - } - case "r": - case "right": - { - direction = 1; - break; - } - case "d": - case "down": - { - direction = 2; - break; - } - case "l": - case "left": - { - direction = 3; - break; - } - default: - { - direction = -1; - break; - } - } - int addAmount; - int.TryParse(args.Parameters[3], out addAmount); - if (TShock.Regions.resizeRegion(args.Parameters[1], addAmount, direction)) - { - args.Player.SendMessage("Region Resized Successfully!", Color.Yellow); - TShock.Regions.ReloadAllRegions(); - } - else - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /region resize [regionname] [u/d/l/r] [amount]", Color.Red); - } - } - else - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /region resize [regionname] [u/d/l/r] [amount]1", Color.Red); - } - 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 name (provides region name)", Color.Yellow); - args.Player.SendMessage("/region delete [name] /region clear (temporary region)", Color.Yellow); - args.Player.SendMessage("/region allow [name] [regionname]", Color.Yellow); - args.Player.SendMessage("/region resize [regionname] [u/d/l/r] [amount]", Color.Yellow); - break; - } - } - } + break; + } + case "resize": + case "expand": + { + if (args.Parameters.Count == 4) + { + int direction; + switch (args.Parameters[2]) + { + case "u": + case "up": + { + direction = 0; + break; + } + case "r": + case "right": + { + direction = 1; + break; + } + case "d": + case "down": + { + direction = 2; + break; + } + case "l": + case "left": + { + direction = 3; + break; + } + default: + { + direction = -1; + break; + } + } + int addAmount; + int.TryParse(args.Parameters[3], out addAmount); + if (TShock.Regions.resizeRegion(args.Parameters[1], addAmount, direction)) + { + args.Player.SendMessage("Region Resized Successfully!", Color.Yellow); + TShock.Regions.ReloadAllRegions(); + } + else + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /region resize [regionname] [u/d/l/r] [amount]", + Color.Red); + } + } + else + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /region resize [regionname] [u/d/l/r] [amount]1", + Color.Red); + } + 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 name (provides region name)", Color.Yellow); + args.Player.SendMessage("/region delete [name] /region clear (temporary region)", Color.Yellow); + args.Player.SendMessage("/region allow [name] [regionname]", Color.Yellow); + args.Player.SendMessage("/region resize [regionname] [u/d/l/r] [amount]", Color.Yellow); + break; + } + } + } - #endregion World Protection Commands + #endregion World Protection Commands - #region General 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 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}.", TShock.Utils.GetPlayers()), 255, 240, 20); - args.Player.SendMessage(string.Format("TShock: {0} ({1}): ({2}/{3})", TShock.VersionNum, TShock.VersionCodename, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots)); - } + private static void Playing(CommandArgs args) + { + args.Player.SendMessage(string.Format("Current players: {0}.", TShock.Utils.GetPlayers()), 255, 240, 20); + args.Player.SendMessage(string.Format("TShock: {0} ({1}): ({2}/{3})", TShock.VersionNum, TShock.VersionCodename, + TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots)); + } - 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 = TShock.Utils.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; - } + 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 = TShock.Utils.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; - } + 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."); - } + 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; - } + 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; - } + 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; - } + 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; - } - if (args.Player.mute) - args.Player.SendMessage("You are muted."); - else - TShock.Utils.Broadcast(string.Format("*{0} {1}", args.Player.Name, String.Join(" ", args.Parameters)), 205, 133, 63); - } + private static void ThirdPerson(CommandArgs args) + { + if (args.Parameters.Count == 0) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /me ", Color.Red); + return; + } + if (args.Player.mute) + args.Player.SendMessage("You are muted."); + else + TShock.Utils.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; + 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 (args.Player.mute) - args.Player.SendMessage("You are muted."); - else 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); - } + if (args.Player.mute) + args.Player.SendMessage("You are muted."); + else 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 Mute(CommandArgs args) - { - if (args.Parameters.Count < 1) - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /mute ", Color.Red); - return; - } + private static void Mute(CommandArgs args) + { + if (args.Parameters.Count < 1) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /mute ", Color.Red); + return; + } - string plStr = String.Join(" ", args.Parameters); - var players = TShock.Utils.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 if (players[0].mute && !players[0].Group.HasPermission(Permissions.mute)) - { - var plr = players[0]; - plr.mute = false; - plr.SendMessage("You have been unmuted."); - TShock.Utils.Broadcast(plr.Name + " has been unmuted by " + args.Player.Name, Color.Yellow); - } - else if (!players[0].Group.HasPermission(Permissions.mute)) - { - var plr = players[0]; - plr.mute = true; - plr.SendMessage("You have been muted."); - TShock.Utils.Broadcast(plr.Name + " has been muted by " + args.Player.Name, Color.Yellow); - } - else - args.Player.SendMessage("You cannot mute this player."); - - } + string plStr = String.Join(" ", args.Parameters); + var players = TShock.Utils.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 if (players[0].mute && !players[0].Group.HasPermission(Permissions.mute)) + { + var plr = players[0]; + plr.mute = false; + plr.SendMessage("You have been unmuted."); + TShock.Utils.Broadcast(plr.Name + " has been unmuted by " + args.Player.Name, Color.Yellow); + } + else if (!players[0].Group.HasPermission(Permissions.mute)) + { + var plr = players[0]; + plr.mute = true; + plr.SendMessage("You have been muted."); + TShock.Utils.Broadcast(plr.Name + " has been muted by " + args.Player.Name, Color.Yellow); + } + else + args.Player.SendMessage("You cannot mute this player."); + } - private static void Motd(CommandArgs args) - { - TShock.Utils.ShowFileToUser(args.Player, "motd.txt"); - } + private static void Motd(CommandArgs args) + { + TShock.Utils.ShowFileToUser(args.Player, "motd.txt"); + } - private static void Rules(CommandArgs args) - { - TShock.Utils.ShowFileToUser(args.Player, "rules.txt"); - } + private static void Rules(CommandArgs args) + { + TShock.Utils.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; - } + private static void Whisper(CommandArgs args) + { + if (args.Parameters.Count < 2) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /whisper ", Color.Red); + return; + } - var players = TShock.Utils.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 if (args.Player.mute) - args.Player.SendMessage("You are muted."); - 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; - } - } + var players = TShock.Utils.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 if (args.Player.mute) + args.Player.SendMessage("You are muted."); + 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.mute) - args.Player.SendMessage("You are muted."); - else 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 Reply(CommandArgs args) + { + if (args.Player.mute) + args.Player.SendMessage("You are muted."); + else 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); + 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 = TShock.Utils.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 + " seconds."); - (new Thread(ply.Whoopie)).Start(annoy); - } - } + var players = TShock.Utils.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 + " seconds."); + (new Thread(ply.Whoopie)).Start(annoy); + } + } - #endregion General Commands + #endregion General Commands - #region Cheat 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; - } + 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 = TShock.Utils.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)); - } - } + string plStr = String.Join(" ", args.Parameters); + var players = TShock.Utils.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; - } + 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); + 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].type != 0 && !Main.npc[i].townNPC && (!Main.npc[i].friendly || killFriendly)) - { - TSPlayer.Server.StrikeNPC(i, 99999, 90f, 1); - killcount++; - } - } - TShock.Utils.Broadcast(string.Format("Killed {0} NPCs.", killcount)); - } + int killcount = 0; + for (int i = 0; i < Main.npc.Length; i++) + { + if (Main.npc[i].active && Main.npc[i].type != 0 && !Main.npc[i].townNPC && (!Main.npc[i].friendly || killFriendly)) + { + TSPlayer.Server.StrikeNPC(i, 99999, 90f, 1); + killcount++; + } + } + TShock.Utils.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] [prefix id/name]", Color.Red); - return; - } - if (args.Parameters[0].Length == 0) - { - args.Player.SendMessage("Missing item name/id", Color.Red); - return; - } - int itemAmount = 0; - int prefix = 0; - if (args.Parameters.Count == 2) - int.TryParse(args.Parameters[1], out itemAmount); - else if (args.Parameters.Count == 3) - { - int.TryParse(args.Parameters[1], out itemAmount); - var found = TShock.Utils.GetPrefixByIdOrName(args.Parameters[2]); - if (found.Count == 1) - prefix = found[0]; - } - var items = TShock.Utils.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, prefix); - args.Player.SendMessage(string.Format("Gave {0} {1}(s).", itemAmount, 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 Item(CommandArgs args) + { + if (args.Parameters.Count < 1) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /item [item amount] [prefix id/name]", + Color.Red); + return; + } + if (args.Parameters[0].Length == 0) + { + args.Player.SendMessage("Missing item name/id", Color.Red); + return; + } + int itemAmount = 0; + int prefix = 0; + if (args.Parameters.Count == 2) + int.TryParse(args.Parameters[1], out itemAmount); + else if (args.Parameters.Count == 3) + { + int.TryParse(args.Parameters[1], out itemAmount); + var found = TShock.Utils.GetPrefixByIdOrName(args.Parameters[2]); + if (found.Count == 1) + prefix = found[0]; + } + var items = TShock.Utils.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, prefix); + args.Player.SendMessage(string.Format("Gave {0} {1}(s).", itemAmount, 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] [prefix id/name]", 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 prefix = 0; - var items = TShock.Utils.GetItemByIdOrName(args.Parameters[0]); - args.Parameters.RemoveAt(0); - string plStr = args.Parameters[0]; - args.Parameters.RemoveAt(0); - if (args.Parameters.Count == 1) - int.TryParse(args.Parameters[0], out itemAmount); - else if (args.Parameters.Count == 2) - { - int.TryParse(args.Parameters[0], out itemAmount); - var found = TShock.Utils.GetPrefixByIdOrName(args.Parameters[1]); - if (found.Count == 1) - prefix = found[0]; - } + private static void Give(CommandArgs args) + { + if (args.Parameters.Count < 2) + { + args.Player.SendMessage( + "Invalid syntax! Proper syntax: /give [item amount] [prefix id/name]", 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 prefix = 0; + var items = TShock.Utils.GetItemByIdOrName(args.Parameters[0]); + args.Parameters.RemoveAt(0); + string plStr = args.Parameters[0]; + args.Parameters.RemoveAt(0); + if (args.Parameters.Count == 1) + int.TryParse(args.Parameters[0], out itemAmount); + else if (args.Parameters.Count == 2) + { + int.TryParse(args.Parameters[0], out itemAmount); + var found = TShock.Utils.GetPrefixByIdOrName(args.Parameters[1]); + if (found.Count == 1) + prefix = found[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) - { - var players = TShock.Utils.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, prefix); - args.Player.SendMessage(string.Format("Gave {0} {1} {2}(s).", plr.Name, itemAmount, item.name)); - plr.SendMessage(string.Format("{0} gave you {1} {2}(s).", args.Player.Name, itemAmount, item.name)); - } - else - { - args.Player.SendMessage("Player does not have free slots!", Color.Red); - } - } - } - else - { - args.Player.SendMessage("Invalid item type!", Color.Red); - } - } - } + 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) + { + var players = TShock.Utils.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, prefix); + args.Player.SendMessage(string.Format("Gave {0} {1} {2}(s).", plr.Name, itemAmount, item.name)); + plr.SendMessage(string.Format("{0} gave you {1} {2}(s).", args.Player.Name, itemAmount, item.name)); + } + else + { + args.Player.SendMessage("Player does not have free slots!", Color.Red); + } + } + } + else + { + args.Player.SendMessage("Invalid item type!", Color.Red); + } + } + } - public static void ClearItems(CommandArgs args) - { + public static void ClearItems(CommandArgs args) + { + int radius = 50; + if (args.Parameters.Count > 0) + { + if (args.Parameters[0].ToLower() == "all") + { + radius = Int32.MaxValue/16; + } + else + { + try + { + radius = Convert.ToInt32(args.Parameters[0]); + } + catch (Exception) + { + args.Player.SendMessage( + "Please either enter the keyword \"all\", or the block radius you wish to delete all items from.", Color.Red); + return; + } + } + } + int count = 0; + for (int i = 0; i < 200; i++) + { + if ( + (Math.Sqrt(Math.Pow(Main.item[i].position.X - args.Player.X, 2) + + Math.Pow(Main.item[i].position.Y - args.Player.Y, 2)) < radius*16) && (Main.item[i].active)) + { + Main.item[i].active = false; + NetMessage.SendData(0x15, -1, -1, "", i, 0f, 0f, 0f, 0); + count++; + } + } + args.Player.SendMessage("All " + count + " items within a radius of " + radius + " have been deleted."); + } - int radius = 50; - if (args.Parameters.Count > 0) - { - if (args.Parameters[0].ToLower() == "all") - { - radius = Int32.MaxValue / 16; - } - else - { - try - { - radius = Convert.ToInt32(args.Parameters[0]); - } - catch (Exception) { args.Player.SendMessage("Please either enter the keyword \"all\", or the block radius you wish to delete all items from.", Color.Red); return; } - } + private static void Heal(CommandArgs args) + { + TSPlayer playerToHeal; + if (args.Parameters.Count > 0) + { + string plStr = String.Join(" ", args.Parameters); + var players = TShock.Utils.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; + } - } - int count = 0; - for (int i = 0; i < 200; i++) - { - if ((Math.Sqrt(Math.Pow(Main.item[i].position.X - args.Player.X, 2) + Math.Pow(Main.item[i].position.Y - args.Player.Y, 2)) < radius * 16) && (Main.item[i].active)) - { - Main.item[i].active = false; - NetMessage.SendData(0x15, -1, -1, "", i, 0f, 0f, 0f, 0); - count++; - } - } - args.Player.SendMessage("All " + count + " items within a radius of " + radius + " have been deleted."); + Item heart = TShock.Utils.GetItemById(58); + Item star = TShock.Utils.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)); + } + } - } + private static void Buff(CommandArgs args) + { + if (args.Parameters.Count < 1 || args.Parameters.Count > 2) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /buff [time(seconds)]", Color.Red); + return; + } + int id = 0; + int time = 60; + if (!int.TryParse(args.Parameters[0], out id)) + { + var found = TShock.Utils.GetBuffByName(args.Parameters[0]); + if (found.Count == 0) + { + args.Player.SendMessage("Invalid buff name!", Color.Red); + return; + } + else if (found.Count > 1) + { + args.Player.SendMessage(string.Format("More than one ({0}) buff matched!", found.Count), Color.Red); + return; + } + id = found[0]; + } + if (args.Parameters.Count == 2) + int.TryParse(args.Parameters[1], out time); + if (id > 0 && id < Main.maxBuffs) + { + if (time < 0 || time > short.MaxValue) + time = 60; + args.Player.SetBuff(id, time*60); + args.Player.SendMessage(string.Format("You have buffed yourself with {0}({1}) for {2} seconds!", + TShock.Utils.GetBuffName(id), TShock.Utils.GetBuffDescription(id), (time)), + Color.Green); + } + else + args.Player.SendMessage("Invalid buff ID!", Color.Red); + } - private static void Heal(CommandArgs args) - { - TSPlayer playerToHeal; - if (args.Parameters.Count > 0) - { - string plStr = String.Join(" ", args.Parameters); - var players = TShock.Utils.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; - } + private static void GBuff(CommandArgs args) + { + if (args.Parameters.Count < 2 || args.Parameters.Count > 3) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /gbuff [time(seconds)]", Color.Red); + return; + } + int id = 0; + int time = 60; + var foundplr = TShock.Utils.FindPlayer(args.Parameters[0]); + if (foundplr.Count == 0) + { + args.Player.SendMessage("Invalid player!", Color.Red); + return; + } + else if (foundplr.Count > 1) + { + args.Player.SendMessage(string.Format("More than one ({0}) player matched!", args.Parameters.Count), Color.Red); + return; + } + else + { + if (!int.TryParse(args.Parameters[1], out id)) + { + var found = TShock.Utils.GetBuffByName(args.Parameters[1]); + if (found.Count == 0) + { + args.Player.SendMessage("Invalid buff name!", Color.Red); + return; + } + else if (found.Count > 1) + { + args.Player.SendMessage(string.Format("More than one ({0}) buff matched!", found.Count), Color.Red); + return; + } + id = found[0]; + } + if (args.Parameters.Count == 3) + int.TryParse(args.Parameters[2], out time); + if (id > 0 && id < Main.maxBuffs) + { + if (time < 0 || time > short.MaxValue) + time = 60; + foundplr[0].SetBuff(id, time*60); + args.Player.SendMessage(string.Format("You have buffed {0} with {1}({2}) for {3} seconds!", + foundplr[0].Name, TShock.Utils.GetBuffName(id), + TShock.Utils.GetBuffDescription(id), (time)), Color.Green); + foundplr[0].SendMessage(string.Format("{0} has buffed you with {1}({2}) for {3} seconds!", + args.Player.Name, TShock.Utils.GetBuffName(id), + TShock.Utils.GetBuffDescription(id), (time)), Color.Green); + } + else + args.Player.SendMessage("Invalid buff ID!", Color.Red); + } + } - Item heart = TShock.Utils.GetItemById(58); - Item star = TShock.Utils.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)); - } - } + private static void Grow(CommandArgs args) + { + if (args.Parameters.Count != 1) + { + args.Player.SendMessage("Invalid syntax! Proper syntax: /grow [tree/epictree/mushroom/cactus/herb]", Color.Red); + return; + } + var name = "Fail"; + var x = args.Player.TileX; + var y = args.Player.TileY + 3; + switch (args.Parameters[0].ToLower()) + { + case "tree": + for (int i = x - 1; i < x + 2; i++) + { + Main.tile[i, y].active = true; + Main.tile[i, y].type = 2; + Main.tile[i, y].wall = 0; + } + Main.tile[x, y - 1].wall = 0; + WorldGen.GrowTree(x, y); + name = "Tree"; + break; + case "epictree": + for (int i = x - 1; i < x + 2; i++) + { + Main.tile[i, y].active = true; + Main.tile[i, y].type = 2; + Main.tile[i, y].wall = 0; + } + Main.tile[x, y - 1].wall = 0; + Main.tile[x, y - 1].liquid = 0; + Main.tile[x, y - 1].active = true; + WorldGen.GrowEpicTree(x, y); + name = "Epic Tree"; + break; + case "mushroom": + for (int i = x - 1; i < x + 2; i++) + { + Main.tile[i, y].active = true; + Main.tile[i, y].type = 70; + Main.tile[i, y].wall = 0; + } + Main.tile[x, y - 1].wall = 0; + WorldGen.GrowShroom(x, y); + name = "Mushroom"; + break; + case "cactus": + Main.tile[x, y].type = 53; + WorldGen.GrowCactus(x, y); + name = "Cactus"; + break; + case "herb": + Main.tile[x, y].active = true; + Main.tile[x, y].frameX = 36; + Main.tile[x, y].type = 83; + WorldGen.GrowAlch(x, y); + name = "Herb"; + break; + default: + args.Player.SendMessage("Unknown plant!", Color.Red); + return; + } + args.Player.SendTileSquare(x, y); + args.Player.SendMessage("Tried to grow a " + name, Color.Green); + } - private static void Buff(CommandArgs args) - { - if (args.Parameters.Count < 1 || args.Parameters.Count > 2) - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /buff [time(seconds)]", Color.Red); - return; - } - int id = 0; - int time = 60; - if (!int.TryParse(args.Parameters[0], out id)) - { - var found = TShock.Utils.GetBuffByName(args.Parameters[0]); - if (found.Count == 0) - { - args.Player.SendMessage("Invalid buff name!", Color.Red); - return; - } - else if (found.Count > 1) - { - args.Player.SendMessage(string.Format("More than one ({0}) buff matched!", found.Count), Color.Red); - return; - } - id = found[0]; - } - if (args.Parameters.Count == 2) - int.TryParse(args.Parameters[1], out time); - if (id > 0 && id < Main.maxBuffs) - { - if (time < 0 || time > short.MaxValue) - time = 60; - args.Player.SetBuff(id, time * 60); - args.Player.SendMessage(string.Format("You have buffed yourself with {0}({1}) for {2} seconds!", - TShock.Utils.GetBuffName(id), TShock.Utils.GetBuffDescription(id), (time)), Color.Green); - } - else - args.Player.SendMessage("Invalid buff ID!", Color.Red); - } - - private static void GBuff(CommandArgs args) - { - if (args.Parameters.Count < 2 || args.Parameters.Count > 3) - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /gbuff [time(seconds)]", Color.Red); - return; - } - int id = 0; - int time = 60; - var foundplr = TShock.Utils.FindPlayer(args.Parameters[0]); - if (foundplr.Count == 0) - { - args.Player.SendMessage("Invalid player!", Color.Red); - return; - } - else if (foundplr.Count > 1) - { - args.Player.SendMessage(string.Format("More than one ({0}) player matched!", args.Parameters.Count), Color.Red); - return; - } - else - { - if (!int.TryParse(args.Parameters[1], out id)) - { - var found = TShock.Utils.GetBuffByName(args.Parameters[1]); - if (found.Count == 0) - { - args.Player.SendMessage("Invalid buff name!", Color.Red); - return; - } - else if (found.Count > 1) - { - args.Player.SendMessage(string.Format("More than one ({0}) buff matched!", found.Count), Color.Red); - return; - } - id = found[0]; - } - if (args.Parameters.Count == 3) - int.TryParse(args.Parameters[2], out time); - if (id > 0 && id < Main.maxBuffs) - { - if (time < 0 || time > short.MaxValue) - time = 60; - foundplr[0].SetBuff(id, time * 60); - args.Player.SendMessage(string.Format("You have buffed {0} with {1}({2}) for {3} seconds!", - foundplr[0].Name, TShock.Utils.GetBuffName(id), TShock.Utils.GetBuffDescription(id), (time)), Color.Green); - foundplr[0].SendMessage(string.Format("{0} has buffed you with {1}({2}) for {3} seconds!", - args.Player.Name, TShock.Utils.GetBuffName(id), TShock.Utils.GetBuffDescription(id), (time)), Color.Green); - } - else - args.Player.SendMessage("Invalid buff ID!", Color.Red); - } - } - - private static void Grow(CommandArgs args) - { - if (args.Parameters.Count != 1) - { - args.Player.SendMessage("Invalid syntax! Proper syntax: /grow [tree/epictree/mushroom/cactus/herb]", Color.Red); - return; - } - var name = "Fail"; - var x = args.Player.TileX; - var y = args.Player.TileY + 3; - switch (args.Parameters[0].ToLower()) - { - case "tree": - for (int i = x - 1; i < x + 2; i++) - { - Main.tile[i, y].active = true; - Main.tile[i, y].type = 2; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowTree(x, y); - name = "Tree"; - break; - case "epictree": - for (int i = x - 1; i < x + 2; i++) - { - Main.tile[i, y].active = true; - Main.tile[i, y].type = 2; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - Main.tile[x, y - 1].liquid = 0; - Main.tile[x, y - 1].active = true; - WorldGen.GrowEpicTree(x, y); - name = "Epic Tree"; - break; - case "mushroom": - for (int i = x - 1; i < x + 2; i++) - { - Main.tile[i, y].active = true; - Main.tile[i, y].type = 70; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowShroom(x, y); - name = "Mushroom"; - break; - case "cactus": - Main.tile[x, y].type = 53; - WorldGen.GrowCactus(x, y); - name = "Cactus"; - break; - case "herb": - Main.tile[x, y].active = true; - Main.tile[x, y].frameX = 36; - Main.tile[x, y].type = 83; - WorldGen.GrowAlch(x, y); - name = "Herb"; - break; - default: - args.Player.SendMessage("Unknown plant!", Color.Red); - return; - } - args.Player.SendTileSquare(x, y); - args.Player.SendMessage("Tried to grow a " + name, Color.Green); - } - - #endregion Cheat Comamnds - } -} + #endregion Cheat Comamnds + } +} \ No newline at end of file diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs index 898fd4bb..3f215257 100644 --- a/TShockAPI/ConfigFile.cs +++ b/TShockAPI/ConfigFile.cs @@ -24,274 +24,245 @@ using Newtonsoft.Json; namespace TShockAPI { - public class ConfigFile - { - [Description("The equation for calculating invasion size is 100 + (multiplier * (number of active players with greater than 200 health))")] - public int InvasionMultiplier = 1; - [Description("The default maximum mobs that will spawn per wave. Higher means more mobs in that wave.")] - public int DefaultMaximumSpawns = 5; - [Description("The delay between waves. Shorter values lead to less mobs.")] - public int DefaultSpawnRate = 600; - [Description("The port the server runs on.")] - public int ServerPort = 7777; - [Description("Enable or disable the whitelist based on IP addresses in whitelist.txt")] - public bool EnableWhitelist; - [Description("Enable the ability for invaison size to never decrease. Make sure to run /invade, and note that this adds 2 million+ goblins to the spawn que for the map.")] - public bool InfiniteInvasion; - [Description("Set the server pvp mode. Vaild types are, \"normal\", \"always\", \"disabled\"")] - public string PvPMode = "normal"; - [Description("Prevents tiles from being placed within SpawnProtectionRadius of the default spawn.")] - public bool SpawnProtection = true; - [Description("Radius from spawn tile for SpawnProtection.")] - public int SpawnProtectionRadius = 10; - [Description("Max slots for the server. If you want people to be kicked with \"Server is full\" set this to how many players you want max and then set Terraria max players to 2 higher.")] - public int MaxSlots = 8; - [Description("Global protection agent for any block distance based anti-grief check.")] - public bool RangeChecks = true; - [Description("Disables any building; placing of blocks")] - public bool DisableBuild; - [Description("#.#.#. = Red/Blue/Green - RGB Colors for the Admin Chat Color. Max value: 255")] - public float[] SuperAdminChatRGB = { 255, 0, 0 }; - [Description("Super admin group chat prefix")] - public string SuperAdminChatPrefix = "(Admin) "; - [Description("Super admin group chat suffix")] - public string SuperAdminChatSuffix = ""; - [Description("Backup frequency in minutes. So, a value of 60 = 60 minutes. Backups are stored in the \\tshock\\backups folder.")] - public int BackupInterval; - [Description("How long backups are kept in minutes. 2880 = 2 days.")] - public int BackupKeepFor = 60; + public class ConfigFile + { + [Description( + "The equation for calculating invasion size is 100 + (multiplier * (number of active players with greater than 200 health))" + )] public int InvasionMultiplier = 1; - [Description("Remembers where a player left off. It works by remembering the IP, NOT the character. \neg. When you try to disconnect, and reconnect to be automatically placed at spawn, you'll be at your last location. Note: Won't save after server restarts.")] - public bool RememberLeavePos; - [Description("Hardcore players ONLY. This means softcore players cannot join.")] - public bool HardcoreOnly; - [Description("Mediumcore players ONLY. This means softcore players cannot join.")] - public bool MediumcoreOnly; - [Description("Kicks a Hardcore player on death.")] - public bool KickOnMediumcoreDeath; - [Description("Bans a Hardcore player on death.")] - public bool BanOnMediumcoreDeath; + [Description("The default maximum mobs that will spawn per wave. Higher means more mobs in that wave.")] public int + DefaultMaximumSpawns = 5; - [Description("Enable/Disable Terrarias built in auto save")] - public bool AutoSave = true; + [Description("The delay between waves. Shorter values lead to less mobs.")] public int DefaultSpawnRate = 600; + [Description("The port the server runs on.")] public int ServerPort = 7777; + [Description("Enable or disable the whitelist based on IP addresses in whitelist.txt")] public bool EnableWhitelist; - [Description("Number of failed login attempts before kicking the player.")] - public int MaximumLoginAttempts = 3; + [Description( + "Enable the ability for invaison size to never decrease. Make sure to run /invade, and note that this adds 2 million+ goblins to the spawn que for the map." + )] public bool InfiniteInvasion; - [Description("Not implemented")] - public string RconPassword = ""; - [Description("Not implemented")] - public int RconPort = 7777; + [Description("Set the server pvp mode. Vaild types are, \"normal\", \"always\", \"disabled\"")] public string PvPMode + = "normal"; - [Description("Not implemented")] - public string ServerName = ""; - [Description("Not implemented")] - public string MasterServer = "127.0.0.1"; + [Description("Prevents tiles from being placed within SpawnProtectionRadius of the default spawn.")] public bool + SpawnProtection = true; - [Description("Valid types are \"sqlite\" and \"mysql\"")] - public string StorageType = "sqlite"; + [Description("Radius from spawn tile for SpawnProtection.")] public int SpawnProtectionRadius = 10; - [Description("The MySQL Hostname and port to direct connections to")] - public string MySqlHost = "localhost:3306"; - [Description("Database name to connect to")] - public string MySqlDbName = ""; - [Description("Database username to connect with")] - public string MySqlUsername = ""; - [Description("Database password to connect with")] - public string MySqlPassword = ""; + [Description( + "Max slots for the server. If you want people to be kicked with \"Server is full\" set this to how many players you want max and then set Terraria max players to 2 higher." + )] public int MaxSlots = 8; - [Description("Bans a Mediumcore player on death.")] - public string MediumcoreBanReason = "Death results in a ban"; - [Description("Kicks a Mediumcore player on death.")] - public string MediumcoreKickReason = "Death results in a kick"; + [Description("Global protection agent for any block distance based anti-grief check.")] public bool RangeChecks = true; + [Description("Disables any building; placing of blocks")] public bool DisableBuild; - [Description("Enables DNS resolution of incoming connections with GetGroupForIPExpensive.")] - public bool EnableDNSHostResolution; + [Description("#.#.#. = Red/Blue/Green - RGB Colors for the Admin Chat Color. Max value: 255")] public float[] + SuperAdminChatRGB = {255, 0, 0}; - [Description("Enables kicking of banned users by matching their IP Address")] - public bool EnableIPBans = true; + [Description("Super admin group chat prefix")] public string SuperAdminChatPrefix = "(Admin) "; + [Description("Super admin group chat suffix")] public string SuperAdminChatSuffix = ""; - [Description("Enables kicking of banned users by matching their Character Name")] - public bool EnableBanOnUsernames; + [Description( + "Backup frequency in minutes. So, a value of 60 = 60 minutes. Backups are stored in the \\tshock\\backups folder.")] public int BackupInterval; - [Description("Drops excessive sync packets")] - public bool EnableAntiLag = true; - - [Description("Selects the default group name to place new registrants under")] - public string DefaultRegistrationGroupName = "default"; + [Description("How long backups are kept in minutes. 2880 = 2 days.")] public int BackupKeepFor = 60; - [Description("Selects the default group name to place non registered users under")] - public string DefaultGuestGroupName = "guest"; + [Description( + "Remembers where a player left off. It works by remembering the IP, NOT the character. \neg. When you try to disconnect, and reconnect to be automatically placed at spawn, you'll be at your last location. Note: Won't save after server restarts." + )] public bool RememberLeavePos; - [Description("Force-Disable printing logs to players with the log permission")] - public bool DisableSpewLogs = true; + [Description("Hardcore players ONLY. This means softcore players cannot join.")] public bool HardcoreOnly; + [Description("Mediumcore players ONLY. This means softcore players cannot join.")] public bool MediumcoreOnly; + [Description("Kicks a Hardcore player on death.")] public bool KickOnMediumcoreDeath; + [Description("Bans a Hardcore player on death.")] public bool BanOnMediumcoreDeath; - [Description("Valid types are \"sha512\", \"sha256\", \"md5\", append with \"-xp\" for the xp supported algorithms")] - public string HashAlgorithm = "sha512"; + [Description("Enable/Disable Terrarias built in auto save")] public bool AutoSave = true; - [Description("Buffers up the packets and sends them out at the end of each frame")] - public bool BufferPackets = true; + [Description("Number of failed login attempts before kicking the player.")] public int MaximumLoginAttempts = 3; - [Description("String that is used when kicking people when the server is full.")] - public string ServerFullReason = "Server is full"; + [Description("Not implemented")] public string RconPassword = ""; + [Description("Not implemented")] public int RconPort = 7777; - [Description("String that is used when kicking people when the server is full with no reserved slots.")] - public string ServerFullNoReservedReason = "Server is full. No reserved slots open."; + [Description("Not implemented")] public string ServerName = ""; + [Description("Not implemented")] public string MasterServer = "127.0.0.1"; - [Description("This will save the world if Terraria crashes from an unhandled exception.")] - public bool SaveWorldOnCrash = true; + [Description("Valid types are \"sqlite\" and \"mysql\"")] public string StorageType = "sqlite"; - [Description("This will announce a player's location on join")] - public bool EnableGeoIP; + [Description("The MySQL Hostname and port to direct connections to")] public string MySqlHost = "localhost:3306"; + [Description("Database name to connect to")] public string MySqlDbName = ""; + [Description("Database username to connect with")] public string MySqlUsername = ""; + [Description("Database password to connect with")] public string MySqlPassword = ""; - [Description("This will turn on a token requirement for the /status API endpoint.")] - public bool EnableTokenEndpointAuthentication; + [Description("Bans a Mediumcore player on death.")] public string MediumcoreBanReason = "Death results in a ban"; + [Description("Kicks a Mediumcore player on death.")] public string MediumcoreKickReason = "Death results in a kick"; - [Description("This is used when the API endpoint /status is queried.")] - public string ServerNickname = "TShock Server"; + [Description("Enables DNS resolution of incoming connections with GetGroupForIPExpensive.")] public bool + EnableDNSHostResolution; - [Description("Enable/Disable the rest api.")] - public bool RestApiEnabled; + [Description("Enables kicking of banned users by matching their IP Address")] public bool EnableIPBans = true; - [Description("This is the port which the rest api will listen on.")] - public int RestApiPort = 7878; + [Description("Enables kicking of banned users by matching their Character Name")] public bool EnableBanOnUsernames; - [Description("Disable tombstones for all players.")] - public bool DisableTombstones = true; + [Description("Drops excessive sync packets")] public bool EnableAntiLag = true; - [Description("Displays a player's IP on join to everyone who has the log permission")] - public bool DisplayIPToAdmins; - - [Description("Some tiles are 'fixed' by not letting TShock handle them. Disabling this may break certain asthetic tiles.")] - public bool EnableInsecureTileFixes = true; + [Description("Selects the default group name to place new registrants under")] public string + DefaultRegistrationGroupName = "default"; - [Description("Kicks users using a proxy as identified with the GeoIP database")] - public bool KickProxyUsers = true; + [Description("Selects the default group name to place non registered users under")] public string + DefaultGuestGroupName = "guest"; - [Description("Disables hardmode, can't never be activated. Overrides /starthardmode")] - public bool DisableHardmode; + [Description("Force-Disable printing logs to players with the log permission")] public bool DisableSpewLogs = true; - [Description("Disables Dungeon Guardian from being spawned by player packets, this will instead force a respawn")] - public bool DisableDungeonGuardian; + [Description("Valid types are \"sha512\", \"sha256\", \"md5\", append with \"-xp\" for the xp supported algorithms")] public string HashAlgorithm = "sha512"; - [Description("Enable Server Side Inventory checks, EXPERIMENTAL")] - public bool ServerSideInventory; + [Description("Buffers up the packets and sends them out at the end of each frame")] public bool BufferPackets = true; - [Description("Disables reporting of playercount to the stat system.")] - public bool DisablePlayerCountReporting; + [Description("String that is used when kicking people when the server is full.")] public string ServerFullReason = + "Server is full"; - [Description("Disables clown bomb projectiles from spawning")] - public bool DisableClownBombs; + [Description("String that is used when kicking people when the server is full with no reserved slots.")] public string + ServerFullNoReservedReason = "Server is full. No reserved slots open."; - [Description("Disables snow ball projectiles from spawning")] - public bool DisableSnowBalls; + [Description("This will save the world if Terraria crashes from an unhandled exception.")] public bool + SaveWorldOnCrash = true; - [Description("Change ingame chat format, {0} = Group Name, {1} = Group Prefix, {2} = Player Name, {3} = Group Suffix, {4} = Chat Message")] - public string ChatFormat = "{1}{2}{3}: {4}"; + [Description("This will announce a player's location on join")] public bool EnableGeoIP; - [Description("Force the world time to be normal, day, or night")] - public string ForceTime = "normal"; + [Description("This will turn on a token requirement for the /status API endpoint.")] public bool + EnableTokenEndpointAuthentication; - [Description("Disable/Revert a player if they exceed this number of tile kills within 1 second.")] - public int TileKillThreshold = 60; + [Description("This is used when the API endpoint /status is queried.")] public string ServerNickname = "TShock Server"; - [Description("Disable/Revert a player if they exceed this number of tile places within 1 second.")] - public int TilePlaceThreshold = 20; + [Description("Enable/Disable the rest api.")] public bool RestApiEnabled; - [Description("Disable a player if they exceed this number of liquid sets within 1 second.")] - public int TileLiquidThreshold = 15; + [Description("This is the port which the rest api will listen on.")] public int RestApiPort = 7878; - [Description("Disable a player if they exceed this number of projectile new within 1 second.")] - public int ProjectileThreshold = 50; + [Description("Disable tombstones for all players.")] public bool DisableTombstones = true; - [Description("Require all players to register or login before being allowed to play.")] - public bool RequireLogin; + [Description("Displays a player's IP on join to everyone who has the log permission")] public bool DisplayIPToAdmins; - [Description("Disables Invisibility potions from being used in PvP (Note, they can use them on the client, but the effect isn't sent to the rest of the server)")] - public bool DisableInvisPvP; + [Description( + "Some tiles are 'fixed' by not letting TShock handle them. Disabling this may break certain asthetic tiles.")] public + bool EnableInsecureTileFixes = true; - [Description("The maximum distance players disabled for various reasons can move from")] - public int MaxRangeForDisabled = 10; + [Description("Kicks users using a proxy as identified with the GeoIP database")] public bool KickProxyUsers = true; - [Description("Server password required to join server")] - public string ServerPassword = ""; + [Description("Disables hardmode, can't never be activated. Overrides /starthardmode")] public bool DisableHardmode; - [Description("Protect chests with region and build permissions")] - public bool RegionProtectChests; + [Description("Disables Dungeon Guardian from being spawned by player packets, this will instead force a respawn")] public bool DisableDungeonGuardian; - [Description("Disable users from being able to login with account password when joining")] - public bool DisableLoginBeforeJoin; + [Description("Enable Server Side Inventory checks, EXPERIMENTAL")] public bool ServerSideInventory; + + [Description("Disables reporting of playercount to the stat system.")] public bool DisablePlayerCountReporting; + + [Description("Disables clown bomb projectiles from spawning")] public bool DisableClownBombs; + + [Description("Disables snow ball projectiles from spawning")] public bool DisableSnowBalls; + + [Description( + "Change ingame chat format, {0} = Group Name, {1} = Group Prefix, {2} = Player Name, {3} = Group Suffix, {4} = Chat Message" + )] public string ChatFormat = "{1}{2}{3}: {4}"; + + [Description("Force the world time to be normal, day, or night")] public string ForceTime = "normal"; + + [Description("Disable/Revert a player if they exceed this number of tile kills within 1 second.")] public int + TileKillThreshold = 60; + + [Description("Disable/Revert a player if they exceed this number of tile places within 1 second.")] public int + TilePlaceThreshold = 20; + + [Description("Disable a player if they exceed this number of liquid sets within 1 second.")] public int + TileLiquidThreshold = 15; + + [Description("Disable a player if they exceed this number of projectile new within 1 second.")] public int + ProjectileThreshold = 50; + + [Description("Require all players to register or login before being allowed to play.")] public bool RequireLogin; + + [Description( + "Disables Invisibility potions from being used in PvP (Note, they can use them on the client, but the effect isn't sent to the rest of the server)" + )] public bool DisableInvisPvP; + + [Description("The maximum distance players disabled for various reasons can move from")] public int + MaxRangeForDisabled = 10; + + [Description("Server password required to join server")] public string ServerPassword = ""; + + [Description("Protect chests with region and build permissions")] public bool RegionProtectChests; + + [Description("Disable users from being able to login with account password when joining")] public bool + DisableLoginBeforeJoin; + + [Description("Allows users to register any username with /register")] public bool AllowRegisterAnyUsername; - [Description("Allows users to register any username with /register")] - public bool AllowRegisterAnyUsername; - public static ConfigFile Read(string path) - { - if (!File.Exists(path)) - return new ConfigFile(); - using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - return Read(fs); - } - } + { + if (!File.Exists(path)) + return new ConfigFile(); + using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return Read(fs); + } + } - public static ConfigFile Read(Stream stream) - { - using (var sr = new StreamReader(stream)) - { - var cf = JsonConvert.DeserializeObject(sr.ReadToEnd()); - if (ConfigRead != null) - ConfigRead(cf); - return cf; - } - } + public static ConfigFile Read(Stream stream) + { + using (var sr = new StreamReader(stream)) + { + var cf = JsonConvert.DeserializeObject(sr.ReadToEnd()); + if (ConfigRead != null) + ConfigRead(cf); + return cf; + } + } - public void Write(string path) - { - using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write)) - { - Write(fs); - } - } + public void Write(string path) + { + using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write)) + { + Write(fs); + } + } - public void Write(Stream stream) - { - var str = JsonConvert.SerializeObject(this, Formatting.Indented); - using (var sw = new StreamWriter(stream)) - { - sw.Write(str); - } - } + public void Write(Stream stream) + { + var str = JsonConvert.SerializeObject(this, Formatting.Indented); + using (var sw = new StreamWriter(stream)) + { + sw.Write(str); + } + } - public static Action ConfigRead; + public static Action ConfigRead; - static void DumpDescriptions() - { - var sb = new StringBuilder(); - var defaults = new ConfigFile(); + private static void DumpDescriptions() + { + var sb = new StringBuilder(); + var defaults = new ConfigFile(); - foreach (var field in defaults.GetType().GetFields()) - { - if (field.IsStatic) - continue; + foreach (var field in defaults.GetType().GetFields()) + { + if (field.IsStatic) + continue; - var name = field.Name; - var type = field.FieldType.Name; + var name = field.Name; + var type = field.FieldType.Name; - var descattr = field.GetCustomAttributes(false).FirstOrDefault(o => o is DescriptionAttribute) as DescriptionAttribute; - var desc = descattr != null && !string.IsNullOrWhiteSpace(descattr.Description) ? descattr.Description : "None"; + var descattr = + field.GetCustomAttributes(false).FirstOrDefault(o => o is DescriptionAttribute) as DescriptionAttribute; + var desc = descattr != null && !string.IsNullOrWhiteSpace(descattr.Description) ? descattr.Description : "None"; - var def = field.GetValue(defaults); + var def = field.GetValue(defaults); - sb.AppendLine("## {0} ".SFormat(name)); - sb.AppendLine("**Type:** {0} ".SFormat(type)); - sb.AppendLine("**Description:** {0} ".SFormat(desc)); - sb.AppendLine("**Default:** \"{0}\" ".SFormat(def)); - sb.AppendLine(); - } + sb.AppendLine("## {0} ".SFormat(name)); + sb.AppendLine("**Type:** {0} ".SFormat(type)); + sb.AppendLine("**Description:** {0} ".SFormat(desc)); + sb.AppendLine("**Default:** \"{0}\" ".SFormat(def)); + sb.AppendLine(); + } - File.WriteAllText("ConfigDescriptions.txt", sb.ToString()); - } - } + File.WriteAllText("ConfigDescriptions.txt", sb.ToString()); + } + } } \ No newline at end of file diff --git a/TShockAPI/DB/BanManager.cs b/TShockAPI/DB/BanManager.cs index e6c17b61..3630287e 100644 --- a/TShockAPI/DB/BanManager.cs +++ b/TShockAPI/DB/BanManager.cs @@ -23,150 +23,153 @@ using MySql.Data.MySqlClient; namespace TShockAPI.DB { - public class BanManager - { - private IDbConnection database; + public class BanManager + { + private IDbConnection database; - public BanManager(IDbConnection db) - { - database = db; + public BanManager(IDbConnection db) + { + database = db; - var table = new SqlTable("Bans", - new SqlColumn("IP", MySqlDbType.String, 16) { Primary = true }, - new SqlColumn("Name", MySqlDbType.Text), - new SqlColumn("Reason", MySqlDbType.Text) - ); - var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator()); - creator.EnsureExists(table); + var table = new SqlTable("Bans", + new SqlColumn("IP", MySqlDbType.String, 16) {Primary = true}, + new SqlColumn("Name", MySqlDbType.Text), + new SqlColumn("Reason", MySqlDbType.Text) + ); + var creator = new SqlTableCreator(db, + db.GetSqlType() == SqlType.Sqlite + ? (IQueryBuilder) new SqliteQueryCreator() + : new MysqlQueryCreator()); + creator.EnsureExists(table); - String file = Path.Combine(TShock.SavePath, "bans.txt"); - if (File.Exists(file)) - { - using (StreamReader sr = new StreamReader(file)) - { - String line; - while ((line = sr.ReadLine()) != null) - { - String[] info = line.Split('|'); - string query; - if (TShock.Config.StorageType.ToLower() == "sqlite") - query = "INSERT OR IGNORE INTO Bans (IP, Name, Reason) VALUES (@0, @1, @2);"; - else - query = "INSERT IGNORE INTO Bans SET IP=@0, Name=@1, Reason=@2;"; - db.Query(query, info[0].Trim(), info[1].Trim(), info[2].Trim()); - } - } - String path = Path.Combine(TShock.SavePath, "old_configs"); - String file2 = Path.Combine(path, "bans.txt"); - if (!Directory.Exists(path)) - Directory.CreateDirectory(path); - if (File.Exists(file2)) - File.Delete(file2); - File.Move(file, file2); - } - } + String file = Path.Combine(TShock.SavePath, "bans.txt"); + if (File.Exists(file)) + { + using (StreamReader sr = new StreamReader(file)) + { + String line; + while ((line = sr.ReadLine()) != null) + { + String[] info = line.Split('|'); + string query; + if (TShock.Config.StorageType.ToLower() == "sqlite") + query = "INSERT OR IGNORE INTO Bans (IP, Name, Reason) VALUES (@0, @1, @2);"; + else + query = "INSERT IGNORE INTO Bans SET IP=@0, Name=@1, Reason=@2;"; + db.Query(query, info[0].Trim(), info[1].Trim(), info[2].Trim()); + } + } + String path = Path.Combine(TShock.SavePath, "old_configs"); + String file2 = Path.Combine(path, "bans.txt"); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + if (File.Exists(file2)) + File.Delete(file2); + File.Move(file, file2); + } + } - public Ban GetBanByIp(string ip) - { - try - { - using (var reader = database.QueryReader("SELECT * FROM Bans WHERE IP=@0", ip)) - { - if (reader.Read()) - return new Ban(reader.Get("IP"), reader.Get("Name"), reader.Get("Reason")); - } - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return null; - } + public Ban GetBanByIp(string ip) + { + try + { + using (var reader = database.QueryReader("SELECT * FROM Bans WHERE IP=@0", ip)) + { + if (reader.Read()) + return new Ban(reader.Get("IP"), reader.Get("Name"), reader.Get("Reason")); + } + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return null; + } - public Ban GetBanByName(string name, bool casesensitive = true) - { - if (!TShock.Config.EnableBanOnUsernames) - { - return null; - } - try - { - var namecol = casesensitive ? "Name" : "UPPER(Name)"; - if (!casesensitive) - name = name.ToUpper(); - using (var reader = database.QueryReader("SELECT * FROM Bans WHERE " + namecol + "=@0", name)) - { - if (reader.Read()) - return new Ban(reader.Get("IP"), reader.Get("Name"), reader.Get("Reason")); + public Ban GetBanByName(string name, bool casesensitive = true) + { + if (!TShock.Config.EnableBanOnUsernames) + { + return null; + } + try + { + var namecol = casesensitive ? "Name" : "UPPER(Name)"; + if (!casesensitive) + name = name.ToUpper(); + using (var reader = database.QueryReader("SELECT * FROM Bans WHERE " + namecol + "=@0", name)) + { + if (reader.Read()) + return new Ban(reader.Get("IP"), reader.Get("Name"), reader.Get("Reason")); + } + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return null; + } - } - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return null; - } + public bool AddBan(string ip, string name = "", string reason = "") + { + try + { + return database.Query("INSERT INTO Bans (IP, Name, Reason) VALUES (@0, @1, @2);", ip, name, reason) != 0; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; + } - public bool AddBan(string ip, string name = "", string reason = "") - { - try - { - return database.Query("INSERT INTO Bans (IP, Name, Reason) VALUES (@0, @1, @2);", ip, name, reason) != 0; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return false; - } + public bool RemoveBan(string ip) + { + try + { + return database.Query("DELETE FROM Bans WHERE IP=@0", ip) != 0; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; + } - public bool RemoveBan(string ip) - { - try - { - return database.Query("DELETE FROM Bans WHERE IP=@0", ip) != 0; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return false; - } - public bool ClearBans() - { - try - { - return database.Query("DELETE FROM Bans") != 0; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return false; - } - } + public bool ClearBans() + { + try + { + return database.Query("DELETE FROM Bans") != 0; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; + } + } - public class Ban - { - public string IP { get; set; } + public class Ban + { + public string IP { get; set; } - public string Name { get; set; } + public string Name { get; set; } - public string Reason { get; set; } + public string Reason { get; set; } - public Ban(string ip, string name, string reason) - { - IP = ip; - Name = name; - Reason = reason; - } + public Ban(string ip, string name, string reason) + { + IP = ip; + Name = name; + Reason = reason; + } - public Ban() - { - IP = string.Empty; - Name = string.Empty; - Reason = string.Empty; - } - } + public Ban() + { + IP = string.Empty; + Name = string.Empty; + Reason = string.Empty; + } + } } \ No newline at end of file diff --git a/TShockAPI/DB/GroupManager.cs b/TShockAPI/DB/GroupManager.cs index 42ac4294..763d4e29 100644 --- a/TShockAPI/DB/GroupManager.cs +++ b/TShockAPI/DB/GroupManager.cs @@ -7,254 +7,258 @@ using MySql.Data.MySqlClient; namespace TShockAPI.DB { - public class GroupManager - { - private IDbConnection database; + public class GroupManager + { + private IDbConnection database; - public List groups = new List(); + public List groups = new List(); - public GroupManager(IDbConnection db) - { - database = db; + public GroupManager(IDbConnection db) + { + database = db; - var table = new SqlTable("GroupList", - new SqlColumn("GroupName", MySqlDbType.VarChar, 32) { Primary = true }, - new SqlColumn("Parent", MySqlDbType.VarChar, 32), - new SqlColumn("Commands", MySqlDbType.Text), - new SqlColumn("ChatColor", MySqlDbType.Text), - new SqlColumn("Prefix", MySqlDbType.Text), - new SqlColumn("Suffix", MySqlDbType.Text) - ); - var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator()); - creator.EnsureExists(table); + var table = new SqlTable("GroupList", + new SqlColumn("GroupName", MySqlDbType.VarChar, 32) {Primary = true}, + new SqlColumn("Parent", MySqlDbType.VarChar, 32), + new SqlColumn("Commands", MySqlDbType.Text), + new SqlColumn("ChatColor", MySqlDbType.Text), + new SqlColumn("Prefix", MySqlDbType.Text), + new SqlColumn("Suffix", MySqlDbType.Text) + ); + var creator = new SqlTableCreator(db, + db.GetSqlType() == SqlType.Sqlite + ? (IQueryBuilder) new SqliteQueryCreator() + : new MysqlQueryCreator()); + creator.EnsureExists(table); - //Add default groups - AddGroup("guest", "canbuild,canregister,canlogin,canpartychat,cantalkinthird"); - AddGroup("default", "guest", "warp,canchangepassword"); - AddGroup("newadmin", "default", "kick,editspawn,reservedslot"); - AddGroup("admin", "newadmin", "ban,unban,whitelist,causeevents,spawnboss,spawnmob,managewarp,time,tp,pvpfun,kill,logs,immunetokick,tphere"); - AddGroup("trustedadmin", "admin", "maintenance,cfg,butcher,item,heal,immunetoban,usebanneditem,manageusers"); - AddGroup("vip", "default", "reservedslot"); + //Add default groups + AddGroup("guest", "canbuild,canregister,canlogin,canpartychat,cantalkinthird"); + AddGroup("default", "guest", "warp,canchangepassword"); + AddGroup("newadmin", "default", "kick,editspawn,reservedslot"); + AddGroup("admin", "newadmin", + "ban,unban,whitelist,causeevents,spawnboss,spawnmob,managewarp,time,tp,pvpfun,kill,logs,immunetokick,tphere"); + AddGroup("trustedadmin", "admin", "maintenance,cfg,butcher,item,heal,immunetoban,usebanneditem,manageusers"); + AddGroup("vip", "default", "reservedslot"); - String file = Path.Combine(TShock.SavePath, "groups.txt"); - if (File.Exists(file)) - { - using (StreamReader sr = new StreamReader(file)) - { - String line; - while ((line = sr.ReadLine()) != null) - { - if (!line.Equals("") && !line.Substring(0, 1).Equals("#")) - { - String[] info = line.Split(' '); - String comms = ""; - int size = info.Length; - for (int i = 1; i < size; i++) - { - if (!comms.Equals("")) - comms = comms + ","; - comms = comms + info[i].Trim(); - } + String file = Path.Combine(TShock.SavePath, "groups.txt"); + if (File.Exists(file)) + { + using (StreamReader sr = new StreamReader(file)) + { + String line; + while ((line = sr.ReadLine()) != null) + { + if (!line.Equals("") && !line.Substring(0, 1).Equals("#")) + { + String[] info = line.Split(' '); + String comms = ""; + int size = info.Length; + for (int i = 1; i < size; i++) + { + if (!comms.Equals("")) + comms = comms + ","; + comms = comms + info[i].Trim(); + } - string query = ""; - if (TShock.Config.StorageType.ToLower() == "sqlite") - query = "INSERT OR IGNORE INTO GroupList (GroupName, Commands) VALUES (@0, @1);"; - else if (TShock.Config.StorageType.ToLower() == "mysql") - query = "INSERT IGNORE INTO GroupList SET GroupName=@0, Commands=@1;"; + string query = ""; + if (TShock.Config.StorageType.ToLower() == "sqlite") + query = "INSERT OR IGNORE INTO GroupList (GroupName, Commands) VALUES (@0, @1);"; + else if (TShock.Config.StorageType.ToLower() == "mysql") + query = "INSERT IGNORE INTO GroupList SET GroupName=@0, Commands=@1;"; - db.Query(query, info[0].Trim(), comms); - - } - } - } - String path = Path.Combine(TShock.SavePath, "old_configs"); - String file2 = Path.Combine(path, "groups.txt"); - if (!Directory.Exists(path)) - Directory.CreateDirectory(path); - if (File.Exists(file2)) - File.Delete(file2); - File.Move(file, file2); - } - - } + db.Query(query, info[0].Trim(), comms); + } + } + } + String path = Path.Combine(TShock.SavePath, "old_configs"); + String file2 = Path.Combine(path, "groups.txt"); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + if (File.Exists(file2)) + File.Delete(file2); + File.Move(file, file2); + } + } - public bool GroupExists(string group) - { - if (group == "superadmin") - return true; + public bool GroupExists(string group) + { + if (group == "superadmin") + return true; - return groups.Any(g => g.Name.Equals(group)); - } + return groups.Any(g => g.Name.Equals(group)); + } - /// - /// Adds group with name and permissions if it does not exist. - /// - /// name of group - /// parent of group - /// permissions - public String AddGroup(String name, string parentname, String permissions, String chatcolor) - { - String message = ""; - if (GroupExists(name)) - return "Error: Group already exists. Use /modGroup to change permissions."; + /// + /// Adds group with name and permissions if it does not exist. + /// + /// name of group + /// parent of group + /// permissions + public String AddGroup(String name, string parentname, String permissions, String chatcolor) + { + String message = ""; + if (GroupExists(name)) + return "Error: Group already exists. Use /modGroup to change permissions."; - var group = new Group(name, null, chatcolor); - group.permissions.Add(permissions); - if (!string.IsNullOrWhiteSpace(parentname)) - { - var parent = groups.FirstOrDefault(gp => gp.Name == parentname); - if (parent == null) - { - var error = "Invalid parent {0} for group {1}".SFormat(group.Name, parentname); - Log.ConsoleError(error); - return error; - } - group.Parent = parent; - } + var group = new Group(name, null, chatcolor); + group.permissions.Add(permissions); + if (!string.IsNullOrWhiteSpace(parentname)) + { + var parent = groups.FirstOrDefault(gp => gp.Name == parentname); + if (parent == null) + { + var error = "Invalid parent {0} for group {1}".SFormat(group.Name, parentname); + Log.ConsoleError(error); + return error; + } + group.Parent = parent; + } - string query = (TShock.Config.StorageType.ToLower() == "sqlite") ? - "INSERT OR IGNORE INTO GroupList (GroupName, Parent, Commands, ChatColor) VALUES (@0, @1, @2, @3);" : - "INSERT IGNORE INTO GroupList SET GroupName=@0, Parent=@1, Commands=@2, ChatColor=@3"; - if (database.Query(query, name, parentname, permissions, chatcolor) == 1) - message = "Group " + name + " has been created successfully."; + string query = (TShock.Config.StorageType.ToLower() == "sqlite") + ? "INSERT OR IGNORE INTO GroupList (GroupName, Parent, Commands, ChatColor) VALUES (@0, @1, @2, @3);" + : "INSERT IGNORE INTO GroupList SET GroupName=@0, Parent=@1, Commands=@2, ChatColor=@3"; + if (database.Query(query, name, parentname, permissions, chatcolor) == 1) + message = "Group " + name + " has been created successfully."; - groups.Add(group); + groups.Add(group); - return message; - } - public String AddGroup(String name, String permissions) - { - return AddGroup(name, "", permissions, "255,255,255"); - } - public String AddGroup(String name, string parent, String permissions) - { - return AddGroup(name, parent, permissions, "255,255,255"); - } + return message; + } - public String DeleteGroup(String name) - { - String message = ""; - if (!GroupExists(name)) - return "Error: Group doesn't exists."; + public String AddGroup(String name, String permissions) + { + return AddGroup(name, "", permissions, "255,255,255"); + } - if (database.Query("DELETE FROM GroupList WHERE GroupName=@0", name) == 1) - message = "Group " + name + " has been deleted successfully."; - groups.Remove(TShock.Utils.GetGroup(name)); + public String AddGroup(String name, string parent, String permissions) + { + return AddGroup(name, parent, permissions, "255,255,255"); + } - return message; - } + public String DeleteGroup(String name) + { + String message = ""; + if (!GroupExists(name)) + return "Error: Group doesn't exists."; - public String AddPermissions(String name, List permissions) - { - String message = ""; - if (!GroupExists(name)) - return "Error: Group doesn't exists."; + if (database.Query("DELETE FROM GroupList WHERE GroupName=@0", name) == 1) + message = "Group " + name + " has been deleted successfully."; + groups.Remove(TShock.Utils.GetGroup(name)); - var group = TShock.Utils.GetGroup(name); - //Add existing permissions (without duplicating) - permissions.AddRange(group.permissions.Where(s => !permissions.Contains(s))); + return message; + } - if (database.Query("UPDATE GroupList SET Commands=@0 WHERE GroupName=@1", String.Join(",", permissions), name) != 0) - { - message = "Group " + name + " has been modified successfully."; - group.SetPermission( permissions ); - } - return message; - } + public String AddPermissions(String name, List permissions) + { + String message = ""; + if (!GroupExists(name)) + return "Error: Group doesn't exists."; - public String DeletePermissions(String name, List permissions) - { - String message = ""; - if (!GroupExists(name)) - return "Error: Group doesn't exists."; + var group = TShock.Utils.GetGroup(name); + //Add existing permissions (without duplicating) + permissions.AddRange(group.permissions.Where(s => !permissions.Contains(s))); - var group = TShock.Utils.GetGroup(name); + if (database.Query("UPDATE GroupList SET Commands=@0 WHERE GroupName=@1", String.Join(",", permissions), name) != 0) + { + message = "Group " + name + " has been modified successfully."; + group.SetPermission(permissions); + } + return message; + } - //Only get permissions that exist in the group. - var newperms = group.permissions.Except( permissions ); + public String DeletePermissions(String name, List permissions) + { + String message = ""; + if (!GroupExists(name)) + return "Error: Group doesn't exists."; - if (database.Query("UPDATE GroupList SET Commands=@0 WHERE GroupName=@1", String.Join(",", newperms), name) != 0) - { - message = "Group " + name + " has been modified successfully."; - group.SetPermission( newperms.ToList() ); - } - return message; - } + var group = TShock.Utils.GetGroup(name); - public void LoadPermisions() - { - //Create a temporary list so if there is an error it doesn't override the currently loaded groups with broken groups. - var tempgroups = new List(); - tempgroups.Add(new SuperAdminGroup()); + //Only get permissions that exist in the group. + var newperms = group.permissions.Except(permissions); - if (groups == null || groups.Count < 2) - groups = tempgroups; + if (database.Query("UPDATE GroupList SET Commands=@0 WHERE GroupName=@1", String.Join(",", newperms), name) != 0) + { + message = "Group " + name + " has been modified successfully."; + group.SetPermission(newperms.ToList()); + } + return message; + } - try - { - var groupsparents = new List>(); - using (var reader = database.QueryReader("SELECT * FROM GroupList")) - { - while (reader.Read()) - { - string groupname = reader.Get("GroupName"); - var group = new Group(groupname); + public void LoadPermisions() + { + //Create a temporary list so if there is an error it doesn't override the currently loaded groups with broken groups. + var tempgroups = new List(); + tempgroups.Add(new SuperAdminGroup()); - group.Prefix = reader.Get("Prefix"); - group.Suffix= reader.Get("Suffix"); + if (groups == null || groups.Count < 2) + groups = tempgroups; - //Inherit Given commands - String[] commands = reader.Get("Commands").Split(','); - foreach (var t in commands) - { - var str = t.Trim(); - if (str.StartsWith("!")) - { - group.NegatePermission(str.Substring(1)); - } - else - { - group.AddPermission(str); - } - } - String[] chatcolour = (reader.Get("ChatColor") ?? "").Split(','); - if (chatcolour.Length == 3) - { - byte.TryParse(chatcolour[0], out group.R); - byte.TryParse(chatcolour[1], out group.G); - byte.TryParse(chatcolour[2], out group.B); - } + try + { + var groupsparents = new List>(); + using (var reader = database.QueryReader("SELECT * FROM GroupList")) + { + while (reader.Read()) + { + string groupname = reader.Get("GroupName"); + var group = new Group(groupname); - groupsparents.Add(Tuple.Create(group, reader.Get("Parent"))); - } - } + group.Prefix = reader.Get("Prefix"); + group.Suffix = reader.Get("Suffix"); - foreach (var t in groupsparents) - { - var group = t.Item1; - var parentname = t.Item2; - if (!string.IsNullOrWhiteSpace(parentname)) - { - var parent = groupsparents.FirstOrDefault(gp => gp.Item1.Name == parentname); - if (parent == null) - { - Log.ConsoleError("Invalid parent {0} for group {1}".SFormat(group.Name, parentname)); - return; - } - group.Parent = parent.Item1; - } - tempgroups.Add(group); - } + //Inherit Given commands + String[] commands = reader.Get("Commands").Split(','); + foreach (var t in commands) + { + var str = t.Trim(); + if (str.StartsWith("!")) + { + group.NegatePermission(str.Substring(1)); + } + else + { + group.AddPermission(str); + } + } + String[] chatcolour = (reader.Get("ChatColor") ?? "").Split(','); + if (chatcolour.Length == 3) + { + byte.TryParse(chatcolour[0], out group.R); + byte.TryParse(chatcolour[1], out group.G); + byte.TryParse(chatcolour[2], out group.B); + } + + groupsparents.Add(Tuple.Create(group, reader.Get("Parent"))); + } + } + + foreach (var t in groupsparents) + { + var group = t.Item1; + var parentname = t.Item2; + if (!string.IsNullOrWhiteSpace(parentname)) + { + var parent = groupsparents.FirstOrDefault(gp => gp.Item1.Name == parentname); + if (parent == null) + { + Log.ConsoleError("Invalid parent {0} for group {1}".SFormat(group.Name, parentname)); + return; + } + group.Parent = parent.Item1; + } + tempgroups.Add(group); + } - groups = tempgroups; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } - } -} + groups = tempgroups; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } + } +} \ No newline at end of file diff --git a/TShockAPI/DB/IQueryBuilder.cs b/TShockAPI/DB/IQueryBuilder.cs index 3ca1d3de..e45a77e1 100644 --- a/TShockAPI/DB/IQueryBuilder.cs +++ b/TShockAPI/DB/IQueryBuilder.cs @@ -7,42 +7,55 @@ using TShockAPI.Extensions; namespace TShockAPI.DB { - public interface IQueryBuilder - { - string CreateTable(SqlTable table); - string AlterTable(SqlTable from, SqlTable to); - string DbTypeToString(MySqlDbType type, int? length); - string UpdateValue(string table, List values, List wheres); - string InsertValues(string table, List values); - string ReadColumn(string table, List wheres); - string DeleteRow(string table, List wheres); - } + public interface IQueryBuilder + { + string CreateTable(SqlTable table); + string AlterTable(SqlTable from, SqlTable to); + string DbTypeToString(MySqlDbType type, int? length); + string UpdateValue(string table, List values, List wheres); + string InsertValues(string table, List values); + string ReadColumn(string table, List wheres); + string DeleteRow(string table, List wheres); + } - public class SqliteQueryCreator : IQueryBuilder - { - public string CreateTable(SqlTable table) - { - var columns = table.Columns.Select(c => "'{0}' {1} {2} {3} {4}".SFormat(c.Name, DbTypeToString(c.Type, c.Length), c.Primary ? "PRIMARY KEY" : "", c.AutoIncrement ? "AUTOINCREMENT" : "", c.NotNull ? "NOT NULL" : "", c.Unique ? "UNIQUE" : "")); - return "CREATE TABLE '{0}' ({1})".SFormat(table.Name, string.Join(", ", columns)); - } - static Random rand = new Random(); - /// - /// Alter a table from source to destination - /// - /// Must have name and column names. Column types are not required - /// Must have column names and column types. - /// - public string AlterTable(SqlTable from, SqlTable to) - { - var rstr = rand.NextString(20); - var alter = "ALTER TABLE '{0}' RENAME TO '{1}_{0}'".SFormat(from.Name, rstr); - var create = CreateTable(to); - //combine all columns in the 'from' variable excluding ones that aren't in the 'to' variable. - //exclude the ones that aren't in 'to' variable because if the column is deleted, why try to import the data? - var insert = "INSERT INTO '{0}' ({1}) SELECT {1} FROM {2}_{0}".SFormat(from.Name, string.Join(", ", from.Columns.Where(c => to.Columns.Any(c2 => c2.Name == c.Name)).Select(c => c.Name)), rstr); - var drop = "DROP TABLE '{0}_{1}'".SFormat(rstr, from.Name); - return "{0}; {1}; {2}; {3};".SFormat(alter, create, insert, drop); - /* + public class SqliteQueryCreator : IQueryBuilder + { + public string CreateTable(SqlTable table) + { + var columns = + table.Columns.Select( + c => + "'{0}' {1} {2} {3} {4}".SFormat(c.Name, DbTypeToString(c.Type, c.Length), c.Primary ? "PRIMARY KEY" : "", + c.AutoIncrement ? "AUTOINCREMENT" : "", c.NotNull ? "NOT NULL" : "", + c.Unique ? "UNIQUE" : "")); + return "CREATE TABLE '{0}' ({1})".SFormat(table.Name, string.Join(", ", columns)); + } + + private static Random rand = new Random(); + + /// + /// Alter a table from source to destination + /// + /// Must have name and column names. Column types are not required + /// Must have column names and column types. + /// + public string AlterTable(SqlTable from, SqlTable to) + { + var rstr = rand.NextString(20); + var alter = "ALTER TABLE '{0}' RENAME TO '{1}_{0}'".SFormat(from.Name, rstr); + var create = CreateTable(to); + //combine all columns in the 'from' variable excluding ones that aren't in the 'to' variable. + //exclude the ones that aren't in 'to' variable because if the column is deleted, why try to import the data? + var insert = "INSERT INTO '{0}' ({1}) SELECT {1} FROM {2}_{0}".SFormat(from.Name, + string.Join(", ", + from.Columns.Where( + c => + to.Columns.Any( + c2 => c2.Name == c.Name)).Select + (c => c.Name)), rstr); + var drop = "DROP TABLE '{0}_{1}'".SFormat(rstr, from.Name); + return "{0}; {1}; {2}; {3};".SFormat(alter, create, insert, drop); + /* ALTER TABLE "main"."Bans" RENAME TO "oXHFcGcd04oXHFcGcd04_Bans" CREATE TABLE "main"."Bans" ("IP" TEXT PRIMARY KEY ,"Name" TEXT) INSERT INTO "main"."Bans" SELECT "IP","Name" FROM "main"."oXHFcGcd04oXHFcGcd04_Bans" @@ -50,238 +63,264 @@ namespace TShockAPI.DB * * Twitchy - Oh. I get it! */ - } - public string DeleteRow(string table, List wheres) - { - var sbwheres = new StringBuilder(); - int count = 0; - foreach (SqlValue where in wheres) - { - sbwheres.Append(where.Name + "=" + where.Value); - if (count != wheres.Count - 1) - sbwheres.Append(" AND "); - count++; - } - if (wheres.Count > 0) - return "DELETE FROM '{0}' WHERE {1} ".SFormat(table, sbwheres.ToString()); - else - return "DELETE FROM '{0}'".SFormat(table, sbwheres.ToString()); - } - public string UpdateValue(string table, List values, List wheres) - { - var sbvalues = new StringBuilder(); - var sbwheres = new StringBuilder(); - int count = 0; - foreach (SqlValue value in values) - { - sbvalues.Append(value.Name + "=" + value.Value); - if (count != values.Count - 1) - sbvalues.Append(","); - count++; - } - count = 0; - foreach (SqlValue where in wheres) - { - sbwheres.Append(where.Name + "=" + where.Value); - if (count != wheres.Count - 1) - sbwheres.Append(" AND "); - count++; - } + } - if (wheres.Count > 0) - return "UPDATE '{0}' SET {1} WHERE {2}".SFormat(table, sbvalues.ToString(), sbwheres.ToString()); - else - return "UPDATE '{0}' SET {1}".SFormat(table, sbvalues.ToString()); - } - public string InsertValues(string table, List values) - { - var sbnames = new StringBuilder(); - var sbvalues = new StringBuilder(); - int count = 0; + public string DeleteRow(string table, List wheres) + { + var sbwheres = new StringBuilder(); + int count = 0; + foreach (SqlValue where in wheres) + { + sbwheres.Append(where.Name + "=" + where.Value); + if (count != wheres.Count - 1) + sbwheres.Append(" AND "); + count++; + } + if (wheres.Count > 0) + return "DELETE FROM '{0}' WHERE {1} ".SFormat(table, sbwheres.ToString()); + else + return "DELETE FROM '{0}'".SFormat(table, sbwheres.ToString()); + } - foreach (SqlValue name in values) - { - sbnames.Append(name.Name); + public string UpdateValue(string table, List values, List wheres) + { + var sbvalues = new StringBuilder(); + var sbwheres = new StringBuilder(); + int count = 0; + foreach (SqlValue value in values) + { + sbvalues.Append(value.Name + "=" + value.Value); + if (count != values.Count - 1) + sbvalues.Append(","); + count++; + } + count = 0; + foreach (SqlValue where in wheres) + { + sbwheres.Append(where.Name + "=" + where.Value); + if (count != wheres.Count - 1) + sbwheres.Append(" AND "); + count++; + } - if (count != values.Count - 1) - sbnames.Append(", "); - count++; - } - count = 0; - foreach (SqlValue value in values) - { - sbvalues.Append(value.Value.ToString()); - if (count != values.Count - 1) - sbvalues.Append(", "); - count++; - } - return "INSERT INTO '{0}' ({1}) VALUES ({2})".SFormat(table, sbnames.ToString(), sbvalues.ToString()); - } - public string ReadColumn(string table, List wheres) - { - var sbwheres = new StringBuilder(); - int count = 0; + if (wheres.Count > 0) + return "UPDATE '{0}' SET {1} WHERE {2}".SFormat(table, sbvalues.ToString(), sbwheres.ToString()); + else + return "UPDATE '{0}' SET {1}".SFormat(table, sbvalues.ToString()); + } - foreach (SqlValue where in wheres) - { - sbwheres.Append(where.Name + "=" + where.Value); - if (count != wheres.Count - 1) - sbwheres.Append(" AND "); - count++; - } + public string InsertValues(string table, List values) + { + var sbnames = new StringBuilder(); + var sbvalues = new StringBuilder(); + int count = 0; - if(wheres.Count > 0) - return "SELECT * FROM {0} WHERE {1}".SFormat(table, sbwheres.ToString()); - else - return "SELECT * FROM {0}".SFormat(table); - } + foreach (SqlValue name in values) + { + sbnames.Append(name.Name); - static readonly Dictionary TypesAsStrings = new Dictionary - { - {MySqlDbType.VarChar, "TEXT"}, - {MySqlDbType.String, "TEXT"}, - {MySqlDbType.Text, "TEXT"}, - {MySqlDbType.TinyText, "TEXT"}, - {MySqlDbType.MediumText, "TEXT"}, - {MySqlDbType.LongText, "TEXT"}, - {MySqlDbType.Int32, "INTEGER"}, - }; - public string DbTypeToString(MySqlDbType type, int? length) - { - string ret; - if (TypesAsStrings.TryGetValue(type, out ret)) - return ret; - throw new NotImplementedException(Enum.GetName(typeof(MySqlDbType), type)); - } - } - public class MysqlQueryCreator : IQueryBuilder - { - public string CreateTable(SqlTable table) - { - var columns = table.Columns.Select(c => "{0} {1} {2} {3}".SFormat(c.Name, DbTypeToString(c.Type, c.Length), c.Primary ? "PRIMARY KEY" : "", c.AutoIncrement ? "AUTO_INCREMENT" : "", c.NotNull ? "NOT NULL" : "")); - var uniques = table.Columns.Where(c => c.Unique).Select(c => c.Name); - return "CREATE TABLE {0} ({1} {2})".SFormat(table.Name, string.Join(", ", columns), uniques.Count() > 0 ? ", UNIQUE({0})".SFormat(string.Join(", ", uniques)) : ""); - } - static Random rand = new Random(); - /// - /// Alter a table from source to destination - /// - /// Must have name and column names. Column types are not required - /// Must have column names and column types. - /// - public string AlterTable(SqlTable from, SqlTable to) - { - var rstr = rand.NextString(20); - var alter = "RENAME TABLE {0} TO {1}_{0}".SFormat(from.Name, rstr); - var create = CreateTable(to); - //combine all columns in the 'from' variable excluding ones that aren't in the 'to' variable. - //exclude the ones that aren't in 'to' variable because if the column is deleted, why try to import the data? - var insert = "INSERT INTO {0} ({1}) SELECT {1} FROM {2}_{0}".SFormat(from.Name, string.Join(", ", from.Columns.Where(c => to.Columns.Any(c2 => c2.Name == c.Name)).Select(c => c.Name)), rstr); - var drop = "DROP TABLE {0}_{1}".SFormat(rstr, from.Name); - return "{0}; {1}; {2}; {3};".SFormat(alter, create, insert, drop); - } - public string DeleteRow(string table, List wheres) - { - var sbwheres = new StringBuilder(); - int count = 0; - foreach (SqlValue where in wheres) - { - sbwheres.Append(where.Name + "=" + where.Value); - if (count != wheres.Count - 1) - sbwheres.Append(" AND "); - count++; - } - if (wheres.Count > 0) - return "DELETE FROM {0} WHERE {1} ".SFormat(table, sbwheres.ToString()); - else - return "DELETE FROM {0}".SFormat(table, sbwheres.ToString()); - } - public string UpdateValue(string table, List values, List wheres) - { - var sbvalues = new StringBuilder(); - var sbwheres = new StringBuilder(); - int count = 0; - foreach (SqlValue value in values) - { - sbvalues.Append(value.Name + "=" + value.Value); - if (count != values.Count - 1) - sbvalues.Append("AND"); - count++; - } - count = 0; - foreach (SqlValue where in wheres) - { - sbwheres.Append(where.Name + "=" + where.Value); - if (count != wheres.Count - 1) - sbwheres.Append(" AND "); - count++; - } + if (count != values.Count - 1) + sbnames.Append(", "); + count++; + } + count = 0; + foreach (SqlValue value in values) + { + sbvalues.Append(value.Value.ToString()); + if (count != values.Count - 1) + sbvalues.Append(", "); + count++; + } + return "INSERT INTO '{0}' ({1}) VALUES ({2})".SFormat(table, sbnames.ToString(), sbvalues.ToString()); + } - if (wheres.Count > 0) - return "UPDATE {0} SET {1} WHERE {2}".SFormat(table, sbvalues.ToString(), sbwheres.ToString()); - else - return "UPDATE {0} SET {1}".SFormat(table, sbvalues.ToString()); - } - public string InsertValues(string table, List values) - { - var sbnames = new StringBuilder(); - var sbvalues = new StringBuilder(); - int count = 0; + public string ReadColumn(string table, List wheres) + { + var sbwheres = new StringBuilder(); + int count = 0; - foreach (SqlValue name in values) - { - sbnames.Append(name.Name); + foreach (SqlValue where in wheres) + { + sbwheres.Append(where.Name + "=" + where.Value); + if (count != wheres.Count - 1) + sbwheres.Append(" AND "); + count++; + } - if (count != values.Count - 1) - sbnames.Append(", "); - count++; - } - count = 0; - foreach (SqlValue value in values) - { - sbvalues.Append(value.Value.ToString()); - if (count != values.Count - 1) - sbvalues.Append(", "); - count++; - } + if (wheres.Count > 0) + return "SELECT * FROM {0} WHERE {1}".SFormat(table, sbwheres.ToString()); + else + return "SELECT * FROM {0}".SFormat(table); + } - return "INSERT INTO {0} ({1}) VALUES ({2})".SFormat(table, sbnames.ToString(), sbvalues.ToString()); - } - public string ReadColumn(string table, List wheres) - { - var sbwheres = new StringBuilder(); - int count = 0; + private static readonly Dictionary TypesAsStrings = new Dictionary + { + {MySqlDbType.VarChar, "TEXT"}, + {MySqlDbType.String, "TEXT"}, + {MySqlDbType.Text, "TEXT"}, + {MySqlDbType.TinyText, "TEXT"}, + {MySqlDbType.MediumText, "TEXT"}, + {MySqlDbType.LongText, "TEXT"}, + {MySqlDbType.Int32, "INTEGER"}, + }; - foreach (SqlValue where in wheres) - { - sbwheres.Append(where.Name + "=" + where.Value); - if (count != wheres.Count - 1) - sbwheres.Append(" AND "); - count++; - } + public string DbTypeToString(MySqlDbType type, int? length) + { + string ret; + if (TypesAsStrings.TryGetValue(type, out ret)) + return ret; + throw new NotImplementedException(Enum.GetName(typeof (MySqlDbType), type)); + } + } - if (wheres.Count > 0) - return "SELECT * FROM {0} WHERE {1}".SFormat(table, sbwheres.ToString()); - else - return "SELECT * FROM {0}".SFormat(table); - } + public class MysqlQueryCreator : IQueryBuilder + { + public string CreateTable(SqlTable table) + { + var columns = + table.Columns.Select( + c => + "{0} {1} {2} {3}".SFormat(c.Name, DbTypeToString(c.Type, c.Length), c.Primary ? "PRIMARY KEY" : "", + c.AutoIncrement ? "AUTO_INCREMENT" : "", c.NotNull ? "NOT NULL" : "")); + var uniques = table.Columns.Where(c => c.Unique).Select(c => c.Name); + return "CREATE TABLE {0} ({1} {2})".SFormat(table.Name, string.Join(", ", columns), + uniques.Count() > 0 + ? ", UNIQUE({0})".SFormat(string.Join(", ", uniques)) + : ""); + } - static readonly Dictionary TypesAsStrings = new Dictionary - { - {MySqlDbType.VarChar, "VARCHAR"}, - {MySqlDbType.String, "CHAR"}, - {MySqlDbType.Text, "TEXT"}, - {MySqlDbType.TinyText, "TINYTEXT"}, - {MySqlDbType.MediumText, "MEDIUMTEXT"}, - {MySqlDbType.LongText, "LONGTEXT"}, - {MySqlDbType.Int32, "INT"}, - }; - public string DbTypeToString(MySqlDbType type, int? length) - { - string ret; - if (TypesAsStrings.TryGetValue(type, out ret)) - return ret + (length != null ? "({0})".SFormat((int)length) : ""); - throw new NotImplementedException(Enum.GetName(typeof(MySqlDbType), type)); - } - } -} + private static Random rand = new Random(); + + /// + /// Alter a table from source to destination + /// + /// Must have name and column names. Column types are not required + /// Must have column names and column types. + /// + public string AlterTable(SqlTable from, SqlTable to) + { + var rstr = rand.NextString(20); + var alter = "RENAME TABLE {0} TO {1}_{0}".SFormat(from.Name, rstr); + var create = CreateTable(to); + //combine all columns in the 'from' variable excluding ones that aren't in the 'to' variable. + //exclude the ones that aren't in 'to' variable because if the column is deleted, why try to import the data? + var insert = "INSERT INTO {0} ({1}) SELECT {1} FROM {2}_{0}".SFormat(from.Name, + string.Join(", ", + from.Columns.Where( + c => + to.Columns.Any( + c2 => c2.Name == c.Name)).Select( + c => c.Name)), rstr); + var drop = "DROP TABLE {0}_{1}".SFormat(rstr, from.Name); + return "{0}; {1}; {2}; {3};".SFormat(alter, create, insert, drop); + } + + public string DeleteRow(string table, List wheres) + { + var sbwheres = new StringBuilder(); + int count = 0; + foreach (SqlValue where in wheres) + { + sbwheres.Append(where.Name + "=" + where.Value); + if (count != wheres.Count - 1) + sbwheres.Append(" AND "); + count++; + } + if (wheres.Count > 0) + return "DELETE FROM {0} WHERE {1} ".SFormat(table, sbwheres.ToString()); + else + return "DELETE FROM {0}".SFormat(table, sbwheres.ToString()); + } + + public string UpdateValue(string table, List values, List wheres) + { + var sbvalues = new StringBuilder(); + var sbwheres = new StringBuilder(); + int count = 0; + foreach (SqlValue value in values) + { + sbvalues.Append(value.Name + "=" + value.Value); + if (count != values.Count - 1) + sbvalues.Append("AND"); + count++; + } + count = 0; + foreach (SqlValue where in wheres) + { + sbwheres.Append(where.Name + "=" + where.Value); + if (count != wheres.Count - 1) + sbwheres.Append(" AND "); + count++; + } + + if (wheres.Count > 0) + return "UPDATE {0} SET {1} WHERE {2}".SFormat(table, sbvalues.ToString(), sbwheres.ToString()); + else + return "UPDATE {0} SET {1}".SFormat(table, sbvalues.ToString()); + } + + public string InsertValues(string table, List values) + { + var sbnames = new StringBuilder(); + var sbvalues = new StringBuilder(); + int count = 0; + + foreach (SqlValue name in values) + { + sbnames.Append(name.Name); + + if (count != values.Count - 1) + sbnames.Append(", "); + count++; + } + count = 0; + foreach (SqlValue value in values) + { + sbvalues.Append(value.Value.ToString()); + if (count != values.Count - 1) + sbvalues.Append(", "); + count++; + } + + return "INSERT INTO {0} ({1}) VALUES ({2})".SFormat(table, sbnames.ToString(), sbvalues.ToString()); + } + + public string ReadColumn(string table, List wheres) + { + var sbwheres = new StringBuilder(); + int count = 0; + + foreach (SqlValue where in wheres) + { + sbwheres.Append(where.Name + "=" + where.Value); + if (count != wheres.Count - 1) + sbwheres.Append(" AND "); + count++; + } + + if (wheres.Count > 0) + return "SELECT * FROM {0} WHERE {1}".SFormat(table, sbwheres.ToString()); + else + return "SELECT * FROM {0}".SFormat(table); + } + + private static readonly Dictionary TypesAsStrings = new Dictionary + { + {MySqlDbType.VarChar, "VARCHAR"}, + {MySqlDbType.String, "CHAR"}, + {MySqlDbType.Text, "TEXT"}, + {MySqlDbType.TinyText, "TINYTEXT"}, + {MySqlDbType.MediumText, "MEDIUMTEXT"}, + {MySqlDbType.LongText, "LONGTEXT"}, + {MySqlDbType.Int32, "INT"}, + }; + + public string DbTypeToString(MySqlDbType type, int? length) + { + string ret; + if (TypesAsStrings.TryGetValue(type, out ret)) + return ret + (length != null ? "({0})".SFormat((int) length) : ""); + throw new NotImplementedException(Enum.GetName(typeof (MySqlDbType), type)); + } + } +} \ No newline at end of file diff --git a/TShockAPI/DB/InventoryManager.cs b/TShockAPI/DB/InventoryManager.cs index 97feb6b4..623e9834 100644 --- a/TShockAPI/DB/InventoryManager.cs +++ b/TShockAPI/DB/InventoryManager.cs @@ -22,81 +22,86 @@ using MySql.Data.MySqlClient; namespace TShockAPI.DB { - public class InventoryManager - { - public IDbConnection database; + public class InventoryManager + { + public IDbConnection database; - public InventoryManager(IDbConnection db) - { - database = db; + public InventoryManager(IDbConnection db) + { + database = db; - var table = new SqlTable("Inventory", - new SqlColumn("Account", MySqlDbType.Int32) { Primary = true }, - new SqlColumn("MaxHealth", MySqlDbType.Int32), - new SqlColumn("MaxMana", MySqlDbType.Int32), - new SqlColumn("Inventory", MySqlDbType.Text) - ); - var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator()); - creator.EnsureExists(table); - } + var table = new SqlTable("Inventory", + new SqlColumn("Account", MySqlDbType.Int32) {Primary = true}, + new SqlColumn("MaxHealth", MySqlDbType.Int32), + new SqlColumn("MaxMana", MySqlDbType.Int32), + new SqlColumn("Inventory", MySqlDbType.Text) + ); + var creator = new SqlTableCreator(db, + db.GetSqlType() == SqlType.Sqlite + ? (IQueryBuilder) new SqliteQueryCreator() + : new MysqlQueryCreator()); + creator.EnsureExists(table); + } - public PlayerData GetPlayerData(TSPlayer player, int acctid) - { - PlayerData playerData = new PlayerData(player); + public PlayerData GetPlayerData(TSPlayer player, int acctid) + { + PlayerData playerData = new PlayerData(player); - try - { - using (var reader = database.QueryReader("SELECT * FROM Inventory WHERE Account=@0", acctid)) - { - if (reader.Read()) - { - playerData.exists = true; - playerData.maxHealth = reader.Get("MaxHealth"); - playerData.inventory = NetItem.Parse(reader.Get("Inventory")); - return playerData; - } - } - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } + try + { + using (var reader = database.QueryReader("SELECT * FROM Inventory WHERE Account=@0", acctid)) + { + if (reader.Read()) + { + playerData.exists = true; + playerData.maxHealth = reader.Get("MaxHealth"); + playerData.inventory = NetItem.Parse(reader.Get("Inventory")); + return playerData; + } + } + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } - return playerData; - } + return playerData; + } - public bool InsertPlayerData(TSPlayer player) - { - PlayerData playerData = player.PlayerData; + public bool InsertPlayerData(TSPlayer player) + { + PlayerData playerData = player.PlayerData; - if (!player.IsLoggedIn) - return false; + if (!player.IsLoggedIn) + return false; - if (!GetPlayerData(player, player.UserID).exists) - { - try - { - database.Query("INSERT INTO Inventory (Account, MaxHealth, Inventory) VALUES (@0, @1, @2);", player.UserID, playerData.maxHealth, NetItem.ToString(playerData.inventory)); - return true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } - else - { - try - { - database.Query("UPDATE Inventory SET MaxHealth = @0, Inventory = @1 WHERE Account = @2;", playerData.maxHealth, NetItem.ToString(playerData.inventory), player.UserID); - return true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } - return false; - } - } -} + if (!GetPlayerData(player, player.UserID).exists) + { + try + { + database.Query("INSERT INTO Inventory (Account, MaxHealth, Inventory) VALUES (@0, @1, @2);", player.UserID, + playerData.maxHealth, NetItem.ToString(playerData.inventory)); + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } + else + { + try + { + database.Query("UPDATE Inventory SET MaxHealth = @0, Inventory = @1 WHERE Account = @2;", playerData.maxHealth, + NetItem.ToString(playerData.inventory), player.UserID); + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } + return false; + } + } +} \ No newline at end of file diff --git a/TShockAPI/DB/ItemManager.cs b/TShockAPI/DB/ItemManager.cs index 4827c4a3..f1ef8d67 100644 --- a/TShockAPI/DB/ItemManager.cs +++ b/TShockAPI/DB/ItemManager.cs @@ -7,119 +7,122 @@ using MySql.Data.MySqlClient; namespace TShockAPI.DB { - public class ItemManager - { - private IDbConnection database; + public class ItemManager + { + private IDbConnection database; public List ItemBans = new List(); - public ItemManager(IDbConnection db) - { - database = db; + public ItemManager(IDbConnection db) + { + database = db; - var table = new SqlTable("ItemBans", - new SqlColumn("ItemName", MySqlDbType.VarChar, 50) { Primary = true }, - new SqlColumn("AllowedGroups", MySqlDbType.Text ) - ); - var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator()); - creator.EnsureExists(table); + var table = new SqlTable("ItemBans", + new SqlColumn("ItemName", MySqlDbType.VarChar, 50) {Primary = true}, + new SqlColumn("AllowedGroups", MySqlDbType.Text) + ); + var creator = new SqlTableCreator(db, + db.GetSqlType() == SqlType.Sqlite + ? (IQueryBuilder) new SqliteQueryCreator() + : new MysqlQueryCreator()); + creator.EnsureExists(table); - String file = Path.Combine(TShock.SavePath, "itembans.txt"); - if (File.Exists(file)) - { - using (StreamReader sr = new StreamReader(file)) - { - String line; - while ((line = sr.ReadLine()) != null) - { - if (!line.Equals("") && !line.Substring(0, 1).Equals("#")) - { + String file = Path.Combine(TShock.SavePath, "itembans.txt"); + if (File.Exists(file)) + { + using (StreamReader sr = new StreamReader(file)) + { + String line; + while ((line = sr.ReadLine()) != null) + { + if (!line.Equals("") && !line.Substring(0, 1).Equals("#")) + { + string query = (TShock.Config.StorageType.ToLower() == "sqlite") + ? "INSERT OR IGNORE INTO 'ItemBans' (ItemName, AllowedGroups) VALUES (@0, @1);" + : "INSERT IGNORE INTO ItemBans SET ItemName=@0,AllowedGroups=@1 ;"; - string query = (TShock.Config.StorageType.ToLower() == "sqlite") ? - "INSERT OR IGNORE INTO 'ItemBans' (ItemName, AllowedGroups) VALUES (@0, @1);" : - "INSERT IGNORE INTO ItemBans SET ItemName=@0,AllowedGroups=@1 ;"; + int id = 0; + int.TryParse(line, out id); - int id = 0; - int.TryParse(line, out id); + database.Query(query, TShock.Utils.GetItemById(id).name, ""); + } + } + } - database.Query(query, TShock.Utils.GetItemById(id).name, ""); - } - } - } + String path = Path.Combine(TShock.SavePath, "old_configs"); + String file2 = Path.Combine(path, "itembans.txt"); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + if (File.Exists(file2)) + File.Delete(file2); + File.Move(file, file2); + } - String path = Path.Combine(TShock.SavePath, "old_configs"); - String file2 = Path.Combine(path, "itembans.txt"); - if (!Directory.Exists(path)) - Directory.CreateDirectory(path); - if (File.Exists(file2)) - File.Delete(file2); - File.Move(file, file2); - } + UpdateItemBans(); + } - UpdateItemBans(); - } + public void UpdateItemBans() + { + ItemBans.Clear(); - public void UpdateItemBans() - { - ItemBans.Clear(); - - using (var reader = database.QueryReader("SELECT * FROM ItemBans")) - { - while (reader != null && reader.Read()) - { + using (var reader = database.QueryReader("SELECT * FROM ItemBans")) + { + while (reader != null && reader.Read()) + { ItemBan ban = new ItemBan(reader.Get("ItemName")); - ban.SetAllowedGroups( reader.Get("AllowedGroups") ); + ban.SetAllowedGroups(reader.Get("AllowedGroups")); ItemBans.Add(ban); - } - } - } + } + } + } - public void AddNewBan(string itemname = "") - { - try - { - database.Query("INSERT INTO ItemBans (ItemName, AllowedGroups) VALUES (@0, @1);", TShock.Utils.GetItemByName(itemname)[0].name, ""); - if (!ItemIsBanned(itemname, null)) - ItemBans.Add( new ItemBan(itemname) ); - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } + public void AddNewBan(string itemname = "") + { + try + { + database.Query("INSERT INTO ItemBans (ItemName, AllowedGroups) VALUES (@0, @1);", + TShock.Utils.GetItemByName(itemname)[0].name, ""); + if (!ItemIsBanned(itemname, null)) + ItemBans.Add(new ItemBan(itemname)); + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } - public void RemoveBan(string itemname) - { - if (!ItemIsBanned(itemname, null)) - return; - try - { - database.Query("Delete FROM 'ItemBans' WHERE ItemName=@0;", TShock.Utils.GetItemByName(itemname)[0].name); - ItemBans.Remove( new ItemBan(itemname) ); - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } + public void RemoveBan(string itemname) + { + if (!ItemIsBanned(itemname, null)) + return; + try + { + database.Query("Delete FROM 'ItemBans' WHERE ItemName=@0;", TShock.Utils.GetItemByName(itemname)[0].name); + ItemBans.Remove(new ItemBan(itemname)); + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } - public bool ItemIsBanned(string name) - { - if (ItemBans.Contains(new ItemBan(name))) - { - return true; - } - return false; - } + public bool ItemIsBanned(string name) + { + if (ItemBans.Contains(new ItemBan(name))) + { + return true; + } + return false; + } - public bool ItemIsBanned(string name, TSPlayer ply) - { - if (ItemBans.Contains( new ItemBan(name) ) ) + public bool ItemIsBanned(string name, TSPlayer ply) + { + if (ItemBans.Contains(new ItemBan(name))) { ItemBan b = GetItemBanByName(name); return !b.HasPermissionToUseItem(ply); } return false; - } + } public bool AllowGroup(string item, string name) { @@ -134,7 +137,7 @@ namespace TShockAPI.DB b.SetAllowedGroups(groupsNew); int q = database.Query("UPDATE ItemBans SET AllowedGroups=@0 WHERE ItemName=@1", groupsNew, - item); + item); return q > 0; } @@ -150,7 +153,7 @@ namespace TShockAPI.DB b.RemoveGroup(group); string groups = string.Join(",", b.AllowedGroups); int q = database.Query("UPDATE ItemBans SET AllowedGroups=@0 WHERE ItemName=@1", groups, - item); + item); if (q > 0) return true; } @@ -168,58 +171,58 @@ namespace TShockAPI.DB } return null; } - } + } public class ItemBan : IEquatable - { - public string Name { get; set; } + { + public string Name { get; set; } public List AllowedGroups { get; set; } - public ItemBan(string name) - : this() - { - Name = name; + public ItemBan(string name) + : this() + { + Name = name; AllowedGroups = new List(); - } + } - public ItemBan() - { - Name = ""; + public ItemBan() + { + Name = ""; AllowedGroups = new List(); - } + } public bool Equals(ItemBan other) { return Name == other.Name; } - public bool HasPermissionToUseItem(TSPlayer ply) - { + public bool HasPermissionToUseItem(TSPlayer ply) + { if (ply == null) return false; - return AllowedGroups.Contains(ply.Group.Name); // could add in the other permissions in this class instead of a giant if switch. - } - - public void SetAllowedGroups( String groups ) - { - // prevent null pointer exceptions - if (!string.IsNullOrEmpty(groups)) - { - List groupArr = groups.Split(',').ToList(); - - for (int i = 0; i < groupArr.Count; i++) - { - groupArr[i] = groupArr[i].Trim(); - Console.WriteLine(groupArr[i]); - } - AllowedGroups = groupArr; - } + return AllowedGroups.Contains(ply.Group.Name); + // could add in the other permissions in this class instead of a giant if switch. } - public bool RemoveGroup(string groupName) + public void SetAllowedGroups(String groups) + { + // prevent null pointer exceptions + if (!string.IsNullOrEmpty(groups)) + { + List groupArr = groups.Split(',').ToList(); + + for (int i = 0; i < groupArr.Count; i++) + { + groupArr[i] = groupArr[i].Trim(); + Console.WriteLine(groupArr[i]); + } + AllowedGroups = groupArr; + } + } + + public bool RemoveGroup(string groupName) { return AllowedGroups.Remove(groupName); } - } - -} + } +} \ No newline at end of file diff --git a/TShockAPI/DB/RegionManager.cs b/TShockAPI/DB/RegionManager.cs index 37bc2e78..63befa4a 100644 --- a/TShockAPI/DB/RegionManager.cs +++ b/TShockAPI/DB/RegionManager.cs @@ -28,527 +28,538 @@ using Terraria; namespace TShockAPI.DB { - public class RegionManager - { - public List Regions = new List(); + public class RegionManager + { + public List Regions = new List(); - private IDbConnection database; + private IDbConnection database; - public RegionManager(IDbConnection db) - { - database = db; - var table = new SqlTable("Regions", - new SqlColumn("X1", MySqlDbType.Int32), - new SqlColumn("Y1", MySqlDbType.Int32), - new SqlColumn("width", MySqlDbType.Int32), - new SqlColumn("height", MySqlDbType.Int32), - new SqlColumn("RegionName", MySqlDbType.VarChar, 50) { Primary = true }, - new SqlColumn("WorldID", MySqlDbType.Text), - new SqlColumn("UserIds", MySqlDbType.Text), - new SqlColumn("Protected", MySqlDbType.Int32), - new SqlColumn("Groups", MySqlDbType.Text), - new SqlColumn("Owner", MySqlDbType.VarChar, 50) + public RegionManager(IDbConnection db) + { + database = db; + var table = new SqlTable("Regions", + new SqlColumn("X1", MySqlDbType.Int32), + new SqlColumn("Y1", MySqlDbType.Int32), + new SqlColumn("width", MySqlDbType.Int32), + new SqlColumn("height", MySqlDbType.Int32), + new SqlColumn("RegionName", MySqlDbType.VarChar, 50) {Primary = true}, + new SqlColumn("WorldID", MySqlDbType.Text), + new SqlColumn("UserIds", MySqlDbType.Text), + new SqlColumn("Protected", MySqlDbType.Int32), + new SqlColumn("Groups", MySqlDbType.Text), + new SqlColumn("Owner", MySqlDbType.VarChar, 50) + ); + var creator = new SqlTableCreator(db, + db.GetSqlType() == SqlType.Sqlite + ? (IQueryBuilder) new SqliteQueryCreator() + : new MysqlQueryCreator()); + creator.EnsureExists(table); - ); - var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator()); - creator.EnsureExists(table); + ImportOld(); + ReloadAllRegions(); + } - ImportOld(); - ReloadAllRegions(); + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + public void ImportOld() + { + String file = Path.Combine(TShock.SavePath, "regions.xml"); + if (!File.Exists(file)) + return; - } + Region region; + Rectangle rect; - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] - public void ImportOld() - { - String file = Path.Combine(TShock.SavePath, "regions.xml"); - if (!File.Exists(file)) - return; + using (var reader = XmlReader.Create(new StreamReader(file), new XmlReaderSettings {CloseInput = true})) + { + // Parse the file and display each of the nodes. + while (reader.Read()) + { + if (reader.NodeType != XmlNodeType.Element || reader.Name != "ProtectedRegion") + continue; - Region region; - Rectangle rect; + region = new Region(); + rect = new Rectangle(); - using (var reader = XmlReader.Create(new StreamReader(file), new XmlReaderSettings { CloseInput = true })) - { - // Parse the file and display each of the nodes. - while (reader.Read()) - { - if (reader.NodeType != XmlNodeType.Element || reader.Name != "ProtectedRegion") - continue; + bool endregion = false; + while (reader.Read() && !endregion) + { + if (reader.NodeType != XmlNodeType.Element) + continue; - region = new Region(); - rect = new Rectangle(); + string name = reader.Name; - bool endregion = false; - while (reader.Read() && !endregion) - { - if (reader.NodeType != XmlNodeType.Element) - continue; + while (reader.Read() && reader.NodeType != XmlNodeType.Text) ; - string name = reader.Name; + int t = 0; - while (reader.Read() && reader.NodeType != XmlNodeType.Text) ; + switch (name) + { + case "RegionName": + region.Name = reader.Value; + break; + case "Point1X": + int.TryParse(reader.Value, out t); + rect.X = t; + break; + case "Point1Y": + int.TryParse(reader.Value, out t); + rect.Y = t; + break; + case "Point2X": + int.TryParse(reader.Value, out t); + rect.Width = t; + break; + case "Point2Y": + int.TryParse(reader.Value, out t); + rect.Height = t; + break; + case "Protected": + region.DisableBuild = reader.Value.ToLower().Equals("true"); + break; + case "WorldName": + region.WorldID = reader.Value; + break; + case "AllowedUserCount": + break; + case "IP": + region.AllowedIDs.Add(int.Parse(reader.Value)); + break; + default: + endregion = true; + break; + } + } - int t = 0; + region.Area = rect; + string query = (TShock.Config.StorageType.ToLower() == "sqlite") + ? "INSERT OR IGNORE INTO Regions VALUES (@0, @1, @2, @3, @4, @5, @6, @7);" + : "INSERT IGNORE INTO Regions SET X1=@0, Y1=@1, height=@2, width=@3, RegionName=@4, WorldID=@5, UserIds=@6, Protected=@7;"; + database.Query(query, region.Area.X, region.Area.Y, region.Area.Width, region.Area.Height, region.Name, + region.WorldID, "", region.DisableBuild); - switch (name) - { - case "RegionName": - region.Name = reader.Value; - break; - case "Point1X": - int.TryParse(reader.Value, out t); - rect.X = t; - break; - case "Point1Y": - int.TryParse(reader.Value, out t); - rect.Y = t; - break; - case "Point2X": - int.TryParse(reader.Value, out t); - rect.Width = t; - break; - case "Point2Y": - int.TryParse(reader.Value, out t); - rect.Height = t; - break; - case "Protected": - region.DisableBuild = reader.Value.ToLower().Equals("true"); - break; - case "WorldName": - region.WorldID = reader.Value; - break; - case "AllowedUserCount": - break; - case "IP": - region.AllowedIDs.Add(int.Parse(reader.Value)); - break; - default: - endregion = true; - break; - } - } + //Todo: What should this be? We don't really have a way to go from ips to userids + /*string.Join(",", region.AllowedIDs)*/ + } + } - region.Area = rect; - string query = (TShock.Config.StorageType.ToLower() == "sqlite") ? - "INSERT OR IGNORE INTO Regions VALUES (@0, @1, @2, @3, @4, @5, @6, @7);" : - "INSERT IGNORE INTO Regions SET X1=@0, Y1=@1, height=@2, width=@3, RegionName=@4, WorldID=@5, UserIds=@6, Protected=@7;"; - database.Query(query, region.Area.X, region.Area.Y, region.Area.Width, region.Area.Height, region.Name, region.WorldID, "", region.DisableBuild); + String path = Path.Combine(TShock.SavePath, "old_configs"); + String file2 = Path.Combine(path, "regions.xml"); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + if (File.Exists(file2)) + File.Delete(file2); + File.Move(file, file2); - //Todo: What should this be? We don't really have a way to go from ips to userids - /*string.Join(",", region.AllowedIDs)*/ + ReloadAllRegions(); + } - } - } + public void ConvertDB() + { + try + { + database.Query("UPDATE Regions SET WorldID=@0, UserIds=''", Main.worldID.ToString()); + ReloadAllRegions(); + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } - String path = Path.Combine(TShock.SavePath, "old_configs"); - String file2 = Path.Combine(path, "regions.xml"); - if (!Directory.Exists(path)) - Directory.CreateDirectory(path); - if (File.Exists(file2)) - File.Delete(file2); - File.Move(file, file2); - - ReloadAllRegions(); - } - - public void ConvertDB() - { - try - { - database.Query("UPDATE Regions SET WorldID=@0, UserIds=''", Main.worldID.ToString()); - ReloadAllRegions(); - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } - - public void ReloadAllRegions() - { - try - { - using (var reader = database.QueryReader("SELECT * FROM Regions WHERE WorldID=@0", Main.worldID.ToString())) - { - Regions.Clear(); - while (reader.Read()) - { - int X1 = reader.Get("X1"); - int Y1 = reader.Get("Y1"); - int height = reader.Get("height"); - int width = reader.Get("width"); - int Protected = reader.Get("Protected"); - string mergedids = reader.Get("UserIds"); - string name = reader.Get("RegionName"); + public void ReloadAllRegions() + { + try + { + using (var reader = database.QueryReader("SELECT * FROM Regions WHERE WorldID=@0", Main.worldID.ToString())) + { + Regions.Clear(); + while (reader.Read()) + { + int X1 = reader.Get("X1"); + int Y1 = reader.Get("Y1"); + int height = reader.Get("height"); + int width = reader.Get("width"); + int Protected = reader.Get("Protected"); + string mergedids = reader.Get("UserIds"); + string name = reader.Get("RegionName"); string owner = reader.Get("Owner"); string groups = reader.Get("Groups"); - string[] splitids = mergedids.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + string[] splitids = mergedids.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); - Region r = new Region(new Rectangle(X1, Y1, width, height), name, owner, Protected != 0, Main.worldID.ToString()); - r.SetAllowedGroups( groups ); - try - { - for (int i = 0; i < splitids.Length; i++) - { - int id; + Region r = new Region(new Rectangle(X1, Y1, width, height), name, owner, Protected != 0, Main.worldID.ToString()); + r.SetAllowedGroups(groups); + try + { + for (int i = 0; i < splitids.Length; i++) + { + int id; - if (Int32.TryParse(splitids[i], out id)) // if unparsable, it's not an int, so silently skip - r.AllowedIDs.Add(id); - else - Log.Warn("One of your UserIDs is not a usable integer: " + splitids[i]); - } - } - catch (Exception e) - { - Log.Error("Your database contains invalid UserIDs (they should be ints)."); - Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field."); - Log.Error(e.ToString()); - Log.Error(e.StackTrace); - } + if (Int32.TryParse(splitids[i], out id)) // if unparsable, it's not an int, so silently skip + r.AllowedIDs.Add(id); + else + Log.Warn("One of your UserIDs is not a usable integer: " + splitids[i]); + } + } + catch (Exception e) + { + Log.Error("Your database contains invalid UserIDs (they should be ints)."); + Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field."); + Log.Error(e.ToString()); + Log.Error(e.StackTrace); + } - Regions.Add(r); - } - } - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } + Regions.Add(r); + } + } + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } - public void ReloadForUnitTest(String n) - { - - using (var reader = database.QueryReader("SELECT * FROM Regions WHERE WorldID=@0", n)) - { - Regions.Clear(); - while (reader.Read()) - { - int X1 = reader.Get("X1"); - int Y1 = reader.Get("Y1"); - int height = reader.Get("height"); - int width = reader.Get("width"); - int Protected = reader.Get("Protected"); - string MergedIDs = reader.Get("UserIds"); - string name = reader.Get("RegionName"); - string[] SplitIDs = MergedIDs.Split(','); + public void ReloadForUnitTest(String n) + { + using (var reader = database.QueryReader("SELECT * FROM Regions WHERE WorldID=@0", n)) + { + Regions.Clear(); + while (reader.Read()) + { + int X1 = reader.Get("X1"); + int Y1 = reader.Get("Y1"); + int height = reader.Get("height"); + int width = reader.Get("width"); + int Protected = reader.Get("Protected"); + string MergedIDs = reader.Get("UserIds"); + string name = reader.Get("RegionName"); + string[] SplitIDs = MergedIDs.Split(','); string owner = reader.Get("Owner"); string groups = reader.Get("Groups"); - Region r = new Region(new Rectangle(X1, Y1, width, height), name, owner, Protected != 0, Main.worldID.ToString()); - r.SetAllowedGroups( groups ); - try - { - for (int i = 0; i < SplitIDs.Length; i++) - { - int id; + Region r = new Region(new Rectangle(X1, Y1, width, height), name, owner, Protected != 0, Main.worldID.ToString()); + r.SetAllowedGroups(groups); + try + { + for (int i = 0; i < SplitIDs.Length; i++) + { + int id; - if (Int32.TryParse(SplitIDs[i], out id)) // if unparsable, it's not an int, so silently skip - r.AllowedIDs.Add(id); - else if (SplitIDs[i] == "") // Split gotcha, can return an empty string with certain conditions - // but we only want to let the user know if it's really a nonparsable integer. - Log.Warn("UnitTest: One of your UserIDs is not a usable integer: " + SplitIDs[i]); - } - } - catch (Exception e) - { - Log.Error("Your database contains invalid UserIDs (they should be ints)."); - Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field."); - Log.Error(e.Message); - Log.Error(e.StackTrace); - } + if (Int32.TryParse(SplitIDs[i], out id)) // if unparsable, it's not an int, so silently skip + r.AllowedIDs.Add(id); + else if (SplitIDs[i] == "") // Split gotcha, can return an empty string with certain conditions + // but we only want to let the user know if it's really a nonparsable integer. + Log.Warn("UnitTest: One of your UserIDs is not a usable integer: " + SplitIDs[i]); + } + } + catch (Exception e) + { + Log.Error("Your database contains invalid UserIDs (they should be ints)."); + Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field."); + Log.Error(e.Message); + Log.Error(e.StackTrace); + } - Regions.Add(r); - } - } + Regions.Add(r); + } + } + } - } - - public bool AddRegion(int tx, int ty, int width, int height, string regionname, string owner, string worldid) - { - if (GetRegionByName(regionname) != null) - { - return false; - } - try - { - database.Query("INSERT INTO Regions (X1, Y1, width, height, RegionName, WorldID, UserIds, Protected, Groups, Owner) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9);", - tx, ty, width, height, regionname, worldid, "", 1, "", owner); - Regions.Add(new Region(new Rectangle(tx, ty, width, height), regionname, owner, true, worldid)); - return true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return false; - } - - public bool DeleteRegion(string name) - { - try - { - database.Query("DELETE FROM Regions WHERE RegionName=@0 AND WorldID=@1", name, Main.worldID.ToString()); - var worldid = Main.worldID.ToString(); - Regions.RemoveAll(r => r.Name == name && r.WorldID == worldid); - return true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return false; - } - - public bool SetRegionState(string name, bool state) - { - try - { - database.Query("UPDATE Regions SET Protected=@0 WHERE RegionName=@1 AND WorldID=@2", state ? 1 : 0, name, Main.worldID.ToString()); - var region = GetRegionByName(name); - if (region != null) - region.DisableBuild = state; - return true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - return false; - } - } - - public bool SetRegionStateTest(string name, string world, bool state) - { - try - { - database.Query("UPDATE Regions SET Protected=@0 WHERE RegionName=@1 AND WorldID=@2", state ? 1 : 0, name, world); - var region = GetRegionByName(name); - if (region != null) - region.DisableBuild = state; - return true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - return false; - } - } - - public bool CanBuild(int x, int y, TSPlayer ply) - { - if (!ply.Group.HasPermission(Permissions.canbuild)) - { - return false; - } - for (int i = 0; i < Regions.Count; i++) - { - if (Regions[i].InArea(new Rectangle(x, y, 0, 0)) && !Regions[i].HasPermissionToBuildInRegion(ply)) - { - return false; - } - } - return true; - } - - public bool InArea(int x, int y) - { - foreach (Region region in Regions) - { - if (x >= region.Area.Left && x <= region.Area.Right && - y >= region.Area.Top && y <= region.Area.Bottom && - region.DisableBuild) - { - return true; - } - } - return false; - } - - public string InAreaRegionName(int x, int y) - { - foreach (Region region in Regions) - { - if (x >= region.Area.Left && x <= region.Area.Right && - y >= region.Area.Top && y <= region.Area.Bottom && - region.DisableBuild) - { - return region.Name; - } - } - return null; - } - - public static List ListIDs(string MergedIDs) - { - return MergedIDs.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); - } - - public bool resizeRegion(string regionName, int addAmount, int direction) - { - //0 = up - //1 = right - //2 = down - //3 = left - int X = 0; - int Y = 0; - int height = 0; - int width = 0; - try - { - using (var reader = database.QueryReader("SELECT X1, Y1, height, width FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName, Main.worldID.ToString())) - { - if (reader.Read()) - X = reader.Get("X1"); - width = reader.Get("width"); - Y = reader.Get("Y1"); - height = reader.Get("height"); - } - if (!(direction == 0)) - { - if (!(direction == 1)) - { - if (!(direction == 2)) - { - if (!(direction == 3)) - { - return false; - } - else - { - X -= addAmount; - width += addAmount; - } - } - else - { - height += addAmount; - } - } - else - { - width += addAmount; - } - } - else - { - Y -= addAmount; - height += addAmount; - } - int q = database.Query("UPDATE Regions SET X1 = @0, Y1 = @1, width = @2, height = @3 WHERE RegionName = @4 AND WorldID=@5", X, Y, width, height, regionName, Main.worldID.ToString()); - if (q > 0) - return true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return false; - } - - public bool RemoveUser(string regionName, string userName) - { - Region r = GetRegionByName(regionName); - if (r != null) - { - r.RemoveID(TShock.Users.GetUserID(userName)); - string ids = string.Join(",", r.AllowedIDs); - int q = database.Query("UPDATE Regions SET UserIds=@0 WHERE RegionName=@1 AND WorldID=@2", ids, - regionName, Main.worldID.ToString()); - if (q > 0) - return true; - } - return false; - } - public bool AddNewUser(string regionName, String userName) - { - try - { - string MergedIDs = string.Empty; - using (var reader = database.QueryReader("SELECT * FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName, Main.worldID.ToString())) - { - if (reader.Read()) - MergedIDs = reader.Get("UserIds"); - } - - if (string.IsNullOrEmpty(MergedIDs)) - MergedIDs = Convert.ToString(TShock.Users.GetUserID(userName)); - else - MergedIDs = MergedIDs + "," + Convert.ToString(TShock.Users.GetUserID(userName)); - - int q = database.Query("UPDATE Regions SET UserIds=@0 WHERE RegionName=@1 AND WorldID=@2", MergedIDs, - regionName, Main.worldID.ToString()); - foreach (var r in Regions) - { - if (r.Name == regionName && r.WorldID == Main.worldID.ToString()) - r.setAllowedIDs(MergedIDs); - } - return q != 0; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return false; - } - - /// - /// Gets all the regions names from world - /// - /// World name to get regions from - /// List of regions with only their names - public List ListAllRegions(string worldid) - { - var regions = new List(); - try - { - using (var reader = database.QueryReader("SELECT RegionName FROM Regions WHERE WorldID=@0", worldid)) - { - while (reader.Read()) - regions.Add(new Region { Name = reader.Get("RegionName") }); - } - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return regions; - } - - public Region GetRegionByName(String name) - { - return Regions.FirstOrDefault(r => r.Name.Equals(name) && r.WorldID == Main.worldID.ToString()); - } - - public Region ZacksGetRegionByName(String name) - { - foreach (Region r in Regions) - { - if (r.Name.Equals(name)) - return r; - } - return null; - } - - public bool ChangeOwner( string regionName, string newOwner ) + public bool AddRegion(int tx, int ty, int width, int height, string regionname, string owner, string worldid) { - var region = GetRegionByName(regionName); - if( region != null ) + if (GetRegionByName(regionname) != null) { - region.Owner = newOwner; - int q = database.Query("UPDATE Regions SET Owner=@0 WHERE RegionName=@1 AND WorldID=@2", newOwner, - regionName, Main.worldID.ToString()); + return false; + } + try + { + database.Query( + "INSERT INTO Regions (X1, Y1, width, height, RegionName, WorldID, UserIds, Protected, Groups, Owner) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9);", + tx, ty, width, height, regionname, worldid, "", 1, "", owner); + Regions.Add(new Region(new Rectangle(tx, ty, width, height), regionname, owner, true, worldid)); + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; + } + + public bool DeleteRegion(string name) + { + try + { + database.Query("DELETE FROM Regions WHERE RegionName=@0 AND WorldID=@1", name, Main.worldID.ToString()); + var worldid = Main.worldID.ToString(); + Regions.RemoveAll(r => r.Name == name && r.WorldID == worldid); + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; + } + + public bool SetRegionState(string name, bool state) + { + try + { + database.Query("UPDATE Regions SET Protected=@0 WHERE RegionName=@1 AND WorldID=@2", state ? 1 : 0, name, + Main.worldID.ToString()); + var region = GetRegionByName(name); + if (region != null) + region.DisableBuild = state; + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + return false; + } + } + + public bool SetRegionStateTest(string name, string world, bool state) + { + try + { + database.Query("UPDATE Regions SET Protected=@0 WHERE RegionName=@1 AND WorldID=@2", state ? 1 : 0, name, world); + var region = GetRegionByName(name); + if (region != null) + region.DisableBuild = state; + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + return false; + } + } + + public bool CanBuild(int x, int y, TSPlayer ply) + { + if (!ply.Group.HasPermission(Permissions.canbuild)) + { + return false; + } + for (int i = 0; i < Regions.Count; i++) + { + if (Regions[i].InArea(new Rectangle(x, y, 0, 0)) && !Regions[i].HasPermissionToBuildInRegion(ply)) + { + return false; + } + } + return true; + } + + public bool InArea(int x, int y) + { + foreach (Region region in Regions) + { + if (x >= region.Area.Left && x <= region.Area.Right && + y >= region.Area.Top && y <= region.Area.Bottom && + region.DisableBuild) + { + return true; + } + } + return false; + } + + public string InAreaRegionName(int x, int y) + { + foreach (Region region in Regions) + { + if (x >= region.Area.Left && x <= region.Area.Right && + y >= region.Area.Top && y <= region.Area.Bottom && + region.DisableBuild) + { + return region.Name; + } + } + return null; + } + + public static List ListIDs(string MergedIDs) + { + return MergedIDs.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).ToList(); + } + + public bool resizeRegion(string regionName, int addAmount, int direction) + { + //0 = up + //1 = right + //2 = down + //3 = left + int X = 0; + int Y = 0; + int height = 0; + int width = 0; + try + { + using ( + var reader = database.QueryReader("SELECT X1, Y1, height, width FROM Regions WHERE RegionName=@0 AND WorldID=@1", + regionName, Main.worldID.ToString())) + { + if (reader.Read()) + X = reader.Get("X1"); + width = reader.Get("width"); + Y = reader.Get("Y1"); + height = reader.Get("height"); + } + if (!(direction == 0)) + { + if (!(direction == 1)) + { + if (!(direction == 2)) + { + if (!(direction == 3)) + { + return false; + } + else + { + X -= addAmount; + width += addAmount; + } + } + else + { + height += addAmount; + } + } + else + { + width += addAmount; + } + } + else + { + Y -= addAmount; + height += addAmount; + } + int q = + database.Query( + "UPDATE Regions SET X1 = @0, Y1 = @1, width = @2, height = @3 WHERE RegionName = @4 AND WorldID=@5", X, Y, width, + height, regionName, Main.worldID.ToString()); + if (q > 0) + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; + } + + public bool RemoveUser(string regionName, string userName) + { + Region r = GetRegionByName(regionName); + if (r != null) + { + r.RemoveID(TShock.Users.GetUserID(userName)); + string ids = string.Join(",", r.AllowedIDs); + int q = database.Query("UPDATE Regions SET UserIds=@0 WHERE RegionName=@1 AND WorldID=@2", ids, + regionName, Main.worldID.ToString()); if (q > 0) return true; } return false; } - public bool AllowGroup( string regionName, string groups) + public bool AddNewUser(string regionName, String userName) + { + try + { + string MergedIDs = string.Empty; + using ( + var reader = database.QueryReader("SELECT * FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName, + Main.worldID.ToString())) + { + if (reader.Read()) + MergedIDs = reader.Get("UserIds"); + } + + if (string.IsNullOrEmpty(MergedIDs)) + MergedIDs = Convert.ToString(TShock.Users.GetUserID(userName)); + else + MergedIDs = MergedIDs + "," + Convert.ToString(TShock.Users.GetUserID(userName)); + + int q = database.Query("UPDATE Regions SET UserIds=@0 WHERE RegionName=@1 AND WorldID=@2", MergedIDs, + regionName, Main.worldID.ToString()); + foreach (var r in Regions) + { + if (r.Name == regionName && r.WorldID == Main.worldID.ToString()) + r.setAllowedIDs(MergedIDs); + } + return q != 0; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; + } + + /// + /// Gets all the regions names from world + /// + /// World name to get regions from + /// List of regions with only their names + public List ListAllRegions(string worldid) + { + var regions = new List(); + try + { + using (var reader = database.QueryReader("SELECT RegionName FROM Regions WHERE WorldID=@0", worldid)) + { + while (reader.Read()) + regions.Add(new Region {Name = reader.Get("RegionName")}); + } + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return regions; + } + + public Region GetRegionByName(String name) + { + return Regions.FirstOrDefault(r => r.Name.Equals(name) && r.WorldID == Main.worldID.ToString()); + } + + public Region ZacksGetRegionByName(String name) + { + foreach (Region r in Regions) + { + if (r.Name.Equals(name)) + return r; + } + return null; + } + + public bool ChangeOwner(string regionName, string newOwner) + { + var region = GetRegionByName(regionName); + if (region != null) + { + region.Owner = newOwner; + int q = database.Query("UPDATE Regions SET Owner=@0 WHERE RegionName=@1 AND WorldID=@2", newOwner, + regionName, Main.worldID.ToString()); + if (q > 0) + return true; + } + return false; + } + + public bool AllowGroup(string regionName, string groups) { string groupsNew = ""; - using (var reader = database.QueryReader("SELECT * FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName, Main.worldID.ToString())) + using ( + var reader = database.QueryReader("SELECT * FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName, + Main.worldID.ToString())) { if (reader.Read()) groupsNew = reader.Get("Groups"); @@ -558,12 +569,12 @@ namespace TShockAPI.DB groupsNew += groups; int q = database.Query("UPDATE Regions SET Groups=@0 WHERE RegionName=@1 AND WorldID=@2", groupsNew, - regionName, Main.worldID.ToString()); + regionName, Main.worldID.ToString()); Region r = GetRegionByName(regionName); - if( r != null ) + if (r != null) { - r.SetAllowedGroups( groupsNew ); + r.SetAllowedGroups(groupsNew); } else { @@ -573,7 +584,7 @@ namespace TShockAPI.DB return q > 0; } - public bool RemoveGroup( string regionName, string group ) + public bool RemoveGroup(string regionName, string group) { Region r = GetRegionByName(regionName); if (r != null) @@ -581,118 +592,118 @@ namespace TShockAPI.DB r.RemoveGroup(group); string groups = string.Join(",", r.AllowedGroups); int q = database.Query("UPDATE Regions SET Groups=@0 WHERE RegionName=@1 AND WorldID=@2", groups, - regionName, Main.worldID.ToString()); + regionName, Main.worldID.ToString()); if (q > 0) return true; } return false; } - } - - public class Region - { - public Rectangle Area { get; set; } - public string Name { get; set; } - public string Owner { get; set; } - public bool DisableBuild { get; set; } - public string WorldID { get; set; } - public List AllowedIDs { get; set; } - public List AllowedGroups { get; set; } - - public Region(Rectangle region, string name, string owner, bool disablebuild, string RegionWorldIDz) - : this() - { - Area = region; - Name = name; - Owner = owner; - DisableBuild = disablebuild; - WorldID = RegionWorldIDz; - - } - - public Region() - { - Area = Rectangle.Empty; - Name = string.Empty; - DisableBuild = true; - WorldID = string.Empty; - AllowedIDs = new List(); - AllowedGroups = new List(); - } - - public bool InArea(Rectangle point) - { - if (Area.Contains(point.X, point.Y)) - { - return true; - } - return false; - } - - public bool HasPermissionToBuildInRegion(TSPlayer ply) - { - if (!ply.IsLoggedIn) - { - if (!ply.HasBeenNaggedAboutLoggingIn) - { - ply.SendMessage("You must be logged in to take advantage of protected regions.", Color.Red); - ply.HasBeenNaggedAboutLoggingIn = true; - } - return false; - } - if (!DisableBuild) - { - return true; - } - - return AllowedIDs.Contains(ply.UserID) || AllowedGroups.Contains(ply.Group.Name) || Owner == ply.UserAccountName || ply.Group.HasPermission("manageregion"); - } - - public void setAllowedIDs(String ids) - { - String[] id_arr = ids.Split(','); - List id_list = new List(); - foreach (String id in id_arr) - { - int i = 0; - int.TryParse(id, out i); - if (i != 0) - id_list.Add(i); - } - AllowedIDs = id_list; - } - - public void SetAllowedGroups( String groups ) - { - // prevent null pointer exceptions - if (!string.IsNullOrEmpty(groups)) - { - List groupArr = groups.Split(',').ToList(); - - for (int i = 0; i < groupArr.Count; i++) - groupArr[i] = groupArr[i].Trim(); - - AllowedGroups = groupArr; - } } - public void RemoveID(int id) - { - var index = -1; - for (int i = 0; i < AllowedIDs.Count; i++) - { - if (AllowedIDs[i] == id) - { - index = i; - break; - } - } - AllowedIDs.RemoveAt(index); - } + public class Region + { + public Rectangle Area { get; set; } + public string Name { get; set; } + public string Owner { get; set; } + public bool DisableBuild { get; set; } + public string WorldID { get; set; } + public List AllowedIDs { get; set; } + public List AllowedGroups { get; set; } - public bool RemoveGroup(string groupName) + public Region(Rectangle region, string name, string owner, bool disablebuild, string RegionWorldIDz) + : this() + { + Area = region; + Name = name; + Owner = owner; + DisableBuild = disablebuild; + WorldID = RegionWorldIDz; + } + + public Region() + { + Area = Rectangle.Empty; + Name = string.Empty; + DisableBuild = true; + WorldID = string.Empty; + AllowedIDs = new List(); + AllowedGroups = new List(); + } + + public bool InArea(Rectangle point) + { + if (Area.Contains(point.X, point.Y)) + { + return true; + } + return false; + } + + public bool HasPermissionToBuildInRegion(TSPlayer ply) + { + if (!ply.IsLoggedIn) + { + if (!ply.HasBeenNaggedAboutLoggingIn) + { + ply.SendMessage("You must be logged in to take advantage of protected regions.", Color.Red); + ply.HasBeenNaggedAboutLoggingIn = true; + } + return false; + } + if (!DisableBuild) + { + return true; + } + + return AllowedIDs.Contains(ply.UserID) || AllowedGroups.Contains(ply.Group.Name) || Owner == ply.UserAccountName || + ply.Group.HasPermission("manageregion"); + } + + public void setAllowedIDs(String ids) + { + String[] id_arr = ids.Split(','); + List id_list = new List(); + foreach (String id in id_arr) + { + int i = 0; + int.TryParse(id, out i); + if (i != 0) + id_list.Add(i); + } + AllowedIDs = id_list; + } + + public void SetAllowedGroups(String groups) + { + // prevent null pointer exceptions + if (!string.IsNullOrEmpty(groups)) + { + List groupArr = groups.Split(',').ToList(); + + for (int i = 0; i < groupArr.Count; i++) + groupArr[i] = groupArr[i].Trim(); + + AllowedGroups = groupArr; + } + } + + public void RemoveID(int id) + { + var index = -1; + for (int i = 0; i < AllowedIDs.Count; i++) + { + if (AllowedIDs[i] == id) + { + index = i; + break; + } + } + AllowedIDs.RemoveAt(index); + } + + public bool RemoveGroup(string groupName) { return AllowedGroups.Remove(groupName); } - } -} + } +} \ No newline at end of file diff --git a/TShockAPI/DB/RememberPosManager.cs b/TShockAPI/DB/RememberPosManager.cs index 5e70c01a..4958eadf 100644 --- a/TShockAPI/DB/RememberPosManager.cs +++ b/TShockAPI/DB/RememberPosManager.cs @@ -23,69 +23,74 @@ using Terraria; namespace TShockAPI.DB { - public class RemeberedPosManager - { - public IDbConnection database; + public class RemeberedPosManager + { + public IDbConnection database; - public RemeberedPosManager(IDbConnection db) - { - database = db; + public RemeberedPosManager(IDbConnection db) + { + database = db; - var table = new SqlTable("RememberedPos", - new SqlColumn("Name", MySqlDbType.VarChar, 50) { Primary = true }, - new SqlColumn("IP", MySqlDbType.Text), - new SqlColumn("X", MySqlDbType.Int32), - new SqlColumn("Y", MySqlDbType.Int32), - new SqlColumn("WorldID", MySqlDbType.Text) - ); - var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator()); - creator.EnsureExists(table); - } + var table = new SqlTable("RememberedPos", + new SqlColumn("Name", MySqlDbType.VarChar, 50) {Primary = true}, + new SqlColumn("IP", MySqlDbType.Text), + new SqlColumn("X", MySqlDbType.Int32), + new SqlColumn("Y", MySqlDbType.Int32), + new SqlColumn("WorldID", MySqlDbType.Text) + ); + var creator = new SqlTableCreator(db, + db.GetSqlType() == SqlType.Sqlite + ? (IQueryBuilder) new SqliteQueryCreator() + : new MysqlQueryCreator()); + creator.EnsureExists(table); + } - public Vector2 GetLeavePos(string name, string IP) - { - try - { - using (var reader = database.QueryReader("SELECT * FROM RememberedPos WHERE Name=@0 AND IP=@1", name, IP)) - { - if (reader.Read()) - { - return new Vector2(reader.Get("X"), reader.Get("Y")); - } - } - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } + public Vector2 GetLeavePos(string name, string IP) + { + try + { + using (var reader = database.QueryReader("SELECT * FROM RememberedPos WHERE Name=@0 AND IP=@1", name, IP)) + { + if (reader.Read()) + { + return new Vector2(reader.Get("X"), reader.Get("Y")); + } + } + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } - return new Vector2(); - } + return new Vector2(); + } - public void InsertLeavePos(string name, string IP, int X, int Y) - { - if (GetLeavePos(name, IP) == Vector2.Zero) - { - try - { - database.Query("INSERT INTO RememberedPos (Name, IP, X, Y, WorldID) VALUES (@0, @1, @2, @3, @4);", name, IP, X, Y + 3, Main.worldID.ToString()); - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } - else - { - try - { - database.Query("UPDATE RememberedPos SET X = @0, Y = @1 WHERE Name = @2 AND IP = @3 AND WorldID = @4;", X, Y + 3, name, IP, Main.worldID.ToString()); - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } - } - } -} + public void InsertLeavePos(string name, string IP, int X, int Y) + { + if (GetLeavePos(name, IP) == Vector2.Zero) + { + try + { + database.Query("INSERT INTO RememberedPos (Name, IP, X, Y, WorldID) VALUES (@0, @1, @2, @3, @4);", name, IP, X, + Y + 3, Main.worldID.ToString()); + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } + else + { + try + { + database.Query("UPDATE RememberedPos SET X = @0, Y = @1 WHERE Name = @2 AND IP = @3 AND WorldID = @4;", X, Y + 3, + name, IP, Main.worldID.ToString()); + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } + } + } +} \ No newline at end of file diff --git a/TShockAPI/DB/SqlColumn.cs b/TShockAPI/DB/SqlColumn.cs index 8e86498c..dce163b4 100644 --- a/TShockAPI/DB/SqlColumn.cs +++ b/TShockAPI/DB/SqlColumn.cs @@ -2,34 +2,35 @@ namespace TShockAPI.DB { - public class SqlColumn - { - //Required - public string Name { get; set; } - public MySqlDbType Type { get; set; } + public class SqlColumn + { + //Required + public string Name { get; set; } + public MySqlDbType Type { get; set; } - //Optional - public bool Unique { get; set; } - public bool Primary { get; set; } - public bool AutoIncrement { get; set; } - public bool NotNull { get; set; } - public string DefaultValue { get; set; } + //Optional + public bool Unique { get; set; } + public bool Primary { get; set; } + public bool AutoIncrement { get; set; } + public bool NotNull { get; set; } + public string DefaultValue { get; set; } - /// - /// Length of the data type, null = default - /// - public int? Length { get; set; } + /// + /// Length of the data type, null = default + /// + public int? Length { get; set; } - public SqlColumn(string name, MySqlDbType type) - : this(name, type, null) - { - } - public SqlColumn(string name, MySqlDbType type, int? length) - { - Name = name; - Type = type; - Length = length; - } - } -} + public SqlColumn(string name, MySqlDbType type) + : this(name, type, null) + { + } + + public SqlColumn(string name, MySqlDbType type, int? length) + { + Name = name; + Type = type; + Length = length; + } + } +} \ No newline at end of file diff --git a/TShockAPI/DB/SqlTable.cs b/TShockAPI/DB/SqlTable.cs index b2610538..8f98ef4d 100644 --- a/TShockAPI/DB/SqlTable.cs +++ b/TShockAPI/DB/SqlTable.cs @@ -6,79 +6,86 @@ using MySql.Data.MySqlClient; namespace TShockAPI.DB { - public class SqlTable - { - public List Columns { get; protected set; } - public string Name { get; protected set; } - public SqlTable(string name, params SqlColumn[] columns) - : this(name, new List(columns)) - { - } - public SqlTable(string name, List columns) - { - Name = name; - Columns = columns; - } - } + public class SqlTable + { + public List Columns { get; protected set; } + public string Name { get; protected set; } - public class SqlTableCreator - { - IDbConnection database; - IQueryBuilder creator; - public SqlTableCreator(IDbConnection db, IQueryBuilder provider) - { - database = db; - creator = provider; - } + public SqlTable(string name, params SqlColumn[] columns) + : this(name, new List(columns)) + { + } - public void EnsureExists(SqlTable table) - { - var columns = GetColumns(table); - if (columns.Count > 0) - { - if (!table.Columns.All(c => columns.Contains(c.Name)) || !columns.All(c => table.Columns.Any(c2 => c2.Name == c))) - { - var from = new SqlTable(table.Name, columns.Select(s => new SqlColumn(s, MySqlDbType.String)).ToList()); - database.Query(creator.AlterTable(from, table)); - } - } - else - { - database.Query(creator.CreateTable(table)); - } - } + public SqlTable(string name, List columns) + { + Name = name; + Columns = columns; + } + } - public List GetColumns(SqlTable table) - { - var ret = new List(); - var name = database.GetSqlType(); - if (name == SqlType.Sqlite) - { - using (var reader = database.QueryReader("PRAGMA table_info({0})".SFormat(table.Name))) - { - while (reader.Read()) - ret.Add(reader.Get("name")); - } - } - else if (name == SqlType.Mysql) - { - using (var reader = database.QueryReader("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME=@0 AND TABLE_SCHEMA=@1", table.Name, database.Database)) - { - while (reader.Read()) - ret.Add(reader.Get("COLUMN_NAME")); - } - } - else - { - throw new NotSupportedException(); - } + public class SqlTableCreator + { + private IDbConnection database; + private IQueryBuilder creator; - return ret; - } + public SqlTableCreator(IDbConnection db, IQueryBuilder provider) + { + database = db; + creator = provider; + } - public void DeleteRow(string table, List wheres) - { - database.Query(creator.DeleteRow(table, wheres)); - } - } -} + public void EnsureExists(SqlTable table) + { + var columns = GetColumns(table); + if (columns.Count > 0) + { + if (!table.Columns.All(c => columns.Contains(c.Name)) || !columns.All(c => table.Columns.Any(c2 => c2.Name == c))) + { + var from = new SqlTable(table.Name, columns.Select(s => new SqlColumn(s, MySqlDbType.String)).ToList()); + database.Query(creator.AlterTable(from, table)); + } + } + else + { + database.Query(creator.CreateTable(table)); + } + } + + public List GetColumns(SqlTable table) + { + var ret = new List(); + var name = database.GetSqlType(); + if (name == SqlType.Sqlite) + { + using (var reader = database.QueryReader("PRAGMA table_info({0})".SFormat(table.Name))) + { + while (reader.Read()) + ret.Add(reader.Get("name")); + } + } + else if (name == SqlType.Mysql) + { + using ( + var reader = + database.QueryReader( + "SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME=@0 AND TABLE_SCHEMA=@1", table.Name, + database.Database)) + { + while (reader.Read()) + ret.Add(reader.Get("COLUMN_NAME")); + } + } + else + { + throw new NotSupportedException(); + } + + return ret; + } + + public void DeleteRow(string table, List wheres) + { + database.Query(creator.DeleteRow(table, wheres)); + } + } +} \ No newline at end of file diff --git a/TShockAPI/DB/SqlValue.cs b/TShockAPI/DB/SqlValue.cs index 48630d7a..fedb818b 100644 --- a/TShockAPI/DB/SqlValue.cs +++ b/TShockAPI/DB/SqlValue.cs @@ -3,50 +3,50 @@ using System.Data; namespace TShockAPI.DB { - public class SqlValue - { - public string Name { get; set; } - public object Value { get; set; } + public class SqlValue + { + public string Name { get; set; } + public object Value { get; set; } - public SqlValue(string name, object value) - { - Name = name; - Value = value; - } - } + public SqlValue(string name, object value) + { + Name = name; + Value = value; + } + } - public class SqlTableEditor - { - IDbConnection database; - IQueryBuilder creator; + public class SqlTableEditor + { + private IDbConnection database; + private IQueryBuilder creator; - public SqlTableEditor(IDbConnection db, IQueryBuilder provider) - { - database = db; - creator = provider; - } + public SqlTableEditor(IDbConnection db, IQueryBuilder provider) + { + database = db; + creator = provider; + } - public void UpdateValues(string table, List values, List wheres) - { - database.Query(creator.UpdateValue(table, values, wheres)); - } + public void UpdateValues(string table, List values, List wheres) + { + database.Query(creator.UpdateValue(table, values, wheres)); + } - public void InsertValues(string table, List values) - { - database.Query(creator.InsertValues(table, values)); - } + public void InsertValues(string table, List values) + { + database.Query(creator.InsertValues(table, values)); + } - public List ReadColumn(string table, string column, List wheres) - { - List values = new List(); + public List ReadColumn(string table, string column, List wheres) + { + List values = new List(); - using (var reader = database.QueryReader(creator.ReadColumn(table, wheres))) - { - while (reader.Read()) - values.Add(reader.Reader.Get(column)); - } + using (var reader = database.QueryReader(creator.ReadColumn(table, wheres))) + { + while (reader.Read()) + values.Add(reader.Reader.Get(column)); + } - return values; - } - } -} + return values; + } + } +} \ No newline at end of file diff --git a/TShockAPI/DB/UserManager.cs b/TShockAPI/DB/UserManager.cs index 3c450674..bb086174 100644 --- a/TShockAPI/DB/UserManager.cs +++ b/TShockAPI/DB/UserManager.cs @@ -1,5 +1,4 @@ - -/* +/* TShock, a server mod for Terraria Copyright (C) 2011 The TShock Team @@ -24,354 +23,366 @@ using MySql.Data.MySqlClient; namespace TShockAPI.DB { - public class UserManager - { - private IDbConnection database; + public class UserManager + { + private IDbConnection database; - public UserManager(IDbConnection db) - { - database = db; + public UserManager(IDbConnection db) + { + database = db; - var table = new SqlTable("Users", - new SqlColumn("ID", MySqlDbType.Int32) { Primary = true, AutoIncrement = true }, - new SqlColumn("Username", MySqlDbType.VarChar, 32) { Unique = true }, - new SqlColumn("Password", MySqlDbType.VarChar, 128), - new SqlColumn("Usergroup", MySqlDbType.Text), - new SqlColumn("IP", MySqlDbType.VarChar, 16) - ); - var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator()); - creator.EnsureExists(table); + var table = new SqlTable("Users", + new SqlColumn("ID", MySqlDbType.Int32) {Primary = true, AutoIncrement = true}, + new SqlColumn("Username", MySqlDbType.VarChar, 32) {Unique = true}, + new SqlColumn("Password", MySqlDbType.VarChar, 128), + new SqlColumn("Usergroup", MySqlDbType.Text), + new SqlColumn("IP", MySqlDbType.VarChar, 16) + ); + var creator = new SqlTableCreator(db, + db.GetSqlType() == SqlType.Sqlite + ? (IQueryBuilder) new SqliteQueryCreator() + : new MysqlQueryCreator()); + creator.EnsureExists(table); - String file = Path.Combine(TShock.SavePath, "users.txt"); - if (File.Exists(file)) - { - using (StreamReader sr = new StreamReader(file)) - { - String line; - while ((line = sr.ReadLine()) != null) - { - if (line.Equals("") || line.Substring(0, 1).Equals("#")) - continue; - String[] info = line.Split(' '); - String username = ""; - String sha = ""; - String group = ""; - String ip = ""; + String file = Path.Combine(TShock.SavePath, "users.txt"); + if (File.Exists(file)) + { + using (StreamReader sr = new StreamReader(file)) + { + String line; + while ((line = sr.ReadLine()) != null) + { + if (line.Equals("") || line.Substring(0, 1).Equals("#")) + continue; + String[] info = line.Split(' '); + String username = ""; + String sha = ""; + String group = ""; + String ip = ""; - String[] nameSha = info[0].Split(':'); + String[] nameSha = info[0].Split(':'); - if (nameSha.Length < 2) - { - username = nameSha[0]; - ip = nameSha[0]; - group = info[1]; - } - else - { - username = nameSha[0]; - sha = nameSha[1]; - group = info[1]; - } + if (nameSha.Length < 2) + { + username = nameSha[0]; + ip = nameSha[0]; + group = info[1]; + } + else + { + username = nameSha[0]; + sha = nameSha[1]; + group = info[1]; + } - string query = (TShock.Config.StorageType.ToLower() == "sqlite") ? - "INSERT OR IGNORE INTO Users (Username, Password, Usergroup, IP) VALUES (@0, @1, @2, @3)" : - "INSERT IGNORE INTO Users SET Username=@0, Password=@1, Usergroup=@2, IP=@3"; + string query = (TShock.Config.StorageType.ToLower() == "sqlite") + ? "INSERT OR IGNORE INTO Users (Username, Password, Usergroup, IP) VALUES (@0, @1, @2, @3)" + : "INSERT IGNORE INTO Users SET Username=@0, Password=@1, Usergroup=@2, IP=@3"; - database.Query(query, username.Trim(), sha.Trim(), group.Trim(), ip.Trim()); - } - } - String path = Path.Combine(TShock.SavePath, "old_configs"); - String file2 = Path.Combine(path, "users.txt"); - if (!Directory.Exists(path)) - Directory.CreateDirectory(path); - if (File.Exists(file2)) - File.Delete(file2); - File.Move(file, file2); - } + database.Query(query, username.Trim(), sha.Trim(), group.Trim(), ip.Trim()); + } + } + String path = Path.Combine(TShock.SavePath, "old_configs"); + String file2 = Path.Combine(path, "users.txt"); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + if (File.Exists(file2)) + File.Delete(file2); + File.Move(file, file2); + } + } - } + /// + /// Adds a given username to the database + /// + /// User user + public void AddUser(User user) + { + try + { + if (!TShock.Groups.GroupExists(user.Group)) + throw new GroupNotExistsException(user.Group); - /// - /// Adds a given username to the database - /// - /// User user - public void AddUser(User user) - { - try - { - if (!TShock.Groups.GroupExists(user.Group)) - throw new GroupNotExistsException(user.Group); + if ( + database.Query("INSERT INTO Users (Username, Password, UserGroup, IP) VALUES (@0, @1, @2, @3);", user.Name, + TShock.Utils.HashPassword(user.Password), user.Group, user.Address) < 1) + throw new UserExistsException(user.Name); + } + catch (Exception ex) + { + throw new UserManagerException("AddUser SQL returned an error", ex); + } + } - if (database.Query("INSERT INTO Users (Username, Password, UserGroup, IP) VALUES (@0, @1, @2, @3);", user.Name, TShock.Utils.HashPassword(user.Password), user.Group, user.Address) < 1) - throw new UserExistsException(user.Name); - } - catch (Exception ex) - { - throw new UserManagerException("AddUser SQL returned an error", ex); - } - } + /// + /// Removes a given username from the database + /// + /// User user + public void RemoveUser(User user) + { + try + { + int affected = -1; + if (!string.IsNullOrEmpty(user.Address)) + { + affected = database.Query("DELETE FROM Users WHERE IP=@0", user.Address); + } + else + { + affected = database.Query("DELETE FROM Users WHERE Username=@0", user.Name); + } - /// - /// Removes a given username from the database - /// - /// User user - public void RemoveUser(User user) - { - try - { - int affected = -1; - if (!string.IsNullOrEmpty(user.Address)) - { - affected = database.Query("DELETE FROM Users WHERE IP=@0", user.Address); - } - else - { - affected = database.Query("DELETE FROM Users WHERE Username=@0", user.Name); - } - - if (affected < 1) - throw new UserNotExistException(string.IsNullOrEmpty(user.Address) ? user.Name : user.Address); - } - catch (Exception ex) - { - throw new UserManagerException("RemoveUser SQL returned an error", ex); - } - } + if (affected < 1) + throw new UserNotExistException(string.IsNullOrEmpty(user.Address) ? user.Name : user.Address); + } + catch (Exception ex) + { + throw new UserManagerException("RemoveUser SQL returned an error", ex); + } + } - /// - /// Sets the Hashed Password for a given username - /// - /// User user - /// string password - public void SetUserPassword(User user, string password) - { - try - { - if (database.Query("UPDATE Users SET Password = @0 WHERE Username = @1;", TShock.Utils.HashPassword(password), user.Name) == 0) - throw new UserNotExistException(user.Name); - } - catch (Exception ex) - { - throw new UserManagerException("SetUserPassword SQL returned an error", ex); - } - } + /// + /// Sets the Hashed Password for a given username + /// + /// User user + /// string password + public void SetUserPassword(User user, string password) + { + try + { + if ( + database.Query("UPDATE Users SET Password = @0 WHERE Username = @1;", TShock.Utils.HashPassword(password), + user.Name) == 0) + throw new UserNotExistException(user.Name); + } + catch (Exception ex) + { + throw new UserManagerException("SetUserPassword SQL returned an error", ex); + } + } - /// - /// Sets the group for a given username - /// - /// User user - /// string group - public void SetUserGroup(User user, string group) - { - try - { - if (!TShock.Groups.GroupExists(group)) - throw new GroupNotExistsException(group); + /// + /// Sets the group for a given username + /// + /// User user + /// string group + public void SetUserGroup(User user, string group) + { + try + { + if (!TShock.Groups.GroupExists(group)) + throw new GroupNotExistsException(group); - if (database.Query("UPDATE Users SET UserGroup = @0 WHERE Username = @1;", group, user.Name) == 0) - throw new UserNotExistException(user.Name); - } - catch (Exception ex) - { - throw new UserManagerException("SetUserGroup SQL returned an error", ex); - } - } + if (database.Query("UPDATE Users SET UserGroup = @0 WHERE Username = @1;", group, user.Name) == 0) + throw new UserNotExistException(user.Name); + } + catch (Exception ex) + { + throw new UserManagerException("SetUserGroup SQL returned an error", ex); + } + } - public int GetUserID(string username) - { - try - { - using (var reader = database.QueryReader("SELECT * FROM Users WHERE Username=@0", username)) - { - if (reader.Read()) - { - return reader.Get("ID"); - } - } - } - catch (Exception ex) - { - Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex); - } - return -1; - } + public int GetUserID(string username) + { + try + { + using (var reader = database.QueryReader("SELECT * FROM Users WHERE Username=@0", username)) + { + if (reader.Read()) + { + return reader.Get("ID"); + } + } + } + catch (Exception ex) + { + Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex); + } + return -1; + } - /// - /// Returns a Group for a ip from the database - /// - /// string ip - public Group GetGroupForIP(string ip) - { - try - { - using (var reader = database.QueryReader("SELECT * FROM Users WHERE IP=@0", ip)) - { - if (reader.Read()) - { - string group = reader.Get("UserGroup"); - return TShock.Utils.GetGroup(group); - } - } - } - catch (Exception ex) - { - Log.ConsoleError("GetGroupForIP SQL returned an error: " + ex); - } - return TShock.Utils.GetGroup(TShock.Config.DefaultGuestGroupName); - } + /// + /// Returns a Group for a ip from the database + /// + /// string ip + public Group GetGroupForIP(string ip) + { + try + { + using (var reader = database.QueryReader("SELECT * FROM Users WHERE IP=@0", ip)) + { + if (reader.Read()) + { + string group = reader.Get("UserGroup"); + return TShock.Utils.GetGroup(group); + } + } + } + catch (Exception ex) + { + Log.ConsoleError("GetGroupForIP SQL returned an error: " + ex); + } + return TShock.Utils.GetGroup(TShock.Config.DefaultGuestGroupName); + } - public Group GetGroupForIPExpensive(string ip) - { - try - { - using (var reader = database.QueryReader("SELECT IP, UserGroup FROM Users")) - { - while (reader.Read()) - { - if (TShock.Utils.GetIPv4Address(reader.Get("IP")) == ip) - { - return TShock.Utils.GetGroup(reader.Get("UserGroup")); - } - } - } - } - catch (Exception ex) - { - Log.ConsoleError("GetGroupForIP SQL returned an error: " + ex); - } - return TShock.Utils.GetGroup(TShock.Config.DefaultGuestGroupName); - } + public Group GetGroupForIPExpensive(string ip) + { + try + { + using (var reader = database.QueryReader("SELECT IP, UserGroup FROM Users")) + { + while (reader.Read()) + { + if (TShock.Utils.GetIPv4Address(reader.Get("IP")) == ip) + { + return TShock.Utils.GetGroup(reader.Get("UserGroup")); + } + } + } + } + catch (Exception ex) + { + Log.ConsoleError("GetGroupForIP SQL returned an error: " + ex); + } + return TShock.Utils.GetGroup(TShock.Config.DefaultGuestGroupName); + } - public User GetUserByName(string name) - { - try - { - return GetUser(new User { Name = name }); - } - catch (UserManagerException) - { - return null; - } - } - public User GetUserByID(int id) - { - try - { - return GetUser(new User { ID = id }); - } - catch (UserManagerException) - { - return null; - } - } - public User GetUserByIP(string ip) - { - try - { - return GetUser(new User { Address = ip }); - } - catch (UserManagerException) - { - return null; - } - } - public User GetUser(User user) - { - try - { - QueryResult result; - if (string.IsNullOrEmpty(user.Address)) - { - result = database.QueryReader("SELECT * FROM Users WHERE Username=@0", user.Name); - } - else - { - result = database.QueryReader("SELECT * FROM Users WHERE IP=@0", user.Address); - } + public User GetUserByName(string name) + { + try + { + return GetUser(new User {Name = name}); + } + catch (UserManagerException) + { + return null; + } + } - using (var reader = result) - { - if (reader.Read()) - { - user.ID = reader.Get("ID"); - user.Group = reader.Get("Usergroup"); - user.Password = reader.Get("Password"); - user.Name = reader.Get("Username"); - user.Address = reader.Get("IP"); - return user; - } - } - } - catch (Exception ex) - { - throw new UserManagerException("GetUserID SQL returned an error", ex); - } - throw new UserNotExistException(string.IsNullOrEmpty(user.Address) ? user.Name : user.Address); - } - } + public User GetUserByID(int id) + { + try + { + return GetUser(new User {ID = id}); + } + catch (UserManagerException) + { + return null; + } + } - public class User - { - public int ID { get; set; } - public string Name { get; set; } - public string Password { get; set; } - public string Group { get; set; } - public string Address { get; set; } + public User GetUserByIP(string ip) + { + try + { + return GetUser(new User {Address = ip}); + } + catch (UserManagerException) + { + return null; + } + } - public User(string ip, string name, string pass, string group) - { - Address = ip; - Name = name; - Password = pass; - Group = group; - } - public User() - { - Address = ""; - Name = ""; - Password = ""; - Group = ""; - } - } + public User GetUser(User user) + { + try + { + QueryResult result; + if (string.IsNullOrEmpty(user.Address)) + { + result = database.QueryReader("SELECT * FROM Users WHERE Username=@0", user.Name); + } + else + { + result = database.QueryReader("SELECT * FROM Users WHERE IP=@0", user.Address); + } - [Serializable] - public class UserManagerException : Exception - { - public UserManagerException(string message) - : base(message) - { + using (var reader = result) + { + if (reader.Read()) + { + user.ID = reader.Get("ID"); + user.Group = reader.Get("Usergroup"); + user.Password = reader.Get("Password"); + user.Name = reader.Get("Username"); + user.Address = reader.Get("IP"); + return user; + } + } + } + catch (Exception ex) + { + throw new UserManagerException("GetUserID SQL returned an error", ex); + } + throw new UserNotExistException(string.IsNullOrEmpty(user.Address) ? user.Name : user.Address); + } + } - } - public UserManagerException(string message, Exception inner) - : base(message, inner) - { + public class User + { + public int ID { get; set; } + public string Name { get; set; } + public string Password { get; set; } + public string Group { get; set; } + public string Address { get; set; } - } - } - [Serializable] - public class UserExistsException : UserManagerException - { - public UserExistsException(string name) - : base("User '" + name + "' already exists") - { - } - } - [Serializable] - public class UserNotExistException : UserManagerException - { - public UserNotExistException(string name) - : base("User '" + name + "' does not exist") - { - } - } - [Serializable] - public class GroupNotExistsException : UserManagerException - { - public GroupNotExistsException(string group) - : base("Group '" + group + "' does not exist") - { - } - } -} + public User(string ip, string name, string pass, string group) + { + Address = ip; + Name = name; + Password = pass; + Group = group; + } + + public User() + { + Address = ""; + Name = ""; + Password = ""; + Group = ""; + } + } + + [Serializable] + public class UserManagerException : Exception + { + public UserManagerException(string message) + : base(message) + { + } + + public UserManagerException(string message, Exception inner) + : base(message, inner) + { + } + } + + [Serializable] + public class UserExistsException : UserManagerException + { + public UserExistsException(string name) + : base("User '" + name + "' already exists") + { + } + } + + [Serializable] + public class UserNotExistException : UserManagerException + { + public UserNotExistException(string name) + : base("User '" + name + "' does not exist") + { + } + } + + [Serializable] + public class GroupNotExistsException : UserManagerException + { + public GroupNotExistsException(string group) + : base("Group '" + group + "' does not exist") + { + } + } +} \ No newline at end of file diff --git a/TShockAPI/DB/WarpsManager.cs b/TShockAPI/DB/WarpsManager.cs index 54e1d10e..174ec3f3 100644 --- a/TShockAPI/DB/WarpsManager.cs +++ b/TShockAPI/DB/WarpsManager.cs @@ -27,245 +27,251 @@ using Terraria; namespace TShockAPI.DB { - public class WarpManager - { - private IDbConnection database; + public class WarpManager + { + private IDbConnection database; - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] - public WarpManager(IDbConnection db) - { - database = db; + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] + public WarpManager(IDbConnection db) + { + database = db; - var table = new SqlTable("Warps", - new SqlColumn("WarpName", MySqlDbType.VarChar, 50) { Primary = true }, - new SqlColumn("X", MySqlDbType.Int32), - new SqlColumn("Y", MySqlDbType.Int32), - new SqlColumn("WorldID", MySqlDbType.Text), - new SqlColumn("Private", MySqlDbType.Text) - ); - var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator()); - creator.EnsureExists(table); + var table = new SqlTable("Warps", + new SqlColumn("WarpName", MySqlDbType.VarChar, 50) {Primary = true}, + new SqlColumn("X", MySqlDbType.Int32), + new SqlColumn("Y", MySqlDbType.Int32), + new SqlColumn("WorldID", MySqlDbType.Text), + new SqlColumn("Private", MySqlDbType.Text) + ); + var creator = new SqlTableCreator(db, + db.GetSqlType() == SqlType.Sqlite + ? (IQueryBuilder) new SqliteQueryCreator() + : new MysqlQueryCreator()); + creator.EnsureExists(table); - String file = Path.Combine(TShock.SavePath, "warps.xml"); - String name = ""; - String world = ""; - int x1 = 0; - int y1 = 0; - if (!File.Exists(file)) - return; + String file = Path.Combine(TShock.SavePath, "warps.xml"); + String name = ""; + String world = ""; + int x1 = 0; + int y1 = 0; + if (!File.Exists(file)) + return; - using (var reader = XmlReader.Create(new StreamReader(file), new XmlReaderSettings { CloseInput = true })) - { - // Parse the file and display each of the nodes. - while (reader.Read()) - { - switch (reader.NodeType) - { - case XmlNodeType.Element: - switch (reader.Name) - { - case "Warp": - name = ""; - world = ""; - x1 = 0; - y1 = 0; - break; - case "WarpName": - while (reader.NodeType != XmlNodeType.Text) - reader.Read(); - name = reader.Value; - break; - case "X": - while (reader.NodeType != XmlNodeType.Text) - reader.Read(); - int.TryParse(reader.Value, out x1); - break; - case "Y": - while (reader.NodeType != XmlNodeType.Text) - reader.Read(); - int.TryParse(reader.Value, out y1); - break; - case "WorldName": - while (reader.NodeType != XmlNodeType.Text) - reader.Read(); - world = reader.Value; - break; - } - break; - case XmlNodeType.Text: + using (var reader = XmlReader.Create(new StreamReader(file), new XmlReaderSettings {CloseInput = true})) + { + // Parse the file and display each of the nodes. + while (reader.Read()) + { + switch (reader.NodeType) + { + case XmlNodeType.Element: + switch (reader.Name) + { + case "Warp": + name = ""; + world = ""; + x1 = 0; + y1 = 0; + break; + case "WarpName": + while (reader.NodeType != XmlNodeType.Text) + reader.Read(); + name = reader.Value; + break; + case "X": + while (reader.NodeType != XmlNodeType.Text) + reader.Read(); + int.TryParse(reader.Value, out x1); + break; + case "Y": + while (reader.NodeType != XmlNodeType.Text) + reader.Read(); + int.TryParse(reader.Value, out y1); + break; + case "WorldName": + while (reader.NodeType != XmlNodeType.Text) + reader.Read(); + world = reader.Value; + break; + } + break; + case XmlNodeType.Text: - break; - case XmlNodeType.XmlDeclaration: - case XmlNodeType.ProcessingInstruction: - break; - case XmlNodeType.Comment: - break; - case XmlNodeType.EndElement: - if (reader.Name.Equals("Warp")) - { - string query = (TShock.Config.StorageType.ToLower() == "sqlite") - ? "INSERT OR IGNORE INTO Warps VALUES (@0, @1,@2, @3);" - : "INSERT IGNORE INTO Warps SET X=@0, Y=@1, WarpName=@2, WorldID=@3;"; - database.Query(query, x1, y1, name, world); - } - break; - } - } + break; + case XmlNodeType.XmlDeclaration: + case XmlNodeType.ProcessingInstruction: + break; + case XmlNodeType.Comment: + break; + case XmlNodeType.EndElement: + if (reader.Name.Equals("Warp")) + { + string query = (TShock.Config.StorageType.ToLower() == "sqlite") + ? "INSERT OR IGNORE INTO Warps VALUES (@0, @1,@2, @3);" + : "INSERT IGNORE INTO Warps SET X=@0, Y=@1, WarpName=@2, WorldID=@3;"; + database.Query(query, x1, y1, name, world); + } + break; + } + } + } - } + String path = Path.Combine(TShock.SavePath, "old_configs"); + String file2 = Path.Combine(path, "warps.xml"); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + if (File.Exists(file2)) + File.Delete(file2); + File.Move(file, file2); + } - String path = Path.Combine(TShock.SavePath, "old_configs"); - String file2 = Path.Combine(path, "warps.xml"); - if (!Directory.Exists(path)) - Directory.CreateDirectory(path); - if (File.Exists(file2)) - File.Delete(file2); - File.Move(file, file2); - } + public void ConvertDB() + { + try + { + database.Query("UPDATE Warps SET WorldID=@0", Main.worldID.ToString()); + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } - public void ConvertDB() - { - try - { - database.Query("UPDATE Warps SET WorldID=@0", Main.worldID.ToString()); - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } + public bool AddWarp(int x, int y, string name, string worldid) + { + try + { + database.Query("INSERT INTO Warps (X, Y, WarpName, WorldID) VALUES (@0, @1, @2, @3);", x, y, name, worldid); + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; + } - public bool AddWarp(int x, int y, string name, string worldid) - { - try - { - database.Query("INSERT INTO Warps (X, Y, WarpName, WorldID) VALUES (@0, @1, @2, @3);", x, y, name, worldid); - return true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return false; - } + public bool RemoveWarp(string name) + { + try + { + database.Query("DELETE FROM Warps WHERE WarpName=@0 AND WorldID=@1", name, Main.worldID.ToString()); + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; + } - public bool RemoveWarp(string name) - { - try - { - database.Query("DELETE FROM Warps WHERE WarpName=@0 AND WorldID=@1", name, Main.worldID.ToString()); - return true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return false; - } + public Warp FindWarp(string name) + { + try + { + using ( + var reader = database.QueryReader("SELECT * FROM Warps WHERE WarpName=@0 AND WorldID=@1", name, + Main.worldID.ToString())) + { + if (reader.Read()) + { + try + { + return new Warp(new Vector2(reader.Get("X"), reader.Get("Y")), reader.Get("WarpName"), + reader.Get("WorldID"), reader.Get("Private")); + } + catch + { + return new Warp(new Vector2(reader.Get("X"), reader.Get("Y")), reader.Get("WarpName"), + reader.Get("WorldID"), "0"); + } + } + } + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return new Warp(); + } - public Warp FindWarp(string name) - { - try - { - using (var reader = database.QueryReader("SELECT * FROM Warps WHERE WarpName=@0 AND WorldID=@1", name, Main.worldID.ToString())) - { - if (reader.Read()) - { - try - { - return new Warp(new Vector2(reader.Get("X"), reader.Get("Y")), reader.Get("WarpName"), reader.Get("WorldID"), reader.Get("Private")); - } - catch - { - return new Warp(new Vector2(reader.Get("X"), reader.Get("Y")), reader.Get("WarpName"), reader.Get("WorldID"), "0"); - } - } - } - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return new Warp(); - } + /// + /// Gets all the warps names from world + /// + /// World name to get warps from + /// List of warps with only their names + public List ListAllPublicWarps(string worldid) + { + var warps = new List(); + try + { + using (var reader = database.QueryReader("SELECT * FROM Warps WHERE WorldID=@0", worldid)) + { + while (reader.Read()) + { + try + { + if (reader.Get("Private") == "0" || reader.Get("Private") == null) + warps.Add(new Warp {WarpName = reader.Get("WarpName")}); + } + catch + { + warps.Add(new Warp {WarpName = reader.Get("WarpName")}); + } + } + } + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return warps; + } - /// - /// Gets all the warps names from world - /// - /// World name to get warps from - /// List of warps with only their names - public List ListAllPublicWarps(string worldid) - { - var warps = new List(); - try - { - using (var reader = database.QueryReader("SELECT * FROM Warps WHERE WorldID=@0", worldid)) - { - while (reader.Read()) - { - try - { - if (reader.Get("Private") == "0" || reader.Get("Private") == null) - warps.Add(new Warp { WarpName = reader.Get("WarpName") }); - } - catch - { - warps.Add(new Warp { WarpName = reader.Get("WarpName") }); - } - } - } - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return warps; - } + /// + /// Gets all the warps names from world + /// + /// World name to get warps from + /// List of warps with only their names + public bool HideWarp(string warp, bool state) + { + try + { + string query = "UPDATE Warps SET Private=@0 WHERE WarpName=@1 AND WorldID=@2"; - /// - /// Gets all the warps names from world - /// - /// World name to get warps from - /// List of warps with only their names - public bool HideWarp(string warp, bool state) - { - try - { - string query = "UPDATE Warps SET Private=@0 WHERE WarpName=@1 AND WorldID=@2"; + database.Query(query, state ? "1" : "0", warp, Main.worldID.ToString()); - database.Query(query, state ? "1" : "0", warp, Main.worldID.ToString()); + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + return false; + } + } + } - return true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - return false; - } - } - } + public class Warp + { + public Vector2 WarpPos { get; set; } + public string WarpName { get; set; } + public string WorldWarpID { get; set; } + public string Private { get; set; } - public class Warp - { - public Vector2 WarpPos { get; set; } - public string WarpName { get; set; } - public string WorldWarpID { get; set; } - public string Private { get; set; } + public Warp(Vector2 warppos, string name, string worldid, string hidden) + { + WarpPos = warppos; + WarpName = name; + WorldWarpID = worldid; + Private = hidden; + } - public Warp(Vector2 warppos, string name, string worldid, string hidden) - { - WarpPos = warppos; - WarpName = name; - WorldWarpID = worldid; - Private = hidden; - } - - public Warp() - { - WarpPos = Vector2.Zero; - WarpName = null; - WorldWarpID = string.Empty; - Private = "0"; - } - } -} + public Warp() + { + WarpPos = Vector2.Zero; + WarpName = null; + WorldWarpID = string.Empty; + Private = "0"; + } + } +} \ No newline at end of file diff --git a/TShockAPI/Extensions/DbExt.cs b/TShockAPI/Extensions/DbExt.cs index 4fdb2dd4..e98bfd83 100644 --- a/TShockAPI/Extensions/DbExt.cs +++ b/TShockAPI/Extensions/DbExt.cs @@ -5,183 +5,214 @@ using System.Diagnostics.CodeAnalysis; namespace TShockAPI.DB { - public static class DbExt - { + public static class DbExt + { + /// + /// Executes a query on a database. + /// + /// Database to query + /// Query string with parameters as @0, @1, etc. + /// Parameters to be put in the query + /// Rows affected by query + [SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")] + public static int Query(this IDbConnection olddb, string query, params object[] args) + { + using (var db = olddb.CloneEx()) + { + db.Open(); + using (var com = db.CreateCommand()) + { + com.CommandText = query; + for (int i = 0; i < args.Length; i++) + com.AddParameter("@" + i, args[i]); - /// - /// Executes a query on a database. - /// - /// Database to query - /// Query string with parameters as @0, @1, etc. - /// Parameters to be put in the query - /// Rows affected by query - [SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")] - public static int Query(this IDbConnection olddb, string query, params object[] args) - { - using (var db = olddb.CloneEx()) - { - db.Open(); - using (var com = db.CreateCommand()) - { - com.CommandText = query; - for (int i = 0; i < args.Length; i++) - com.AddParameter("@" + i, args[i]); + return com.ExecuteNonQuery(); + } + } + } - return com.ExecuteNonQuery(); - } - } - } - /// - /// Executes a query on a database. - /// - /// Database to query - /// Query string with parameters as @0, @1, etc. - /// Parameters to be put in the query - /// Query result as IDataReader - [SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")] - public static QueryResult QueryReader(this IDbConnection olddb, string query, params object[] args) - { - var db = olddb.CloneEx(); - db.Open(); - using (var com = db.CreateCommand()) - { - com.CommandText = query; - for (int i = 0; i < args.Length; i++) - com.AddParameter("@" + i, args[i]); + /// + /// Executes a query on a database. + /// + /// Database to query + /// Query string with parameters as @0, @1, etc. + /// Parameters to be put in the query + /// Query result as IDataReader + [SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")] + public static QueryResult QueryReader(this IDbConnection olddb, string query, params object[] args) + { + var db = olddb.CloneEx(); + db.Open(); + using (var com = db.CreateCommand()) + { + com.CommandText = query; + for (int i = 0; i < args.Length; i++) + com.AddParameter("@" + i, args[i]); - return new QueryResult(db, com.ExecuteReader()); - } - } + return new QueryResult(db, com.ExecuteReader()); + } + } - public static QueryResult QueryReaderDict(this IDbConnection olddb, string query, Dictionary values) - { - var db = olddb.CloneEx(); - db.Open(); - using (var com = db.CreateCommand()) - { - com.CommandText = query; - foreach(var kv in values) - com.AddParameter("@" + kv.Key, kv.Value); + public static QueryResult QueryReaderDict(this IDbConnection olddb, string query, Dictionary values) + { + var db = olddb.CloneEx(); + db.Open(); + using (var com = db.CreateCommand()) + { + com.CommandText = query; + foreach (var kv in values) + com.AddParameter("@" + kv.Key, kv.Value); - return new QueryResult(db, com.ExecuteReader()); - } - } + return new QueryResult(db, com.ExecuteReader()); + } + } - public static IDbDataParameter AddParameter(this IDbCommand command, string name, object data) - { - var parm = command.CreateParameter(); - parm.ParameterName = name; - parm.Value = data; - command.Parameters.Add(parm); - return parm; - } + public static IDbDataParameter AddParameter(this IDbCommand command, string name, object data) + { + var parm = command.CreateParameter(); + parm.ParameterName = name; + parm.Value = data; + command.Parameters.Add(parm); + return parm; + } - public static IDbConnection CloneEx(this IDbConnection conn) - { - var clone = (IDbConnection)Activator.CreateInstance(conn.GetType()); - clone.ConnectionString = conn.ConnectionString; - return clone; - } + public static IDbConnection CloneEx(this IDbConnection conn) + { + var clone = (IDbConnection) Activator.CreateInstance(conn.GetType()); + clone.ConnectionString = conn.ConnectionString; + return clone; + } - public static SqlType GetSqlType(this IDbConnection conn) - { - var name = conn.GetType().Name; - if (name == "SqliteConnection") - return SqlType.Sqlite; - if (name == "MySqlConnection") - return SqlType.Mysql; - return SqlType.Unknown; - } + public static SqlType GetSqlType(this IDbConnection conn) + { + var name = conn.GetType().Name; + if (name == "SqliteConnection") + return SqlType.Sqlite; + if (name == "MySqlConnection") + return SqlType.Mysql; + return SqlType.Unknown; + } - static readonly Dictionary> ReadFuncs = new Dictionary> - { - {typeof(bool), (s, i) => s.GetBoolean(i)}, - {typeof(byte), (s, i) => s.GetByte(i)}, - {typeof(Int16), (s, i) => s.GetInt16(i)}, - {typeof(Int32), (s, i) => s.GetInt32(i)}, - {typeof(Int64), (s, i) => s.GetInt64(i)}, - {typeof(string), (s, i) => s.GetString(i)}, - {typeof(decimal), (s, i) => s.GetDecimal(i)}, - {typeof(float), (s, i) => s.GetFloat(i)}, - {typeof(double), (s, i) => s.GetDouble(i)}, - {typeof(object), (s, i) => s.GetValue(i)}, - }; + private static readonly Dictionary> ReadFuncs = new Dictionary + > + { + { + typeof (bool), + (s, i) => s.GetBoolean(i) + }, + { + typeof (byte), + (s, i) => s.GetByte(i) + }, + { + typeof (Int16), + (s, i) => s.GetInt16(i) + }, + { + typeof (Int32), + (s, i) => s.GetInt32(i) + }, + { + typeof (Int64), + (s, i) => s.GetInt64(i) + }, + { + typeof (string), + (s, i) => s.GetString(i) + }, + { + typeof (decimal), + (s, i) => s.GetDecimal(i) + }, + { + typeof (float), + (s, i) => s.GetFloat(i) + }, + { + typeof (double), + (s, i) => s.GetDouble(i) + }, + { + typeof (object), + (s, i) => s.GetValue(i) + }, + }; - public static T Get(this IDataReader reader, string column) - { - return reader.Get(reader.GetOrdinal(column)); - } + public static T Get(this IDataReader reader, string column) + { + return reader.Get(reader.GetOrdinal(column)); + } - public static T Get(this IDataReader reader, int column) - { - if (reader.IsDBNull(column)) - return default(T); + public static T Get(this IDataReader reader, int column) + { + if (reader.IsDBNull(column)) + return default(T); - if (ReadFuncs.ContainsKey(typeof(T))) - return (T)ReadFuncs[typeof(T)](reader, column); + if (ReadFuncs.ContainsKey(typeof (T))) + return (T) ReadFuncs[typeof (T)](reader, column); - throw new NotImplementedException(); - } - } + throw new NotImplementedException(); + } + } - public enum SqlType - { - Unknown, - Sqlite, - Mysql - } + public enum SqlType + { + Unknown, + Sqlite, + Mysql + } - public class QueryResult : IDisposable - { - public IDbConnection Connection { get; protected set; } - public IDataReader Reader { get; protected set; } + public class QueryResult : IDisposable + { + public IDbConnection Connection { get; protected set; } + public IDataReader Reader { get; protected set; } - public QueryResult(IDbConnection conn, IDataReader reader) - { - Connection = conn; - Reader = reader; - } + public QueryResult(IDbConnection conn, IDataReader reader) + { + Connection = conn; + Reader = reader; + } - ~QueryResult() - { - Dispose(false); - } + ~QueryResult() + { + Dispose(false); + } - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (Reader != null) - { - Reader.Dispose(); - Reader = null; - } - if (Connection != null) - { - Connection.Dispose(); - Connection = null; - } - } - } + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (Reader != null) + { + Reader.Dispose(); + Reader = null; + } + if (Connection != null) + { + Connection.Dispose(); + Connection = null; + } + } + } - public bool Read() - { - if (Reader == null) - return false; - return Reader.Read(); - } - public T Get(string column) - { - if (Reader == null) - return default(T); - return Reader.Get(Reader.GetOrdinal(column)); - } - } + public bool Read() + { + if (Reader == null) + return false; + return Reader.Read(); + } -} + public T Get(string column) + { + if (Reader == null) + return default(T); + return Reader.Get(Reader.GetOrdinal(column)); + } + } +} \ No newline at end of file diff --git a/TShockAPI/Extensions/LinqExt.cs b/TShockAPI/Extensions/LinqExt.cs index bd8384fc..965af17e 100644 --- a/TShockAPI/Extensions/LinqExt.cs +++ b/TShockAPI/Extensions/LinqExt.cs @@ -3,15 +3,15 @@ using System.Collections.Generic; namespace TShockAPI { - public static class LinqExt - { - public static void ForEach(this IEnumerable source, Action action) - { - if (source == null) throw new ArgumentNullException("source"); - if (action == null) throw new ArgumentNullException("action"); + public static class LinqExt + { + public static void ForEach(this IEnumerable source, Action action) + { + if (source == null) throw new ArgumentNullException("source"); + if (action == null) throw new ArgumentNullException("action"); - foreach (T item in source) - action(item); - } - } -} + foreach (T item in source) + action(item); + } + } +} \ No newline at end of file diff --git a/TShockAPI/Extensions/RandomExt.cs b/TShockAPI/Extensions/RandomExt.cs index 517e445b..b65050ee 100644 --- a/TShockAPI/Extensions/RandomExt.cs +++ b/TShockAPI/Extensions/RandomExt.cs @@ -3,27 +3,27 @@ using System.Text; namespace TShockAPI.Extensions { - public static class RandomExt - { - public static string NextString(this Random rand, int length) - { - var sb = new StringBuilder(); - for (int i = 0; i < length; i++) - { - switch (rand.Next(0, 3)) - { - case 0: - sb.Append((char)rand.Next('a', 'z' + 1)); - break; - case 1: - sb.Append((char)rand.Next('A', 'Z' + 1)); - break; - case 2: - sb.Append((char)rand.Next('0', '9' + 1)); - break; - } - } - return sb.ToString(); - } - } -} + public static class RandomExt + { + public static string NextString(this Random rand, int length) + { + var sb = new StringBuilder(); + for (int i = 0; i < length; i++) + { + switch (rand.Next(0, 3)) + { + case 0: + sb.Append((char) rand.Next('a', 'z' + 1)); + break; + case 1: + sb.Append((char) rand.Next('A', 'Z' + 1)); + break; + case 2: + sb.Append((char) rand.Next('0', '9' + 1)); + break; + } + } + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/TShockAPI/Extensions/StringExt.cs b/TShockAPI/Extensions/StringExt.cs index 569cd1f8..edbf05fe 100644 --- a/TShockAPI/Extensions/StringExt.cs +++ b/TShockAPI/Extensions/StringExt.cs @@ -2,12 +2,12 @@ namespace TShockAPI { - public static class StringExt - { - //Can't name it Format :( - public static String SFormat(this String str, params object[] args) - { - return String.Format(str, args); - } - } -} + public static class StringExt + { + //Can't name it Format :( + public static String SFormat(this String str, params object[] args) + { + return String.Format(str, args); + } + } +} \ No newline at end of file diff --git a/TShockAPI/FileTools.cs b/TShockAPI/FileTools.cs index 4d5f6b8e..ee05a301 100644 --- a/TShockAPI/FileTools.cs +++ b/TShockAPI/FileTools.cs @@ -20,93 +20,111 @@ using System.IO; namespace TShockAPI { - public class FileTools - { - internal static string RulesPath { get { return Path.Combine(TShock.SavePath, "rules.txt"); } } - internal static string MotdPath { get { return Path.Combine(TShock.SavePath, "motd.txt"); } } - internal static string WhitelistPath { get { return Path.Combine(TShock.SavePath, "whitelist.txt"); } } - internal static string RememberedPosPath { get { return Path.Combine(TShock.SavePath, "oldpos.xml"); } } - internal static string ConfigPath { get { return Path.Combine(TShock.SavePath, "config.json"); } } + public class FileTools + { + internal static string RulesPath + { + get { return Path.Combine(TShock.SavePath, "rules.txt"); } + } - public static void CreateFile(string file) - { - File.Create(file).Close(); - } + internal static string MotdPath + { + get { return Path.Combine(TShock.SavePath, "motd.txt"); } + } - public static void CreateIfNot(string file, string data = "") - { - if (!File.Exists(file)) - { - File.WriteAllText(file, data); - } - } + internal static string WhitelistPath + { + get { return Path.Combine(TShock.SavePath, "whitelist.txt"); } + } - /// - /// Sets up the configuration file for all variables, and creates any missing files. - /// - public static void SetupConfig() - { - if (!Directory.Exists(TShock.SavePath)) - { - Directory.CreateDirectory(TShock.SavePath); - } + internal static string RememberedPosPath + { + get { return Path.Combine(TShock.SavePath, "oldpos.xml"); } + } - CreateIfNot(RulesPath, "Respect the admins!\nDon't use TNT!"); - CreateIfNot(MotdPath, "This server is running TShock. Type /help for a list of commands.\n%255,000,000%Current map: %map%\nCurrent players: %players%"); - CreateIfNot(WhitelistPath); + internal static string ConfigPath + { + get { return Path.Combine(TShock.SavePath, "config.json"); } + } - try - { - if (File.Exists(ConfigPath)) - { - TShock.Config = ConfigFile.Read(ConfigPath); - // Add all the missing config properties in the json file - } - TShock.Config.Write(ConfigPath); - } - catch (Exception ex) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine("Error in config file"); - Console.ForegroundColor = ConsoleColor.Gray; - Log.Error("Config Exception"); - Log.Error(ex.ToString()); - } + public static void CreateFile(string file) + { + File.Create(file).Close(); + } + public static void CreateIfNot(string file, string data = "") + { + if (!File.Exists(file)) + { + File.WriteAllText(file, data); + } + } - } + /// + /// Sets up the configuration file for all variables, and creates any missing files. + /// + public static void SetupConfig() + { + if (!Directory.Exists(TShock.SavePath)) + { + Directory.CreateDirectory(TShock.SavePath); + } - /// - /// Tells if a user is on the whitelist - /// - /// string ip of the user - /// true/false - public static bool OnWhitelist(string ip) - { - if (!TShock.Config.EnableWhitelist) - { - return true; - } - CreateIfNot(WhitelistPath, "127.0.0.1"); - using (var tr = new StreamReader(WhitelistPath)) - { - string whitelist = tr.ReadToEnd(); - ip = TShock.Utils.GetRealIP(ip); - bool contains = whitelist.Contains(ip); - if (!contains) - { - foreach (var line in whitelist.Split(Environment.NewLine.ToCharArray())) - { - if (string.IsNullOrWhiteSpace(line)) - continue; - contains = TShock.Utils.GetIPv4Address(line).Equals(ip); - if (contains) - return true; - } - return false; - } - return true; - } - } - } + CreateIfNot(RulesPath, "Respect the admins!\nDon't use TNT!"); + CreateIfNot(MotdPath, + "This server is running TShock. Type /help for a list of commands.\n%255,000,000%Current map: %map%\nCurrent players: %players%"); + CreateIfNot(WhitelistPath); + + try + { + if (File.Exists(ConfigPath)) + { + TShock.Config = ConfigFile.Read(ConfigPath); + // Add all the missing config properties in the json file + } + TShock.Config.Write(ConfigPath); + } + catch (Exception ex) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Error in config file"); + Console.ForegroundColor = ConsoleColor.Gray; + Log.Error("Config Exception"); + Log.Error(ex.ToString()); + } + } + + /// + /// Tells if a user is on the whitelist + /// + /// string ip of the user + /// true/false + public static bool OnWhitelist(string ip) + { + if (!TShock.Config.EnableWhitelist) + { + return true; + } + CreateIfNot(WhitelistPath, "127.0.0.1"); + using (var tr = new StreamReader(WhitelistPath)) + { + string whitelist = tr.ReadToEnd(); + ip = TShock.Utils.GetRealIP(ip); + bool contains = whitelist.Contains(ip); + if (!contains) + { + foreach (var line in whitelist.Split(Environment.NewLine.ToCharArray())) + { + if (string.IsNullOrWhiteSpace(line)) + continue; + contains = TShock.Utils.GetIPv4Address(line).Equals(ip); + if (contains) + return true; + } + return false; + } + return true; + } + } + } } \ No newline at end of file diff --git a/TShockAPI/GeoIPCountry.cs b/TShockAPI/GeoIPCountry.cs index 44ca4a19..0301bb00 100644 --- a/TShockAPI/GeoIPCountry.cs +++ b/TShockAPI/GeoIPCountry.cs @@ -27,234 +27,290 @@ using System.Net.Sockets; namespace MaxMind { - /// - /// Allows for looking up a country based on an IP address. See www.maxmind.com for more details. - /// - /// - /// static void Main(string[] args) - /// { - /// using(GeoIPCountry geo = new GeoIPCountry("GeoIP.dat")) - /// { - /// try - /// { - /// Console.WriteLine("Country code of IP address 67.15.94.80: " + geo.GetCountryCode("67.15.94.80")); - /// } - /// catch(Exception ex) - /// { - /// Console.WriteLine(ex.ToString()); - /// } - /// } - /// } - /// - public sealed class GeoIPCountry : IDisposable - { - Stream _geodata; - bool _close; + /// + /// Allows for looking up a country based on an IP address. See www.maxmind.com for more details. + /// + /// + /// static void Main(string[] args) + /// { + /// using(GeoIPCountry geo = new GeoIPCountry("GeoIP.dat")) + /// { + /// try + /// { + /// Console.WriteLine("Country code of IP address 67.15.94.80: " + geo.GetCountryCode("67.15.94.80")); + /// } + /// catch(Exception ex) + /// { + /// Console.WriteLine(ex.ToString()); + /// } + /// } + /// } + /// + public sealed class GeoIPCountry : IDisposable + { + private Stream _geodata; + private bool _close; - // hard coded position of where country data starts in the data file. - const long COUNTRY_BEGIN = 16776960; + // hard coded position of where country data starts in the data file. + private const long COUNTRY_BEGIN = 16776960; - static readonly string[] CountryCodes = { - "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","AN","AO","AQ","AR","AS", - "AT","AU","AW","AZ","BA","BB","BD","BE","BF","BG","BH","BI","BJ","BM","BN", - "BO","BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD","CF","CG","CH","CI", - "CK","CL","CM","CN","CO","CR","CU","CV","CX","CY","CZ","DE","DJ","DK","DM", - "DO","DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ","FK","FM","FO","FR", - "FX","GA","GB","GD","GE","GF","GH","GI","GL","GM","GN","GP","GQ","GR","GS", - "GT","GU","GW","GY","HK","HM","HN","HR","HT","HU","ID","IE","IL","IN","IO", - "IQ","IR","IS","IT","JM","JO","JP","KE","KG","KH","KI","KM","KN","KP","KR", - "KW","KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT","LU","LV","LY","MA", - "MC","MD","MG","MH","MK","ML","MM","MN","MO","MP","MQ","MR","MS","MT","MU", - "MV","MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI","NL","NO","NP","NR", - "NU","NZ","OM","PA","PE","PF","PG","PH","PK","PL","PM","PN","PR","PS","PT", - "PW","PY","QA","RE","RO","RU","RW","SA","SB","SC","SD","SE","SG","SH","SI", - "SJ","SK","SL","SM","SN","SO","SR","ST","SV","SY","SZ","TC","TD","TF","TG", - "TH","TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW","TZ","UA","UG","UM", - "US","UY","UZ","VA","VC","VE","VG","VI","VN","VU","WF","WS","YE","YT","RS", - "ZA","ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE","BL","MF" - }; + private static readonly string[] CountryCodes = { + "--", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", + "AO", "AQ", "AR", "AS", + "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", + "BI", "BJ", "BM", "BN", + "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", + "CF", "CG", "CH", "CI", + "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CX", "CY", "CZ", + "DE", "DJ", "DK", "DM", + "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", + "FK", "FM", "FO", "FR", + "FX", "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GL", "GM", "GN", + "GP", "GQ", "GR", "GS", + "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", + "IE", "IL", "IN", "IO", + "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", + "KM", "KN", "KP", "KR", + "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", + "LU", "LV", "LY", "MA", + "MC", "MD", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", + "MR", "MS", "MT", "MU", + "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", + "NL", "NO", "NP", "NR", + "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", + "PN", "PR", "PS", "PT", + "PW", "PY", "QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", + "SE", "SG", "SH", "SI", + "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", + "TC", "TD", "TF", "TG", + "TH", "TJ", "TK", "TM", "TN", "TO", "TL", "TR", "TT", "TV", "TW", + "TZ", "UA", "UG", "UM", + "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", + "WS", "YE", "YT", "RS", + "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1", "AX", "GG", "IM", "JE", + "BL", "MF" + }; - static readonly string[] CountryNames = { - "N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan", - "Antigua and Barbuda","Anguilla","Albania","Armenia","Netherlands Antilles","Angola", - "Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan", - "Bosnia and Herzegovina","Barbados","Bangladesh","Belgium","Burkina Faso","Bulgaria", - "Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia","Brazil","Bahamas", - "Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands", - "Congo, The Democratic Republic of the","Central African Republic","Congo","Switzerland", - "Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica","Cuba", - "Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark", - "Dominica","Dominican Republic","Algeria","Ecuador","Estonia","Egypt","Western Sahara", - "Eritrea","Spain","Ethiopia","Finland","Fiji","Falkland Islands (Malvinas)", - "Micronesia, Federated States of","Faroe Islands","France","France, Metropolitan","Gabon", - "United Kingdom","Grenada","Georgia","French Guiana","Ghana","Gibraltar","Greenland", - "Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece", - "South Georgia and the South Sandwich Islands","Guatemala","Guam","Guinea-Bissau","Guyana", - "Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary", - "Indonesia","Ireland","Israel","India","British Indian Ocean Territory","Iraq", - "Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan","Japan","Kenya", - "Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis", - "Korea, Democratic People's Republic of","Korea, Republic of","Kuwait","Cayman Islands", - "Kazakstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein", - "Sri Lanka","Liberia","Lesotho","Lithuania","Luxembourg","Latvia","Libyan Arab Jamahiriya", - "Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia", - "Mali","Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania", - "Montserrat","Malta","Mauritius","Maldives","Malawi","Mexico","Malaysia","Mozambique", - "Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua","Netherlands", - "Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia", - "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon", - "Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau","Paraguay", - "Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia", - "Solomon Islands","Seychelles","Sudan","Sweden","Singapore","Saint Helena","Slovenia", - "Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia", - "Suriname","Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland", - "Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand", - "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey", - "Trinidad and Tobago","Tuvalu","Taiwan","Tanzania, United Republic of","Ukraine","Uganda", - "United States Minor Outlying Islands","United States","Uruguay","Uzbekistan", - "Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela", - "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna", - "Samoa","Yemen","Mayotte","Serbia","South Africa","Zambia","Montenegro","Zimbabwe", - "Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man", - "Jersey","Saint Barthelemy","Saint Martin" - }; + private static readonly string[] CountryNames = { + "N/A", "Asia/Pacific Region", "Europe", "Andorra", + "United Arab Emirates", "Afghanistan", + "Antigua and Barbuda", "Anguilla", "Albania", "Armenia", + "Netherlands Antilles", "Angola", + "Antarctica", "Argentina", "American Samoa", "Austria", "Australia", + "Aruba", "Azerbaijan", + "Bosnia and Herzegovina", "Barbados", "Bangladesh", "Belgium", + "Burkina Faso", "Bulgaria", + "Bahrain", "Burundi", "Benin", "Bermuda", "Brunei Darussalam", + "Bolivia", "Brazil", "Bahamas", + "Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize", "Canada", + "Cocos (Keeling) Islands", + "Congo, The Democratic Republic of the", "Central African Republic", + "Congo", "Switzerland", + "Cote D'Ivoire", "Cook Islands", "Chile", "Cameroon", "China", + "Colombia", "Costa Rica", "Cuba", + "Cape Verde", "Christmas Island", "Cyprus", "Czech Republic", + "Germany", "Djibouti", "Denmark", + "Dominica", "Dominican Republic", "Algeria", "Ecuador", "Estonia", + "Egypt", "Western Sahara", + "Eritrea", "Spain", "Ethiopia", "Finland", "Fiji", + "Falkland Islands (Malvinas)", + "Micronesia, Federated States of", "Faroe Islands", "France", + "France, Metropolitan", "Gabon", + "United Kingdom", "Grenada", "Georgia", "French Guiana", "Ghana", + "Gibraltar", "Greenland", + "Gambia", "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece", + "South Georgia and the South Sandwich Islands", "Guatemala", "Guam", + "Guinea-Bissau", "Guyana", + "Hong Kong", "Heard Island and McDonald Islands", "Honduras", + "Croatia", "Haiti", "Hungary", + "Indonesia", "Ireland", "Israel", "India", + "British Indian Ocean Territory", "Iraq", + "Iran, Islamic Republic of", "Iceland", "Italy", "Jamaica", "Jordan", + "Japan", "Kenya", + "Kyrgyzstan", "Cambodia", "Kiribati", "Comoros", + "Saint Kitts and Nevis", + "Korea, Democratic People's Republic of", "Korea, Republic of", + "Kuwait", "Cayman Islands", + "Kazakstan", "Lao People's Democratic Republic", "Lebanon", + "Saint Lucia", "Liechtenstein", + "Sri Lanka", "Liberia", "Lesotho", "Lithuania", "Luxembourg", + "Latvia", "Libyan Arab Jamahiriya", + "Morocco", "Monaco", "Moldova, Republic of", "Madagascar", + "Marshall Islands", "Macedonia", + "Mali", "Myanmar", "Mongolia", "Macau", "Northern Mariana Islands", + "Martinique", "Mauritania", + "Montserrat", "Malta", "Mauritius", "Maldives", "Malawi", "Mexico", + "Malaysia", "Mozambique", + "Namibia", "New Caledonia", "Niger", "Norfolk Island", "Nigeria", + "Nicaragua", "Netherlands", + "Norway", "Nepal", "Nauru", "Niue", "New Zealand", "Oman", "Panama", + "Peru", "French Polynesia", + "Papua New Guinea", "Philippines", "Pakistan", "Poland", + "Saint Pierre and Miquelon", + "Pitcairn Islands", "Puerto Rico", "Palestinian Territory", + "Portugal", "Palau", "Paraguay", + "Qatar", "Reunion", "Romania", "Russian Federation", "Rwanda", + "Saudi Arabia", + "Solomon Islands", "Seychelles", "Sudan", "Sweden", "Singapore", + "Saint Helena", "Slovenia", + "Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino", + "Senegal", "Somalia", + "Suriname", "Sao Tome and Principe", "El Salvador", + "Syrian Arab Republic", "Swaziland", + "Turks and Caicos Islands", "Chad", "French Southern Territories", + "Togo", "Thailand", + "Tajikistan", "Tokelau", "Turkmenistan", "Tunisia", "Tonga", + "Timor-Leste", "Turkey", + "Trinidad and Tobago", "Tuvalu", "Taiwan", + "Tanzania, United Republic of", "Ukraine", "Uganda", + "United States Minor Outlying Islands", "United States", "Uruguay", + "Uzbekistan", + "Holy See (Vatican City State)", "Saint Vincent and the Grenadines", + "Venezuela", + "Virgin Islands, British", "Virgin Islands, U.S.", "Vietnam", + "Vanuatu", "Wallis and Futuna", + "Samoa", "Yemen", "Mayotte", "Serbia", "South Africa", "Zambia", + "Montenegro", "Zimbabwe", + "Anonymous Proxy", "Satellite Provider", "Other", "Aland Islands", + "Guernsey", "Isle of Man", + "Jersey", "Saint Barthelemy", "Saint Martin" + }; - // - // Constructor - // + // + // Constructor + // - /// - /// Initialises a new instance of this class. - /// - /// An already open stream pointing to the contents of a GeoIP.dat file. - /// The stream is not closed when this class is disposed. Be sure to clean up afterwards! - public GeoIPCountry(Stream datafile) - { - _geodata = datafile; - _close = false; - } + /// + /// Initialises a new instance of this class. + /// + /// An already open stream pointing to the contents of a GeoIP.dat file. + /// The stream is not closed when this class is disposed. Be sure to clean up afterwards! + public GeoIPCountry(Stream datafile) + { + _geodata = datafile; + _close = false; + } - /// - /// Initialises a new instance of this class, using an on-disk database. - /// - /// Path to database file. - /// The file will be closed when this class is disposed. - public GeoIPCountry(string filename) - { - FileStream fs = new FileStream(filename, FileMode.Open); - _geodata = fs; - _close = true; - } + /// + /// Initialises a new instance of this class, using an on-disk database. + /// + /// Path to database file. + /// The file will be closed when this class is disposed. + public GeoIPCountry(string filename) + { + FileStream fs = new FileStream(filename, FileMode.Open); + _geodata = fs; + _close = true; + } - /// - /// Retrieves a two-letter code, defined by MaxMind, which details the country the specified IP address is located. - /// - /// IP address to query. - /// A two-letter code string. Throws exceptions on failure. - /// The IP address must be IPv4. - public string GetCountryCode(IPAddress ip) - { - return CountryCodes[FindIndex(ip)]; - } + /// + /// Retrieves a two-letter code, defined by MaxMind, which details the country the specified IP address is located. + /// + /// IP address to query. + /// A two-letter code string. Throws exceptions on failure. + /// The IP address must be IPv4. + public string GetCountryCode(IPAddress ip) + { + return CountryCodes[FindIndex(ip)]; + } - /// - /// Retrieves a two-letter code, defined by MaxMind, which details the country the specified IP address is located. Does not throw exceptions on failure. - /// - /// IP address to query. - /// Two-letter country code or null on failure. - public string TryGetCountryCode(IPAddress ip) - { - try - { - return CountryCodes[FindIndex(ip)]; - } - catch (Exception) - { - return null; - } - } + /// + /// Retrieves a two-letter code, defined by MaxMind, which details the country the specified IP address is located. Does not throw exceptions on failure. + /// + /// IP address to query. + /// Two-letter country code or null on failure. + public string TryGetCountryCode(IPAddress ip) + { + try + { + return CountryCodes[FindIndex(ip)]; + } + catch (Exception) + { + return null; + } + } - /// - /// Gets the English name of a country, by a country code. - /// - /// Country code to look up, returned by GetCountryCode or TryGetCountryCode. - /// English name of the country, or null on failure. - public static string GetCountryNameByCode(string countrycode) - { - int index = Array.IndexOf(CountryCodes, countrycode); - return index == -1 ? null : CountryNames[index]; - } + /// + /// Gets the English name of a country, by a country code. + /// + /// Country code to look up, returned by GetCountryCode or TryGetCountryCode. + /// English name of the country, or null on failure. + public static string GetCountryNameByCode(string countrycode) + { + int index = Array.IndexOf(CountryCodes, countrycode); + return index == -1 ? null : CountryNames[index]; + } - int FindIndex(IPAddress ip) - { - return (int)FindCountryCode(0, AddressToLong(ip), 31); - } + private int FindIndex(IPAddress ip) + { + return (int) FindCountryCode(0, AddressToLong(ip), 31); + } - // Converts an IPv4 address into a long, for reading from geo database - long AddressToLong(IPAddress ip) - { - if (ip.AddressFamily != AddressFamily.InterNetwork) - throw new InvalidOperationException("IP address is not IPv4"); + // Converts an IPv4 address into a long, for reading from geo database + private long AddressToLong(IPAddress ip) + { + if (ip.AddressFamily != AddressFamily.InterNetwork) + throw new InvalidOperationException("IP address is not IPv4"); - long num = 0; - byte[] bytes = ip.GetAddressBytes(); - for (int i = 0; i < 4; ++i) - { - long y = bytes[i]; - if (y < 0) - y += 256; - num += y << ((3 - i) * 8); - } + long num = 0; + byte[] bytes = ip.GetAddressBytes(); + for (int i = 0; i < 4; ++i) + { + long y = bytes[i]; + if (y < 0) + y += 256; + num += y << ((3 - i)*8); + } - return num; - } + return num; + } - // Traverses the GeoIP binary data looking for a country code based - // on the IP address mask - long FindCountryCode(long offset, long ipnum, int depth) - { - byte[] buffer = new byte[6]; // 2 * MAX_RECORD_LENGTH - long[] x = new long[2]; - if (depth < 0) - throw new IOException("Cannot seek GeoIP database"); + // Traverses the GeoIP binary data looking for a country code based + // on the IP address mask + private long FindCountryCode(long offset, long ipnum, int depth) + { + byte[] buffer = new byte[6]; // 2 * MAX_RECORD_LENGTH + long[] x = new long[2]; + if (depth < 0) + throw new IOException("Cannot seek GeoIP database"); - _geodata.Seek(6 * offset, SeekOrigin.Begin); - _geodata.Read(buffer, 0, 6); + _geodata.Seek(6*offset, SeekOrigin.Begin); + _geodata.Read(buffer, 0, 6); - for (int i = 0; i < 2; i++) - { - x[i] = 0; - for (int j = 0; j < 3; j++) - { - int y = buffer[i * 3 + j]; - if (y < 0) - y += 256; - x[i] += (y << (j * 8)); - } - } + for (int i = 0; i < 2; i++) + { + x[i] = 0; + for (int j = 0; j < 3; j++) + { + int y = buffer[i*3 + j]; + if (y < 0) + y += 256; + x[i] += (y << (j*8)); + } + } - if ((ipnum & (1 << depth)) > 0) - { - if (x[1] >= COUNTRY_BEGIN) - return x[1] - COUNTRY_BEGIN; - return FindCountryCode(x[1], ipnum, depth - 1); - } - else - { - if (x[0] >= COUNTRY_BEGIN) - return x[0] - COUNTRY_BEGIN; - return FindCountryCode(x[0], ipnum, depth - 1); - } - } - - public void Dispose() - { - if (_close && _geodata != null) - { - _geodata.Close(); - _geodata = null; - } - } - } -} + if ((ipnum & (1 << depth)) > 0) + { + if (x[1] >= COUNTRY_BEGIN) + return x[1] - COUNTRY_BEGIN; + return FindCountryCode(x[1], ipnum, depth - 1); + } + else + { + if (x[0] >= COUNTRY_BEGIN) + return x[0] - COUNTRY_BEGIN; + return FindCountryCode(x[0], ipnum, depth - 1); + } + } + public void Dispose() + { + if (_close && _geodata != null) + { + _geodata.Close(); + _geodata = null; + } + } + } +} \ No newline at end of file diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 5a77e4d7..78fd9ed4 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -26,523 +26,529 @@ using TShockAPI.Net; namespace TShockAPI { - public delegate bool GetDataHandlerDelegate(GetDataHandlerArgs args); - public class GetDataHandlerArgs : EventArgs - { - public TSPlayer Player { get; private set; } - public MemoryStream Data { get; private set; } + public delegate bool GetDataHandlerDelegate(GetDataHandlerArgs args); - public Player TPlayer - { - get { return Player.TPlayer; } - } + public class GetDataHandlerArgs : EventArgs + { + public TSPlayer Player { get; private set; } + public MemoryStream Data { get; private set; } - public GetDataHandlerArgs(TSPlayer player, MemoryStream data) - { - Player = player; - Data = data; - } - } - public static class GetDataHandlers - { - private static Dictionary GetDataHandlerDelegates; - public static int[] WhitelistBuffMaxTime; + public Player TPlayer + { + get { return Player.TPlayer; } + } - public static void InitGetDataHandler() - { - #region Blacklists + public GetDataHandlerArgs(TSPlayer player, MemoryStream data) + { + Player = player; + Data = data; + } + } - WhitelistBuffMaxTime = new int[Main.maxBuffs]; - WhitelistBuffMaxTime[20] = 600; - WhitelistBuffMaxTime[0x18] = 1200; - WhitelistBuffMaxTime[0x1f] = 120; - WhitelistBuffMaxTime[0x27] = 420; + public static class GetDataHandlers + { + private static Dictionary GetDataHandlerDelegates; + public static int[] WhitelistBuffMaxTime; - #endregion Blacklists + public static void InitGetDataHandler() + { + #region Blacklists - GetDataHandlerDelegates = new Dictionary - { - {PacketTypes.PlayerInfo, HandlePlayerInfo}, - {PacketTypes.PlayerUpdate, HandlePlayerUpdate}, - {PacketTypes.Tile, HandleTile}, - {PacketTypes.TileSendSquare, HandleSendTileSquare}, - {PacketTypes.ProjectileNew, HandleProjectileNew}, - {PacketTypes.TogglePvp, HandleTogglePvp}, - {PacketTypes.TileKill, HandleTileKill}, - {PacketTypes.PlayerKillMe, HandlePlayerKillMe}, - {PacketTypes.LiquidSet, HandleLiquidSet}, - {PacketTypes.PlayerSpawn, HandleSpawn}, - {PacketTypes.SyncPlayers, HandleSync}, - {PacketTypes.ChestGetContents, HandleChestOpen}, - {PacketTypes.ChestItem, HandleChestItem}, - {PacketTypes.SignNew, HandleSign}, - {PacketTypes.PlayerSlot, HandlePlayerSlot}, - {PacketTypes.TileGetSection, HandleGetSection}, - {PacketTypes.UpdateNPCHome, UpdateNPCHome}, - {PacketTypes.PlayerAddBuff, HandlePlayerBuff}, - {PacketTypes.ItemDrop, HandleItemDrop}, - {PacketTypes.PlayerHp, HandlePlayerHp}, - {PacketTypes.PlayerMana, HandlePlayerMana}, - {PacketTypes.PlayerDamage, HandlePlayerDamage}, - {PacketTypes.NpcStrike, HandleNpcStrike}, - {PacketTypes.NpcSpecial, HandleSpecial}, - {PacketTypes.PlayerAnimation, HandlePlayerAnimation}, - {PacketTypes.PlayerBuff, HandlePlayerBuffUpdate}, - {PacketTypes.PasswordSend, HandlePassword}, - {PacketTypes.ContinueConnecting2, HandleConnecting} - }; - } + WhitelistBuffMaxTime = new int[Main.maxBuffs]; + WhitelistBuffMaxTime[20] = 600; + WhitelistBuffMaxTime[0x18] = 1200; + WhitelistBuffMaxTime[0x1f] = 120; + WhitelistBuffMaxTime[0x27] = 420; - public static bool HandlerGetData(PacketTypes type, TSPlayer player, MemoryStream data) - { - GetDataHandlerDelegate handler; - if (GetDataHandlerDelegates.TryGetValue(type, out handler)) - { - try - { - return handler(new GetDataHandlerArgs(player, data)); - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } - return false; - } + #endregion Blacklists - private static bool HandleSync(GetDataHandlerArgs args) - { - return TShock.Config.EnableAntiLag; - } + GetDataHandlerDelegates = new Dictionary + { + {PacketTypes.PlayerInfo, HandlePlayerInfo}, + {PacketTypes.PlayerUpdate, HandlePlayerUpdate}, + {PacketTypes.Tile, HandleTile}, + {PacketTypes.TileSendSquare, HandleSendTileSquare}, + {PacketTypes.ProjectileNew, HandleProjectileNew}, + {PacketTypes.TogglePvp, HandleTogglePvp}, + {PacketTypes.TileKill, HandleTileKill}, + {PacketTypes.PlayerKillMe, HandlePlayerKillMe}, + {PacketTypes.LiquidSet, HandleLiquidSet}, + {PacketTypes.PlayerSpawn, HandleSpawn}, + {PacketTypes.SyncPlayers, HandleSync}, + {PacketTypes.ChestGetContents, HandleChestOpen}, + {PacketTypes.ChestItem, HandleChestItem}, + {PacketTypes.SignNew, HandleSign}, + {PacketTypes.PlayerSlot, HandlePlayerSlot}, + {PacketTypes.TileGetSection, HandleGetSection}, + {PacketTypes.UpdateNPCHome, UpdateNPCHome}, + {PacketTypes.PlayerAddBuff, HandlePlayerBuff}, + {PacketTypes.ItemDrop, HandleItemDrop}, + {PacketTypes.PlayerHp, HandlePlayerHp}, + {PacketTypes.PlayerMana, HandlePlayerMana}, + {PacketTypes.PlayerDamage, HandlePlayerDamage}, + {PacketTypes.NpcStrike, HandleNpcStrike}, + {PacketTypes.NpcSpecial, HandleSpecial}, + {PacketTypes.PlayerAnimation, HandlePlayerAnimation}, + {PacketTypes.PlayerBuff, HandlePlayerBuffUpdate}, + {PacketTypes.PasswordSend, HandlePassword}, + {PacketTypes.ContinueConnecting2, HandleConnecting} + }; + } - private static bool HandlePlayerSlot(GetDataHandlerArgs args) - { - int plr = args.Data.ReadInt8(); - int slot = args.Data.ReadInt8(); - int stack = args.Data.ReadInt8(); - short prefix = args.Data.ReadInt8(); - int type = args.Data.ReadInt16(); + public static bool HandlerGetData(PacketTypes type, TSPlayer player, MemoryStream data) + { + GetDataHandlerDelegate handler; + if (GetDataHandlerDelegates.TryGetValue(type, out handler)) + { + try + { + return handler(new GetDataHandlerArgs(player, data)); + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } + return false; + } - if (plr != args.Player.Index) - { - return true; - } + private static bool HandleSync(GetDataHandlerArgs args) + { + return TShock.Config.EnableAntiLag; + } - if (slot < 0 || slot > NetItem.maxNetInventory) - { - return true; - } + private static bool HandlePlayerSlot(GetDataHandlerArgs args) + { + int plr = args.Data.ReadInt8(); + int slot = args.Data.ReadInt8(); + int stack = args.Data.ReadInt8(); + short prefix = args.Data.ReadInt8(); + int type = args.Data.ReadInt16(); - var item = new Item(); - item.netDefaults(type); - item.Prefix(prefix); + if (plr != args.Player.Index) + { + return true; + } - if (args.Player.IsLoggedIn) - { - args.Player.PlayerData.StoreSlot(slot, type, prefix, stack); - } + if (slot < 0 || slot > NetItem.maxNetInventory) + { + return true; + } - return false; - } + var item = new Item(); + item.netDefaults(type); + item.Prefix(prefix); - private static bool HandlePlayerHp(GetDataHandlerArgs args) - { - int plr = args.Data.ReadInt8(); - int cur = args.Data.ReadInt16(); - int max = args.Data.ReadInt16(); + if (args.Player.IsLoggedIn) + { + args.Player.PlayerData.StoreSlot(slot, type, prefix, stack); + } - if (args.Player.FirstMaxHP == 0) - args.Player.FirstMaxHP = max; + return false; + } - if (max > 400 && max > args.Player.FirstMaxHP) - { - TShock.Utils.ForceKick(args.Player, "Hacked Client Detected."); - return false; - } + private static bool HandlePlayerHp(GetDataHandlerArgs args) + { + int plr = args.Data.ReadInt8(); + int cur = args.Data.ReadInt16(); + int max = args.Data.ReadInt16(); - if (args.Player.IsLoggedIn) - { - args.Player.PlayerData.maxHealth = max; - } + if (args.Player.FirstMaxHP == 0) + args.Player.FirstMaxHP = max; - return false; - } + if (max > 400 && max > args.Player.FirstMaxHP) + { + TShock.Utils.ForceKick(args.Player, "Hacked Client Detected."); + return false; + } - private static bool HandlePlayerMana(GetDataHandlerArgs args) - { - int plr = args.Data.ReadInt8(); - int cur = args.Data.ReadInt16(); - int max = args.Data.ReadInt16(); + if (args.Player.IsLoggedIn) + { + args.Player.PlayerData.maxHealth = max; + } - if (args.Player.FirstMaxMP == 0) - args.Player.FirstMaxMP = max; + return false; + } - if (max > 400 && max > args.Player.FirstMaxMP) - { - TShock.Utils.ForceKick(args.Player, "Hacked Client Detected."); - return false; - } + private static bool HandlePlayerMana(GetDataHandlerArgs args) + { + int plr = args.Data.ReadInt8(); + int cur = args.Data.ReadInt16(); + int max = args.Data.ReadInt16(); - return false; - } + if (args.Player.FirstMaxMP == 0) + args.Player.FirstMaxMP = max; - private static bool HandlePlayerInfo(GetDataHandlerArgs args) - { - var playerid = args.Data.ReadInt8(); - var hair = args.Data.ReadInt8(); - var male = args.Data.ReadInt8(); - args.Data.Position += 21; - var difficulty = args.Data.ReadInt8(); - string name = Encoding.ASCII.GetString(args.Data.ReadBytes((int)(args.Data.Length - args.Data.Position - 1))); + if (max > 400 && max > args.Player.FirstMaxMP) + { + TShock.Utils.ForceKick(args.Player, "Hacked Client Detected."); + return false; + } - if (!TShock.Utils.ValidString(name)) - { - TShock.Utils.ForceKick(args.Player, "Unprintable character in name"); - return true; - } - if (name.Length > 32) - { - TShock.Utils.ForceKick(args.Player, "Name exceeded 32 characters."); - return true; - } - if (name.Trim().Length == 0) - { - TShock.Utils.ForceKick(args.Player, "Empty Name."); - return true; - } - var ban = TShock.Bans.GetBanByName(name); - if (ban != null) - { - TShock.Utils.ForceKick(args.Player, string.Format("You are banned: {0}", ban.Reason)); - return true; - } - if (args.Player.ReceivedInfo) - { - return true; - } - if (TShock.Config.MediumcoreOnly && difficulty < 1) - { - TShock.Utils.ForceKick(args.Player, "Server is set to mediumcore and above characters only!"); - return true; - } - if (TShock.Config.HardcoreOnly && difficulty < 2) - { - TShock.Utils.ForceKick(args.Player, "Server is set to hardcore characters only!"); - return true; - } - args.Player.Difficulty = difficulty; - args.TPlayer.name = name; - args.Player.ReceivedInfo = true; + return false; + } - return false; - } + private static bool HandlePlayerInfo(GetDataHandlerArgs args) + { + var playerid = args.Data.ReadInt8(); + var hair = args.Data.ReadInt8(); + var male = args.Data.ReadInt8(); + args.Data.Position += 21; + var difficulty = args.Data.ReadInt8(); + string name = Encoding.ASCII.GetString(args.Data.ReadBytes((int) (args.Data.Length - args.Data.Position - 1))); - private static bool HandleConnecting(GetDataHandlerArgs args) - { - var user = TShock.Users.GetUserByName(args.Player.Name); - if (user != null && !TShock.Config.DisableLoginBeforeJoin) - { - args.Player.RequiresPassword = true; - NetMessage.SendData((int)PacketTypes.PasswordRequired, args.Player.Index); - return true; - } - else if (!string.IsNullOrEmpty(TShock.Config.ServerPassword)) - { - args.Player.RequiresPassword = true; - NetMessage.SendData((int)PacketTypes.PasswordRequired, args.Player.Index); - return true; - } + if (!TShock.Utils.ValidString(name)) + { + TShock.Utils.ForceKick(args.Player, "Unprintable character in name"); + return true; + } + if (name.Length > 32) + { + TShock.Utils.ForceKick(args.Player, "Name exceeded 32 characters."); + return true; + } + if (name.Trim().Length == 0) + { + TShock.Utils.ForceKick(args.Player, "Empty Name."); + return true; + } + var ban = TShock.Bans.GetBanByName(name); + if (ban != null) + { + TShock.Utils.ForceKick(args.Player, string.Format("You are banned: {0}", ban.Reason)); + return true; + } + if (args.Player.ReceivedInfo) + { + return true; + } + if (TShock.Config.MediumcoreOnly && difficulty < 1) + { + TShock.Utils.ForceKick(args.Player, "Server is set to mediumcore and above characters only!"); + return true; + } + if (TShock.Config.HardcoreOnly && difficulty < 2) + { + TShock.Utils.ForceKick(args.Player, "Server is set to hardcore characters only!"); + return true; + } + args.Player.Difficulty = difficulty; + args.TPlayer.name = name; + args.Player.ReceivedInfo = true; - if (args.Player.State == 1) - args.Player.State = 2; - NetMessage.SendData((int)PacketTypes.WorldInfo, args.Player.Index); - return true; - } + return false; + } - private static bool HandlePassword(GetDataHandlerArgs args) - { - if (!args.Player.RequiresPassword) - return true; + private static bool HandleConnecting(GetDataHandlerArgs args) + { + var user = TShock.Users.GetUserByName(args.Player.Name); + if (user != null && !TShock.Config.DisableLoginBeforeJoin) + { + args.Player.RequiresPassword = true; + NetMessage.SendData((int) PacketTypes.PasswordRequired, args.Player.Index); + return true; + } + else if (!string.IsNullOrEmpty(TShock.Config.ServerPassword)) + { + args.Player.RequiresPassword = true; + NetMessage.SendData((int) PacketTypes.PasswordRequired, args.Player.Index); + return true; + } - string password = Encoding.ASCII.GetString(args.Data.ReadBytes((int)(args.Data.Length - args.Data.Position - 1))); - var user = TShock.Users.GetUserByName(args.Player.Name); - if (user != null) - { - string encrPass = TShock.Utils.HashPassword(password); - if (user.Password.ToUpper() == encrPass.ToUpper()) - { - args.Player.RequiresPassword = false; - args.Player.PlayerData = TShock.InventoryDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Player.Name)); + if (args.Player.State == 1) + args.Player.State = 2; + NetMessage.SendData((int) PacketTypes.WorldInfo, args.Player.Index); + return true; + } - if (args.Player.State == 1) - args.Player.State = 2; - NetMessage.SendData((int)PacketTypes.WorldInfo, args.Player.Index); + private static bool HandlePassword(GetDataHandlerArgs args) + { + if (!args.Player.RequiresPassword) + return true; - if (TShock.Config.ServerSideInventory) - { - if (args.Player.Group.HasPermission(Permissions.bypassinventorychecks)) - { - args.Player.IgnoreActionsForClearingTrashCan = false; - } - else if (!TShock.CheckInventory(args.Player)) - { - args.Player.SendMessage("Login Failed, Please fix the above errors then /login again.", Color.Cyan); - args.Player.IgnoreActionsForClearingTrashCan = true; - return true; - } - } + string password = Encoding.ASCII.GetString(args.Data.ReadBytes((int) (args.Data.Length - args.Data.Position - 1))); + var user = TShock.Users.GetUserByName(args.Player.Name); + if (user != null) + { + string encrPass = TShock.Utils.HashPassword(password); + if (user.Password.ToUpper() == encrPass.ToUpper()) + { + args.Player.RequiresPassword = false; + args.Player.PlayerData = TShock.InventoryDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Player.Name)); - if (args.Player.Group.HasPermission(Permissions.ignorestackhackdetection)) - args.Player.IgnoreActionsForCheating = "none"; + if (args.Player.State == 1) + args.Player.State = 2; + NetMessage.SendData((int) PacketTypes.WorldInfo, args.Player.Index); - if (args.Player.Group.HasPermission(Permissions.usebanneditem)) - args.Player.IgnoreActionsForDisabledArmor = "none"; + if (TShock.Config.ServerSideInventory) + { + if (args.Player.Group.HasPermission(Permissions.bypassinventorychecks)) + { + args.Player.IgnoreActionsForClearingTrashCan = false; + } + else if (!TShock.CheckInventory(args.Player)) + { + args.Player.SendMessage("Login Failed, Please fix the above errors then /login again.", Color.Cyan); + args.Player.IgnoreActionsForClearingTrashCan = true; + return true; + } + } - args.Player.Group = TShock.Utils.GetGroup(user.Group); - args.Player.UserAccountName = args.Player.Name; - args.Player.UserID = TShock.Users.GetUserID(args.Player.UserAccountName); - args.Player.IsLoggedIn = true; - args.Player.IgnoreActionsForInventory = "none"; + if (args.Player.Group.HasPermission(Permissions.ignorestackhackdetection)) + args.Player.IgnoreActionsForCheating = "none"; - args.Player.PlayerData.CopyInventory(args.Player); - TShock.InventoryDB.InsertPlayerData(args.Player); + if (args.Player.Group.HasPermission(Permissions.usebanneditem)) + args.Player.IgnoreActionsForDisabledArmor = "none"; - args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen); - Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + args.Player.Name); - return true; - } - TShock.Utils.ForceKick(args.Player, "Incorrect User Account Password"); - return true; - } - if (!string.IsNullOrEmpty(TShock.Config.ServerPassword)) - { - if(TShock.Config.ServerPassword == password) - { - args.Player.RequiresPassword = false; - if (args.Player.State == 1) - args.Player.State = 2; - NetMessage.SendData((int)PacketTypes.WorldInfo, args.Player.Index); - return true; - } - TShock.Utils.ForceKick(args.Player, "Incorrect Server Password"); - return true; - } + args.Player.Group = TShock.Utils.GetGroup(user.Group); + args.Player.UserAccountName = args.Player.Name; + args.Player.UserID = TShock.Users.GetUserID(args.Player.UserAccountName); + args.Player.IsLoggedIn = true; + args.Player.IgnoreActionsForInventory = "none"; - TShock.Utils.ForceKick(args.Player, "Bad Password Attempt"); - return true; - } + args.Player.PlayerData.CopyInventory(args.Player); + TShock.InventoryDB.InsertPlayerData(args.Player); - private static bool HandleGetSection(GetDataHandlerArgs args) - { - if (args.Player.RequestedSection) - return true; + args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen); + Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + args.Player.Name); + return true; + } + TShock.Utils.ForceKick(args.Player, "Incorrect User Account Password"); + return true; + } + if (!string.IsNullOrEmpty(TShock.Config.ServerPassword)) + { + if (TShock.Config.ServerPassword == password) + { + args.Player.RequiresPassword = false; + if (args.Player.State == 1) + args.Player.State = 2; + NetMessage.SendData((int) PacketTypes.WorldInfo, args.Player.Index); + return true; + } + TShock.Utils.ForceKick(args.Player, "Incorrect Server Password"); + return true; + } - args.Player.RequestedSection = true; - if (TShock.HackedHealth(args.Player) && !args.Player.Group.HasPermission(Permissions.ignorestathackdetection)) - { - TShock.Utils.ForceKick(args.Player, "You have Hacked Health/Mana, Please use a different character."); - } + TShock.Utils.ForceKick(args.Player, "Bad Password Attempt"); + return true; + } - if (!args.Player.Group.HasPermission(Permissions.ignorestackhackdetection)) - { - TShock.HackedInventory(args.Player); - } + private static bool HandleGetSection(GetDataHandlerArgs args) + { + if (args.Player.RequestedSection) + return true; - if (TShock.Utils.ActivePlayers() + 1 > TShock.Config.MaxSlots && !args.Player.Group.HasPermission(Permissions.reservedslot)) - { - TShock.Utils.ForceKick(args.Player, TShock.Config.ServerFullReason); - return true; - } + args.Player.RequestedSection = true; + if (TShock.HackedHealth(args.Player) && !args.Player.Group.HasPermission(Permissions.ignorestathackdetection)) + { + TShock.Utils.ForceKick(args.Player, "You have Hacked Health/Mana, Please use a different character."); + } - NetMessage.SendData((int)PacketTypes.TimeSet, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); + if (!args.Player.Group.HasPermission(Permissions.ignorestackhackdetection)) + { + TShock.HackedInventory(args.Player); + } - if (TShock.Config.EnableGeoIP && TShock.Geo != null) - { - Log.Info(string.Format("{0} ({1}) from '{2}' group from '{3}' joined. ({4}/{5})", args.Player.Name, args.Player.IP, args.Player.Group.Name, args.Player.Country, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots)); - TShock.Utils.Broadcast(args.Player.Name + " has joined from the " + args.Player.Country, Color.Yellow); - } - else - { - Log.Info(string.Format("{0} ({1}) from '{2}' group joined. ({3}/{4})", args.Player.Name, args.Player.IP, args.Player.Group.Name, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots)); - TShock.Utils.Broadcast(args.Player.Name + " has joined", Color.Yellow); - } + if (TShock.Utils.ActivePlayers() + 1 > TShock.Config.MaxSlots && + !args.Player.Group.HasPermission(Permissions.reservedslot)) + { + TShock.Utils.ForceKick(args.Player, TShock.Config.ServerFullReason); + return true; + } - if (TShock.Config.DisplayIPToAdmins) - TShock.Utils.SendLogs(string.Format("{0} has joined. IP: {1}", args.Player.Name, args.Player.IP), Color.Blue); + NetMessage.SendData((int) PacketTypes.TimeSet, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); - return false; - } + if (TShock.Config.EnableGeoIP && TShock.Geo != null) + { + Log.Info(string.Format("{0} ({1}) from '{2}' group from '{3}' joined. ({4}/{5})", args.Player.Name, args.Player.IP, + args.Player.Group.Name, args.Player.Country, TShock.Utils.ActivePlayers(), + TShock.Config.MaxSlots)); + TShock.Utils.Broadcast(args.Player.Name + " has joined from the " + args.Player.Country, Color.Yellow); + } + else + { + Log.Info(string.Format("{0} ({1}) from '{2}' group joined. ({3}/{4})", args.Player.Name, args.Player.IP, + args.Player.Group.Name, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots)); + TShock.Utils.Broadcast(args.Player.Name + " has joined", Color.Yellow); + } - private static bool HandleSendTileSquare(GetDataHandlerArgs args) - { - if (args.Player.Group.HasPermission(Permissions.allowclientsideworldedit)) - return false; + if (TShock.Config.DisplayIPToAdmins) + TShock.Utils.SendLogs(string.Format("{0} has joined. IP: {1}", args.Player.Name, args.Player.IP), Color.Blue); - var size = args.Data.ReadInt16(); - var tileX = args.Data.ReadInt32(); - var tileY = args.Data.ReadInt32(); + return false; + } - if (size > 5) - return true; + private static bool HandleSendTileSquare(GetDataHandlerArgs args) + { + if (args.Player.Group.HasPermission(Permissions.allowclientsideworldedit)) + return false; - if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) - { - args.Player.SendTileSquare(tileX, tileY, size); - return true; - } + var size = args.Data.ReadInt16(); + var tileX = args.Data.ReadInt32(); + var tileY = args.Data.ReadInt32(); - if (TShock.CheckIgnores(args.Player)) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } + if (size > 5) + return true; - var tiles = new NetTile[size, size]; + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.SendTileSquare(tileX, tileY, size); + return true; + } - for (int x = 0; x < size; x++) - { - for (int y = 0; y < size; y++) - { - tiles[x, y] = new NetTile(args.Data); - } - } + if (TShock.CheckIgnores(args.Player)) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } - bool changed = false; - for (int x = 0; x < size; x++) - { - int realx = tileX + x; - if (realx < 0 || realx >= Main.maxTilesX) - continue; + var tiles = new NetTile[size,size]; - for (int y = 0; y < size; y++) - { - int realy = tileY + y; - if (realy < 0 || realy >= Main.maxTilesY) - continue; + for (int x = 0; x < size; x++) + { + for (int y = 0; y < size; y++) + { + tiles[x, y] = new NetTile(args.Data); + } + } - var tile = Main.tile[realx, realy]; - var newtile = tiles[x, y]; - if(TShock.CheckTilePermission(args.Player, x, y)) - { - continue; - } - if(TShock.CheckRangePermission(args.Player, x, y)) - { - continue; - } - if ((tile.type == 128 && newtile.Type == 128) || (tile.type == 105 && newtile.Type == 105)) - { + bool changed = false; + for (int x = 0; x < size; x++) + { + int realx = tileX + x; + if (realx < 0 || realx >= Main.maxTilesX) + continue; + + for (int y = 0; y < size; y++) + { + int realy = tileY + y; + if (realy < 0 || realy >= Main.maxTilesY) + continue; + + var tile = Main.tile[realx, realy]; + var newtile = tiles[x, y]; + if (TShock.CheckTilePermission(args.Player, x, y)) + { + continue; + } + if (TShock.CheckRangePermission(args.Player, x, y)) + { + continue; + } + if ((tile.type == 128 && newtile.Type == 128) || (tile.type == 105 && newtile.Type == 105)) + { if (TShock.Config.EnableInsecureTileFixes) { return false; } - } + } - if (tile.type == 0x17 && newtile.Type == 0x2) - { - tile.type = 0x2; - changed = true; - } - else if (tile.type == 0x19 && newtile.Type == 0x1) - { - tile.type = 0x1; - changed = true; - } - else if ((tile.type == 0xF && newtile.Type == 0xF) || - (tile.type == 0x4F && newtile.Type == 0x4F)) - { - tile.frameX = newtile.FrameX; - tile.frameY = newtile.FrameY; - changed = true; - } - // Holy water/Unholy water - else if (tile.type == 1 && newtile.Type == 117) - { - tile.type = 117; - changed = true; - } - else if (tile.type == 1 && newtile.Type == 25) - { - tile.type = 25; - changed = true; - } - else if (tile.type == 117 && newtile.Type == 25) - { - tile.type = 25; - changed = true; - } - else if (tile.type == 25 && newtile.Type == 117) - { - tile.type = 117; - changed = true; - } - else if (tile.type == 2 && newtile.Type == 23) - { - tile.type = 23; - changed = true; - } - else if (tile.type == 2 && newtile.Type == 109) - { - tile.type = 109; - changed = true; - } - else if (tile.type == 23 && newtile.Type == 109) - { - tile.type = 109; - changed = true; - } - else if (tile.type == 109 && newtile.Type == 23) - { - tile.type = 23; - changed = true; - } - else if (tile.type == 23 && newtile.Type == 109) - { - tile.type = 109; - changed = true; - } - else if (tile.type == 53 && newtile.Type == 116) - { - tile.type = 116; - changed = true; - } - else if (tile.type == 53 && newtile.Type == 112) - { - tile.type = 112; - changed = true; - } - else if (tile.type == 112 && newtile.Type == 116) - { - tile.type = 116; - changed = true; - } - else if (tile.type == 116 && newtile.Type == 112) - { - tile.type = 112; - changed = true; - } - else if (tile.type == 112 && newtile.Type == 53) - { - tile.type = 53; - changed = true; - } - else if (tile.type == 109 && newtile.Type == 2) - { - tile.type = 2; - changed = true; - } - else if (tile.type == 116 && newtile.Type == 53) - { - tile.type = 53; - changed = true; - } - else if (tile.type == 117 && newtile.Type == 1) - { - tile.type = 1; - changed = true; - } - } - } + if (tile.type == 0x17 && newtile.Type == 0x2) + { + tile.type = 0x2; + changed = true; + } + else if (tile.type == 0x19 && newtile.Type == 0x1) + { + tile.type = 0x1; + changed = true; + } + else if ((tile.type == 0xF && newtile.Type == 0xF) || + (tile.type == 0x4F && newtile.Type == 0x4F)) + { + tile.frameX = newtile.FrameX; + tile.frameY = newtile.FrameY; + changed = true; + } + // Holy water/Unholy water + else if (tile.type == 1 && newtile.Type == 117) + { + tile.type = 117; + changed = true; + } + else if (tile.type == 1 && newtile.Type == 25) + { + tile.type = 25; + changed = true; + } + else if (tile.type == 117 && newtile.Type == 25) + { + tile.type = 25; + changed = true; + } + else if (tile.type == 25 && newtile.Type == 117) + { + tile.type = 117; + changed = true; + } + else if (tile.type == 2 && newtile.Type == 23) + { + tile.type = 23; + changed = true; + } + else if (tile.type == 2 && newtile.Type == 109) + { + tile.type = 109; + changed = true; + } + else if (tile.type == 23 && newtile.Type == 109) + { + tile.type = 109; + changed = true; + } + else if (tile.type == 109 && newtile.Type == 23) + { + tile.type = 23; + changed = true; + } + else if (tile.type == 23 && newtile.Type == 109) + { + tile.type = 109; + changed = true; + } + else if (tile.type == 53 && newtile.Type == 116) + { + tile.type = 116; + changed = true; + } + else if (tile.type == 53 && newtile.Type == 112) + { + tile.type = 112; + changed = true; + } + else if (tile.type == 112 && newtile.Type == 116) + { + tile.type = 116; + changed = true; + } + else if (tile.type == 116 && newtile.Type == 112) + { + tile.type = 112; + changed = true; + } + else if (tile.type == 112 && newtile.Type == 53) + { + tile.type = 53; + changed = true; + } + else if (tile.type == 109 && newtile.Type == 2) + { + tile.type = 2; + changed = true; + } + else if (tile.type == 116 && newtile.Type == 53) + { + tile.type = 53; + changed = true; + } + else if (tile.type == 117 && newtile.Type == 1) + { + tile.type = 1; + changed = true; + } + } + } if (changed) { @@ -551,947 +557,964 @@ namespace TShockAPI } else { - args.Player.SendTileSquare(tileX, tileY, size); + args.Player.SendTileSquare(tileX, tileY, size); } - return true; - } - - private static bool HandleTile(GetDataHandlerArgs args) - { - var type = args.Data.ReadInt8(); - var tileX = args.Data.ReadInt32(); - var tileY = args.Data.ReadInt32(); - var tiletype = args.Data.ReadInt8(); - - if (tileX < 0 || tileX >= Main.maxTilesX || tileY < 0 || tileY >= Main.maxTilesY) - return false; - - if (args.Player.AwaitingName) - { - if (TShock.Regions.InAreaRegionName(tileX, tileY) == null) - { - args.Player.SendMessage("Region is not protected", Color.Yellow); - } - else - { - args.Player.SendMessage("Region Name: " + TShock.Regions.InAreaRegionName(tileX, tileY), Color.Yellow); - } - args.Player.SendTileSquare(tileX, tileY); - args.Player.AwaitingName = false; - return true; - } - - if (args.Player.AwaitingTempPoint > 0) - { - args.Player.TempPoints[args.Player.AwaitingTempPoint - 1].X = tileX; - args.Player.TempPoints[args.Player.AwaitingTempPoint - 1].Y = tileY; - args.Player.SendMessage("Set Temp Point " + args.Player.AwaitingTempPoint, Color.Yellow); - args.Player.SendTileSquare(tileX, tileY); - args.Player.AwaitingTempPoint = 0; - return true; - } - - if (type == 1 || type == 3) - { - if (tiletype >= ((type == 1) ? Main.maxTileSets : Main.maxWallTypes)) - { - return true; - } - if (tiletype == 29 && tiletype == 97 && TShock.Config.ServerSideInventory) - { - args.Player.SendMessage("You cannot place this tile, Server side inventory is enabled.", Color.Red); - args.Player.SendTileSquare(tileX, tileY); - return true; - } - if (tiletype == 48 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Spike", args.Player)) - { - args.Player.Disable(); - args.Player.SendTileSquare(tileX, tileY); - return true; - } - if (type == 1 && tiletype == 21 && TShock.Utils.MaxChests()) - { - args.Player.SendMessage("Reached world's max chest limit, unable to place more!", Color.Red); - args.Player.SendTileSquare(tileX, tileY); - return true; - } - if (tiletype == 141 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Explosives", args.Player)) - { - args.Player.Disable(); - args.Player.SendTileSquare(tileX, tileY); - return true; - } - } - - if (TShock.CheckIgnores(args.Player)) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (TShock.CheckTilePermission(args.Player, tileX, tileY)) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if ((tiletype == 127 || Main.tileCut[tiletype]) && (type == 0 || type == 4)) - { - return false; - } - - if (TShock.CheckRangePermission(args.Player, tileX, tileY)) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (args.Player.TileKillThreshold >= TShock.Config.TileKillThreshold) - { - args.Player.Disable(); - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (args.Player.TilePlaceThreshold >= TShock.Config.TilePlaceThreshold) - { - args.Player.Disable(); - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (type == 1 && !args.Player.Group.HasPermission(Permissions.ignoreplacetiledetection)) - { - args.Player.TilePlaceThreshold++; - var coords = new Vector2(tileX, tileY); - if (!args.Player.TilesCreated.ContainsKey(coords)) - args.Player.TilesCreated.Add(coords, Main.tile[tileX, tileY].Data); - } - - if ((type == 0 || type == 4) && Main.tileSolid[Main.tile[tileX, tileY].type] && !args.Player.Group.HasPermission(Permissions.ignorekilltiledetection)) - { - args.Player.TileKillThreshold++; - var coords = new Vector2(tileX, tileY); - if (!args.Player.TilesDestroyed.ContainsKey(coords)) - args.Player.TilesDestroyed.Add(coords, Main.tile[tileX, tileY].Data); - } - - return false; - } - - private static bool HandleTogglePvp(GetDataHandlerArgs args) - { - int id = args.Data.ReadByte(); - bool pvp = args.Data.ReadBoolean(); - - if (id != args.Player.Index) - { - return true; - } - - if (TShock.Config.PvPMode == "disabled") - { - return true; - } - - if (args.TPlayer.hostile != pvp) - { - long seconds = (long)(DateTime.UtcNow - args.Player.LastPvpChange).TotalSeconds; - if (seconds > 5) - { - TSPlayer.All.SendMessage(string.Format("{0} has {1} PvP!", args.Player.Name, pvp ? "enabled" : "disabled"), Main.teamColor[args.Player.Team]); - } - args.Player.LastPvpChange = DateTime.UtcNow; - } - - args.TPlayer.hostile = pvp; - - if (TShock.Config.PvPMode == "always") - { - if (!pvp) - args.Player.Spawn(); - } - - NetMessage.SendData((int)PacketTypes.TogglePvp, -1, -1, "", args.Player.Index); - - return true; - } - - private static bool HandlePlayerUpdate(GetDataHandlerArgs args) - { - var plr = args.Data.ReadInt8(); - var control = args.Data.ReadInt8(); - var item = args.Data.ReadInt8(); - var pos = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); - var vel = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); - - if (item < 0 || item >= args.TPlayer.inventory.Length) - { - return true; - } - - if(args.Player.LastNetPosition == Vector2.Zero) - { - return true; - } - - if (!pos.Equals(args.Player.LastNetPosition)) - { - float distance = Vector2.Distance(new Vector2(pos.X / 16f, pos.Y / 16f), new Vector2(args.Player.LastNetPosition.X / 16f, args.Player.LastNetPosition.Y / 16f)); - if (TShock.CheckIgnores(args.Player)) - { - if (distance > TShock.Config.MaxRangeForDisabled) - { - if (args.Player.IgnoreActionsForCheating != "none") - { - args.Player.SendMessage("Disabled for cheating: " + args.Player.IgnoreActionsForCheating, - Color.Red); - } - else if (args.Player.IgnoreActionsForDisabledArmor != "none") - { - args.Player.SendMessage( - "Disabled for banned armor: " + args.Player.IgnoreActionsForDisabledArmor, Color.Red); - } - else if (args.Player.IgnoreActionsForInventory != "none") - { - args.Player.SendMessage( - "Disabled for Server Side Inventory: " + args.Player.IgnoreActionsForInventory, - Color.Red); - } - else if (TShock.Config.RequireLogin && !args.Player.IsLoggedIn) - { - args.Player.SendMessage("Please /register or /login to play!", Color.Red); - } - else if (args.Player.IgnoreActionsForClearingTrashCan) - { - args.Player.SendMessage("You need to rejoin to ensure your trash can is cleared!", Color.Red); - } - else if (TShock.Config.PvPMode == "always" && !args.TPlayer.hostile) - { - args.Player.SendMessage("PvP is forced! Enable PvP else you can't move or do anything!", - Color.Red); - } - int lastTileX = (int) (args.Player.LastNetPosition.X/16f); - int lastTileY = (int) (args.Player.LastNetPosition.Y/16f); - if (!args.Player.Teleport(lastTileX, lastTileY)) - { - args.Player.Spawn(); - } - return true; - } - return true; - } - - if (args.Player.Dead) - { - return true; - } - - if (!args.Player.Group.HasPermission(Permissions.ignorenoclipdetection) && Collision.SolidCollision(pos, args.TPlayer.width, args.TPlayer.height)) - { - int lastTileX = (int)(args.Player.LastNetPosition.X / 16f); - int lastTileY = (int)(args.Player.LastNetPosition.Y / 16f); - if (!args.Player.Teleport(lastTileX, lastTileY + 3)) - { - args.Player.SendMessage("You got stuck in a solid object, Sent to spawn point."); - args.Player.Spawn(); - } - return true; - } - args.Player.LastNetPosition = pos; - } - - if ((control & 32) == 32) - { - if (!args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned(args.TPlayer.inventory[item].name, args.Player)) - { - control -= 32; - args.Player.Disable(); - args.Player.SendMessage(string.Format("You cannot use {0} on this server. Your actions are being ignored.", args.TPlayer.inventory[item].name), Color.Red); - } - } - - args.TPlayer.selectedItem = item; - args.TPlayer.position = pos; - args.TPlayer.velocity = vel; - args.TPlayer.oldVelocity = args.TPlayer.velocity; - args.TPlayer.fallStart = (int)(pos.Y / 16f); - args.TPlayer.controlUp = false; - args.TPlayer.controlDown = false; - args.TPlayer.controlLeft = false; - args.TPlayer.controlRight = false; - args.TPlayer.controlJump = false; - args.TPlayer.controlUseItem = false; - args.TPlayer.direction = -1; - if ((control & 1) == 1) - { - args.TPlayer.controlUp = true; - } - if ((control & 2) == 2) - { - args.TPlayer.controlDown = true; - } - if ((control & 4) == 4) - { - args.TPlayer.controlLeft = true; - } - if ((control & 8) == 8) - { - args.TPlayer.controlRight = true; - } - if ((control & 16) == 16) - { - args.TPlayer.controlJump = true; - } - if ((control & 32) == 32) - { - args.TPlayer.controlUseItem = true; - } - if ((control & 64) == 64) - { - args.TPlayer.direction = 1; - } - NetMessage.SendData((int)PacketTypes.PlayerUpdate, -1, args.Player.Index, "", args.Player.Index); - - return true; - } - - private static bool HandleProjectileNew(GetDataHandlerArgs args) - { - var ident = args.Data.ReadInt16(); - var pos = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); - var vel = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); - var knockback = args.Data.ReadSingle(); - var dmg = args.Data.ReadInt16(); - var owner = args.Data.ReadInt8(); - var type = args.Data.ReadInt8(); - - var index = TShock.Utils.SearchProjectile(ident); - - if (index > Main.maxProjectiles || index < 0) - { - return true; - } - - if (args.Player.Index != owner) - { - args.Player.Disable(); - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if (dmg > 175) - { - args.Player.Disable(); - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if (TShock.CheckIgnores(args.Player)) - { - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if (TShock.CheckProjectilePermission(args.Player, index, type)) - { - args.Player.Disable(); - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if (args.Player.ProjectileThreshold >= TShock.Config.ProjectileThreshold) - { - args.Player.Disable(); - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) - { - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if (!args.Player.Group.HasPermission(Permissions.ignoreprojectiledetection)) - { - args.Player.ProjectileThreshold++; - } - - return false; - } - - private static bool HandleProjectileKill(GetDataHandlerArgs args) - { - var ident = args.Data.ReadInt16(); - var owner = args.Data.ReadInt8(); - - if (args.Player.Index != owner) - { - args.Player.Disable(); - return true; - } - - var index = TShock.Utils.SearchProjectile(ident); - - if (index > Main.maxProjectiles || index < 0) - { - return true; - } - - int type = Main.projectile[index].type; - - if (args.Player.Index != Main.projectile[index].owner) - { - args.Player.Disable(); - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if (TShock.CheckIgnores(args.Player)) - { - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if (TShock.CheckProjectilePermission(args.Player, index, type)) - { - args.Player.Disable(); - args.Player.RemoveProjectile(ident, owner); - return true; - } - - if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) - { - args.Player.RemoveProjectile(ident, owner); - return true; - } - - return false; - } - - private static bool HandlePlayerKillMe(GetDataHandlerArgs args) - { - var id = args.Data.ReadInt8(); - var direction = args.Data.ReadInt8(); - var dmg = args.Data.ReadInt16(); - var pvp = args.Data.ReadInt8() == 0; - - int textlength = (int)(args.Data.Length - args.Data.Position - 1); - string deathtext = ""; - if (textlength > 0) - { - deathtext = Encoding.ASCII.GetString(args.Data.ReadBytes(textlength)); - if (!TShock.Utils.ValidString(deathtext)) - { - return true; - } - } - - args.Player.LastDeath = DateTime.Now; - args.Player.Dead = true; - - return false; - } - - private static bool HandleLiquidSet(GetDataHandlerArgs args) - { - int tileX = args.Data.ReadInt32(); - int tileY = args.Data.ReadInt32(); - byte liquid = args.Data.ReadInt8(); - bool lava = args.Data.ReadBoolean(); - - //The liquid was picked up. - if (liquid == 0) - return false; - - if (tileX < 0 || tileX >= Main.maxTilesX || tileY < 0 || tileY >= Main.maxTilesY) - return false; - - if (TShock.CheckIgnores(args.Player)) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (args.Player.TileLiquidThreshold >= TShock.Config.TileLiquidThreshold) - { - args.Player.Disable(); - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (!args.Player.Group.HasPermission(Permissions.ignoreliquidsetdetection)) - { - args.Player.TileLiquidThreshold++; - } - - int bucket = 0; - if (args.TPlayer.inventory[args.TPlayer.selectedItem].type == 206) - { - bucket = 1; - } - else if (args.TPlayer.inventory[args.TPlayer.selectedItem].type == 207) - { - bucket = 2; - } - - if (lava && bucket != 2 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Lava Bucket", args.Player)) - { - args.Player.Disable(); - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (!lava && bucket != 1 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Water Bucket", args.Player)) - { - args.Player.Disable(); - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (TShock.CheckTilePermission(args.Player, tileX, tileY)) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (TShock.CheckRangePermission(args.Player, tileX, tileY, 16)) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - return false; - } - - private static bool HandleTileKill(GetDataHandlerArgs args) - { - var tileX = args.Data.ReadInt32(); - var tileY = args.Data.ReadInt32(); - - if (tileX < 0 || tileX >= Main.maxTilesX || tileY < 0 || tileY >= Main.maxTilesY) - return false; - - if (TShock.CheckIgnores(args.Player)) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (Main.tile[tileX, tileY].type != 0x15 && (!TShock.Utils.MaxChests() && Main.tile[tileX, tileY].type != 0)) //Chest - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (TShock.CheckTilePermission(args.Player, tileX, tileY)) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - if (TShock.CheckRangePermission(args.Player, tileX, tileY)) - { - args.Player.SendTileSquare(tileX, tileY); - return true; - } - - return false; - } - - private static bool HandleSpawn(GetDataHandlerArgs args) - { - var player = args.Data.ReadInt8(); - var spawnx = args.Data.ReadInt32(); - var spawny = args.Data.ReadInt32(); - - if (args.Player.InitSpawn && args.TPlayer.inventory[args.TPlayer.selectedItem].type != 50) - { - if (args.TPlayer.difficulty == 1 && (TShock.Config.KickOnMediumcoreDeath || TShock.Config.BanOnMediumcoreDeath)) - { - if (args.TPlayer.selectedItem != 50) - { - if (TShock.Config.BanOnMediumcoreDeath) - { - if (!TShock.Utils.Ban(args.Player, TShock.Config.MediumcoreBanReason)) - TShock.Utils.ForceKick(args.Player, "Death results in a ban, but can't ban you"); - } - else - { - TShock.Utils.ForceKick(args.Player, TShock.Config.MediumcoreKickReason); - } - return true; - } - } - } - else - args.Player.InitSpawn = true; - - args.Player.Dead = false; - return false; - } - - private static bool HandleChestOpen(GetDataHandlerArgs args) - { - var x = args.Data.ReadInt32(); - var y = args.Data.ReadInt32(); - - if (TShock.CheckIgnores(args.Player)) - { - return true; - } - - if (TShock.CheckRangePermission(args.Player, x, y)) - { - return true; - } - - if (TShock.CheckTilePermission(args.Player, x, y) && TShock.Config.RegionProtectChests) - { - return true; - } - - return false; - } - - private static bool HandleChestItem(GetDataHandlerArgs args) - { - var id = args.Data.ReadInt16(); - var slot = args.Data.ReadInt8(); - var stacks = args.Data.ReadInt8(); - var prefix = args.Data.ReadInt8(); - var type = args.Data.ReadInt16(); - - if (args.TPlayer.chest != id) - { - return false; - } - - if (TShock.CheckIgnores(args.Player)) - { - args.Player.SendData(PacketTypes.ChestItem, "", id, slot); - return true; - } - - Item item = new Item(); - item.netDefaults(type); - if (stacks > item.maxStack || TShock.Itembans.ItemIsBanned(item.name, args.Player)) - { - return false; - } - - if (TShock.CheckTilePermission(args.Player, Main.chest[id].x, Main.chest[id].y) && TShock.Config.RegionProtectChests) - { - return false; - } - - if (TShock.CheckRangePermission(args.Player, Main.chest[id].x, Main.chest[id].y)) - { - return false; - } - - return false; - } - - private static bool HandleSign(GetDataHandlerArgs args) - { - var id = args.Data.ReadInt16(); - var x = args.Data.ReadInt32(); - var y = args.Data.ReadInt32(); - - if (TShock.CheckTilePermission(args.Player, x, y)) - { - args.Player.SendData(PacketTypes.SignNew, "", id); - return true; - } - - if (TShock.CheckRangePermission(args.Player, x, y)) - { - args.Player.SendData(PacketTypes.SignNew, "", id); - return true; - } - return false; - } - - private static bool UpdateNPCHome(GetDataHandlerArgs args) - { - var id = args.Data.ReadInt16(); - var x = args.Data.ReadInt16(); - var y = args.Data.ReadInt16(); - var homeless = args.Data.ReadInt8(); - - if (!args.Player.Group.HasPermission(Permissions.movenpc)) - { - args.Player.SendMessage("You do not have permission to relocate NPCs.", Color.Red); - args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY, Convert.ToByte(Main.npc[id].homeless)); - return true; - } - - if (TShock.CheckTilePermission(args.Player, x, y)) - { - args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY, Convert.ToByte(Main.npc[id].homeless)); - return true; - } - - if (TShock.CheckRangePermission(args.Player, x, y)) - { - args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY, Convert.ToByte(Main.npc[id].homeless)); - return true; - } - return false; - } - - private static bool HandlePlayerBuff(GetDataHandlerArgs args) - { - var id = args.Data.ReadInt8(); - var type = args.Data.ReadInt8(); - var time = args.Data.ReadInt16(); - - if (TShock.CheckIgnores(args.Player)) - { - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - return true; - } - if (!TShock.Players[id].TPlayer.hostile) - { - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - return true; - } - if (TShock.CheckRangePermission(args.Player, TShock.Players[id].TileX, TShock.Players[id].TileY, 50)) - { - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - return true; - } - if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) - { - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - return true; - } - - if (WhitelistBuffMaxTime[type] > 0 && time <= WhitelistBuffMaxTime[type]) - { - return false; - } - - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - return true; - } - - private static bool HandleItemDrop(GetDataHandlerArgs args) - { - var id = args.Data.ReadInt16(); - var pos = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); - var vel = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); - var stacks = args.Data.ReadInt8(); - var prefix = args.Data.ReadInt8(); - var type = args.Data.ReadInt16(); - - if (type == 0) //Item removed, let client do this to prevent item duplication client side - { - return false; - } - - if (TShock.CheckRangePermission(args.Player, (int)(pos.X / 16f), (int)(pos.Y / 16f))) - { - args.Player.SendData(PacketTypes.ItemDrop, "", id); - return true; - } - - Item item = new Item(); - item.netDefaults(type); - if (stacks > item.maxStack || TShock.Itembans.ItemIsBanned(item.name, args.Player)) - { - args.Player.SendData(PacketTypes.ItemDrop, "", id); - return true; - } - - if (TShock.CheckIgnores(args.Player)) - { - args.Player.SendData(PacketTypes.ItemDrop, "", id); - return true; - } - - return false; - } - - private static bool HandlePlayerDamage(GetDataHandlerArgs args) - { - var id = args.Data.ReadInt8(); - var direction = args.Data.ReadInt8(); - var dmg = args.Data.ReadInt16(); - var pvp = args.Data.ReadInt8(); - var crit = args.Data.ReadInt8(); - - int textlength = (int)(args.Data.Length - args.Data.Position - 1); - string deathtext = ""; - if (textlength > 0) - { - deathtext = Encoding.ASCII.GetString(args.Data.ReadBytes(textlength)); - if (!TShock.Utils.ValidString(deathtext)) - { - return true; - } - } - - if (TShock.Players[id] == null) - return true; - - if (dmg > 175) - { - args.Player.Disable(); - args.Player.SendData(PacketTypes.PlayerHp, "", id); - args.Player.SendData(PacketTypes.PlayerUpdate, "", id); - return true; - } - - if (!TShock.Players[id].TPlayer.hostile) - { - args.Player.SendData(PacketTypes.PlayerHp, "", id); - args.Player.SendData(PacketTypes.PlayerUpdate, "", id); - return true; - } - - if (TShock.CheckIgnores(args.Player)) - { - args.Player.SendData(PacketTypes.PlayerHp, "", id); - args.Player.SendData(PacketTypes.PlayerUpdate, "", id); - return true; - } - - if (TShock.CheckRangePermission(args.Player, TShock.Players[id].TileX, TShock.Players[id].TileY, 100)) - { - args.Player.SendData(PacketTypes.PlayerHp, "", id); - args.Player.SendData(PacketTypes.PlayerUpdate, "", id); - return true; - } - - if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) - { - args.Player.SendData(PacketTypes.PlayerHp, "", id); - args.Player.SendData(PacketTypes.PlayerUpdate, "", id); - return true; - } - - return false; - } - - private static bool HandleNpcStrike(GetDataHandlerArgs args) - { - var id = args.Data.ReadInt8(); - var direction = args.Data.ReadInt8(); - var dmg = args.Data.ReadInt16(); - var pvp = args.Data.ReadInt8(); - var crit = args.Data.ReadInt8(); - - if (Main.npc[id] == null) - return true; - - if (dmg > 175) - { - args.Player.Disable(); - args.Player.SendData(PacketTypes.NpcUpdate, "", id); - return true; - } - - if (TShock.CheckIgnores(args.Player)) - { - args.Player.SendData(PacketTypes.NpcUpdate, "", id); - return true; - } - - if (Main.npc[id].townNPC && !args.Player.Group.HasPermission(Permissions.movenpc)) - { - args.Player.SendData(PacketTypes.NpcUpdate, "", id); - return true; - } - - if (TShock.Config.RangeChecks && TShock.CheckRangePermission(args.Player, (int)(Main.npc[id].position.X / 16f), (int)(Main.npc[id].position.Y / 16f), 100)) - { - args.Player.SendData(PacketTypes.NpcUpdate, "", id); - return true; - } - - if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) - { - args.Player.SendData(PacketTypes.NpcUpdate, "", id); - return true; - } - - return false; - } - - private static bool HandleSpecial(GetDataHandlerArgs args) - { - var id = args.Data.ReadInt8(); - var type = args.Data.ReadInt8(); - - if (type == 1 && TShock.Config.DisableDungeonGuardian) - { - args.Player.SendMessage("The Dungeon Guardian returned you to your spawn point", Color.Purple); - args.Player.Spawn(); - return true; - } - - return false; - } - - private static bool HandlePlayerAnimation(GetDataHandlerArgs args) - { - if (TShock.CheckIgnores(args.Player)) - { - args.Player.SendData(PacketTypes.PlayerAnimation, "", args.Player.Index); - return true; - } - - if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) - { - args.Player.SendData(PacketTypes.PlayerAnimation, "", args.Player.Index); - return true; - } - - return false; - } - - private static bool HandlePlayerBuffUpdate(GetDataHandlerArgs args) - { - var id = args.Data.ReadInt8(); - for (int i = 0; i < 10; i++) - { - var buff = args.Data.ReadInt8(); - - if (buff == 10) - { - if (!args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Invisibility Potion", args.Player) ) - buff = 0; - else if (TShock.Config.DisableInvisPvP && args.TPlayer.hostile) - buff = 0; - } - - args.TPlayer.buffType[i] = buff; - if (args.TPlayer.buffType[i] > 0) - { - args.TPlayer.buffTime[i] = 60; - } - else - { - args.TPlayer.buffTime[i] = 0; - } - } - NetMessage.SendData((int)PacketTypes.PlayerBuff, -1, args.Player.Index, "", args.Player.Index); - return true; - } - } -} + return true; + } + + private static bool HandleTile(GetDataHandlerArgs args) + { + var type = args.Data.ReadInt8(); + var tileX = args.Data.ReadInt32(); + var tileY = args.Data.ReadInt32(); + var tiletype = args.Data.ReadInt8(); + + if (tileX < 0 || tileX >= Main.maxTilesX || tileY < 0 || tileY >= Main.maxTilesY) + return false; + + if (args.Player.AwaitingName) + { + if (TShock.Regions.InAreaRegionName(tileX, tileY) == null) + { + args.Player.SendMessage("Region is not protected", Color.Yellow); + } + else + { + args.Player.SendMessage("Region Name: " + TShock.Regions.InAreaRegionName(tileX, tileY), Color.Yellow); + } + args.Player.SendTileSquare(tileX, tileY); + args.Player.AwaitingName = false; + return true; + } + + if (args.Player.AwaitingTempPoint > 0) + { + args.Player.TempPoints[args.Player.AwaitingTempPoint - 1].X = tileX; + args.Player.TempPoints[args.Player.AwaitingTempPoint - 1].Y = tileY; + args.Player.SendMessage("Set Temp Point " + args.Player.AwaitingTempPoint, Color.Yellow); + args.Player.SendTileSquare(tileX, tileY); + args.Player.AwaitingTempPoint = 0; + return true; + } + + if (type == 1 || type == 3) + { + if (tiletype >= ((type == 1) ? Main.maxTileSets : Main.maxWallTypes)) + { + return true; + } + if (tiletype == 29 && tiletype == 97 && TShock.Config.ServerSideInventory) + { + args.Player.SendMessage("You cannot place this tile, Server side inventory is enabled.", Color.Red); + args.Player.SendTileSquare(tileX, tileY); + return true; + } + if (tiletype == 48 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && + TShock.Itembans.ItemIsBanned("Spike", args.Player)) + { + args.Player.Disable(); + args.Player.SendTileSquare(tileX, tileY); + return true; + } + if (type == 1 && tiletype == 21 && TShock.Utils.MaxChests()) + { + args.Player.SendMessage("Reached world's max chest limit, unable to place more!", Color.Red); + args.Player.SendTileSquare(tileX, tileY); + return true; + } + if (tiletype == 141 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && + TShock.Itembans.ItemIsBanned("Explosives", args.Player)) + { + args.Player.Disable(); + args.Player.SendTileSquare(tileX, tileY); + return true; + } + } + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (TShock.CheckTilePermission(args.Player, tileX, tileY)) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if ((tiletype == 127 || Main.tileCut[tiletype]) && (type == 0 || type == 4)) + { + return false; + } + + if (TShock.CheckRangePermission(args.Player, tileX, tileY)) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (args.Player.TileKillThreshold >= TShock.Config.TileKillThreshold) + { + args.Player.Disable(); + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (args.Player.TilePlaceThreshold >= TShock.Config.TilePlaceThreshold) + { + args.Player.Disable(); + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (type == 1 && !args.Player.Group.HasPermission(Permissions.ignoreplacetiledetection)) + { + args.Player.TilePlaceThreshold++; + var coords = new Vector2(tileX, tileY); + if (!args.Player.TilesCreated.ContainsKey(coords)) + args.Player.TilesCreated.Add(coords, Main.tile[tileX, tileY].Data); + } + + if ((type == 0 || type == 4) && Main.tileSolid[Main.tile[tileX, tileY].type] && + !args.Player.Group.HasPermission(Permissions.ignorekilltiledetection)) + { + args.Player.TileKillThreshold++; + var coords = new Vector2(tileX, tileY); + if (!args.Player.TilesDestroyed.ContainsKey(coords)) + args.Player.TilesDestroyed.Add(coords, Main.tile[tileX, tileY].Data); + } + + return false; + } + + private static bool HandleTogglePvp(GetDataHandlerArgs args) + { + int id = args.Data.ReadByte(); + bool pvp = args.Data.ReadBoolean(); + + if (id != args.Player.Index) + { + return true; + } + + if (TShock.Config.PvPMode == "disabled") + { + return true; + } + + if (args.TPlayer.hostile != pvp) + { + long seconds = (long) (DateTime.UtcNow - args.Player.LastPvpChange).TotalSeconds; + if (seconds > 5) + { + TSPlayer.All.SendMessage(string.Format("{0} has {1} PvP!", args.Player.Name, pvp ? "enabled" : "disabled"), + Main.teamColor[args.Player.Team]); + } + args.Player.LastPvpChange = DateTime.UtcNow; + } + + args.TPlayer.hostile = pvp; + + if (TShock.Config.PvPMode == "always") + { + if (!pvp) + args.Player.Spawn(); + } + + NetMessage.SendData((int) PacketTypes.TogglePvp, -1, -1, "", args.Player.Index); + + return true; + } + + private static bool HandlePlayerUpdate(GetDataHandlerArgs args) + { + var plr = args.Data.ReadInt8(); + var control = args.Data.ReadInt8(); + var item = args.Data.ReadInt8(); + var pos = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); + var vel = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); + + if (item < 0 || item >= args.TPlayer.inventory.Length) + { + return true; + } + + if (args.Player.LastNetPosition == Vector2.Zero) + { + return true; + } + + if (!pos.Equals(args.Player.LastNetPosition)) + { + float distance = Vector2.Distance(new Vector2(pos.X/16f, pos.Y/16f), + new Vector2(args.Player.LastNetPosition.X/16f, args.Player.LastNetPosition.Y/16f)); + if (TShock.CheckIgnores(args.Player)) + { + if (distance > TShock.Config.MaxRangeForDisabled) + { + if (args.Player.IgnoreActionsForCheating != "none") + { + args.Player.SendMessage("Disabled for cheating: " + args.Player.IgnoreActionsForCheating, + Color.Red); + } + else if (args.Player.IgnoreActionsForDisabledArmor != "none") + { + args.Player.SendMessage( + "Disabled for banned armor: " + args.Player.IgnoreActionsForDisabledArmor, Color.Red); + } + else if (args.Player.IgnoreActionsForInventory != "none") + { + args.Player.SendMessage( + "Disabled for Server Side Inventory: " + args.Player.IgnoreActionsForInventory, + Color.Red); + } + else if (TShock.Config.RequireLogin && !args.Player.IsLoggedIn) + { + args.Player.SendMessage("Please /register or /login to play!", Color.Red); + } + else if (args.Player.IgnoreActionsForClearingTrashCan) + { + args.Player.SendMessage("You need to rejoin to ensure your trash can is cleared!", Color.Red); + } + else if (TShock.Config.PvPMode == "always" && !args.TPlayer.hostile) + { + args.Player.SendMessage("PvP is forced! Enable PvP else you can't move or do anything!", + Color.Red); + } + int lastTileX = (int) (args.Player.LastNetPosition.X/16f); + int lastTileY = (int) (args.Player.LastNetPosition.Y/16f); + if (!args.Player.Teleport(lastTileX, lastTileY)) + { + args.Player.Spawn(); + } + return true; + } + return true; + } + + if (args.Player.Dead) + { + return true; + } + + if (!args.Player.Group.HasPermission(Permissions.ignorenoclipdetection) && + Collision.SolidCollision(pos, args.TPlayer.width, args.TPlayer.height)) + { + int lastTileX = (int) (args.Player.LastNetPosition.X/16f); + int lastTileY = (int) (args.Player.LastNetPosition.Y/16f); + if (!args.Player.Teleport(lastTileX, lastTileY + 3)) + { + args.Player.SendMessage("You got stuck in a solid object, Sent to spawn point."); + args.Player.Spawn(); + } + return true; + } + args.Player.LastNetPosition = pos; + } + + if ((control & 32) == 32) + { + if (!args.Player.Group.HasPermission(Permissions.usebanneditem) && + TShock.Itembans.ItemIsBanned(args.TPlayer.inventory[item].name, args.Player)) + { + control -= 32; + args.Player.Disable(); + args.Player.SendMessage( + string.Format("You cannot use {0} on this server. Your actions are being ignored.", + args.TPlayer.inventory[item].name), Color.Red); + } + } + + args.TPlayer.selectedItem = item; + args.TPlayer.position = pos; + args.TPlayer.velocity = vel; + args.TPlayer.oldVelocity = args.TPlayer.velocity; + args.TPlayer.fallStart = (int) (pos.Y/16f); + args.TPlayer.controlUp = false; + args.TPlayer.controlDown = false; + args.TPlayer.controlLeft = false; + args.TPlayer.controlRight = false; + args.TPlayer.controlJump = false; + args.TPlayer.controlUseItem = false; + args.TPlayer.direction = -1; + if ((control & 1) == 1) + { + args.TPlayer.controlUp = true; + } + if ((control & 2) == 2) + { + args.TPlayer.controlDown = true; + } + if ((control & 4) == 4) + { + args.TPlayer.controlLeft = true; + } + if ((control & 8) == 8) + { + args.TPlayer.controlRight = true; + } + if ((control & 16) == 16) + { + args.TPlayer.controlJump = true; + } + if ((control & 32) == 32) + { + args.TPlayer.controlUseItem = true; + } + if ((control & 64) == 64) + { + args.TPlayer.direction = 1; + } + NetMessage.SendData((int) PacketTypes.PlayerUpdate, -1, args.Player.Index, "", args.Player.Index); + + return true; + } + + private static bool HandleProjectileNew(GetDataHandlerArgs args) + { + var ident = args.Data.ReadInt16(); + var pos = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); + var vel = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); + var knockback = args.Data.ReadSingle(); + var dmg = args.Data.ReadInt16(); + var owner = args.Data.ReadInt8(); + var type = args.Data.ReadInt8(); + + var index = TShock.Utils.SearchProjectile(ident); + + if (index > Main.maxProjectiles || index < 0) + { + return true; + } + + if (args.Player.Index != owner) + { + args.Player.Disable(); + args.Player.RemoveProjectile(ident, owner); + return true; + } + + if (dmg > 175) + { + args.Player.Disable(); + args.Player.RemoveProjectile(ident, owner); + return true; + } + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.RemoveProjectile(ident, owner); + return true; + } + + if (TShock.CheckProjectilePermission(args.Player, index, type)) + { + args.Player.Disable(); + args.Player.RemoveProjectile(ident, owner); + return true; + } + + if (args.Player.ProjectileThreshold >= TShock.Config.ProjectileThreshold) + { + args.Player.Disable(); + args.Player.RemoveProjectile(ident, owner); + return true; + } + + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.RemoveProjectile(ident, owner); + return true; + } + + if (!args.Player.Group.HasPermission(Permissions.ignoreprojectiledetection)) + { + args.Player.ProjectileThreshold++; + } + + return false; + } + + private static bool HandleProjectileKill(GetDataHandlerArgs args) + { + var ident = args.Data.ReadInt16(); + var owner = args.Data.ReadInt8(); + + if (args.Player.Index != owner) + { + args.Player.Disable(); + return true; + } + + var index = TShock.Utils.SearchProjectile(ident); + + if (index > Main.maxProjectiles || index < 0) + { + return true; + } + + int type = Main.projectile[index].type; + + if (args.Player.Index != Main.projectile[index].owner) + { + args.Player.Disable(); + args.Player.RemoveProjectile(ident, owner); + return true; + } + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.RemoveProjectile(ident, owner); + return true; + } + + if (TShock.CheckProjectilePermission(args.Player, index, type)) + { + args.Player.Disable(); + args.Player.RemoveProjectile(ident, owner); + return true; + } + + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.RemoveProjectile(ident, owner); + return true; + } + + return false; + } + + private static bool HandlePlayerKillMe(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt8(); + var direction = args.Data.ReadInt8(); + var dmg = args.Data.ReadInt16(); + var pvp = args.Data.ReadInt8() == 0; + + int textlength = (int) (args.Data.Length - args.Data.Position - 1); + string deathtext = ""; + if (textlength > 0) + { + deathtext = Encoding.ASCII.GetString(args.Data.ReadBytes(textlength)); + if (!TShock.Utils.ValidString(deathtext)) + { + return true; + } + } + + args.Player.LastDeath = DateTime.Now; + args.Player.Dead = true; + + return false; + } + + private static bool HandleLiquidSet(GetDataHandlerArgs args) + { + int tileX = args.Data.ReadInt32(); + int tileY = args.Data.ReadInt32(); + byte liquid = args.Data.ReadInt8(); + bool lava = args.Data.ReadBoolean(); + + //The liquid was picked up. + if (liquid == 0) + return false; + + if (tileX < 0 || tileX >= Main.maxTilesX || tileY < 0 || tileY >= Main.maxTilesY) + return false; + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (args.Player.TileLiquidThreshold >= TShock.Config.TileLiquidThreshold) + { + args.Player.Disable(); + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (!args.Player.Group.HasPermission(Permissions.ignoreliquidsetdetection)) + { + args.Player.TileLiquidThreshold++; + } + + int bucket = 0; + if (args.TPlayer.inventory[args.TPlayer.selectedItem].type == 206) + { + bucket = 1; + } + else if (args.TPlayer.inventory[args.TPlayer.selectedItem].type == 207) + { + bucket = 2; + } + + if (lava && bucket != 2 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && + TShock.Itembans.ItemIsBanned("Lava Bucket", args.Player)) + { + args.Player.Disable(); + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (!lava && bucket != 1 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && + TShock.Itembans.ItemIsBanned("Water Bucket", args.Player)) + { + args.Player.Disable(); + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (TShock.CheckTilePermission(args.Player, tileX, tileY)) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (TShock.CheckRangePermission(args.Player, tileX, tileY, 16)) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + return false; + } + + private static bool HandleTileKill(GetDataHandlerArgs args) + { + var tileX = args.Data.ReadInt32(); + var tileY = args.Data.ReadInt32(); + + if (tileX < 0 || tileX >= Main.maxTilesX || tileY < 0 || tileY >= Main.maxTilesY) + return false; + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (Main.tile[tileX, tileY].type != 0x15 && (!TShock.Utils.MaxChests() && Main.tile[tileX, tileY].type != 0)) //Chest + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (TShock.CheckTilePermission(args.Player, tileX, tileY)) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + if (TShock.CheckRangePermission(args.Player, tileX, tileY)) + { + args.Player.SendTileSquare(tileX, tileY); + return true; + } + + return false; + } + + private static bool HandleSpawn(GetDataHandlerArgs args) + { + var player = args.Data.ReadInt8(); + var spawnx = args.Data.ReadInt32(); + var spawny = args.Data.ReadInt32(); + + if (args.Player.InitSpawn && args.TPlayer.inventory[args.TPlayer.selectedItem].type != 50) + { + if (args.TPlayer.difficulty == 1 && (TShock.Config.KickOnMediumcoreDeath || TShock.Config.BanOnMediumcoreDeath)) + { + if (args.TPlayer.selectedItem != 50) + { + if (TShock.Config.BanOnMediumcoreDeath) + { + if (!TShock.Utils.Ban(args.Player, TShock.Config.MediumcoreBanReason)) + TShock.Utils.ForceKick(args.Player, "Death results in a ban, but can't ban you"); + } + else + { + TShock.Utils.ForceKick(args.Player, TShock.Config.MediumcoreKickReason); + } + return true; + } + } + } + else + args.Player.InitSpawn = true; + + args.Player.Dead = false; + return false; + } + + private static bool HandleChestOpen(GetDataHandlerArgs args) + { + var x = args.Data.ReadInt32(); + var y = args.Data.ReadInt32(); + + if (TShock.CheckIgnores(args.Player)) + { + return true; + } + + if (TShock.CheckRangePermission(args.Player, x, y)) + { + return true; + } + + if (TShock.CheckTilePermission(args.Player, x, y) && TShock.Config.RegionProtectChests) + { + return true; + } + + return false; + } + + private static bool HandleChestItem(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt16(); + var slot = args.Data.ReadInt8(); + var stacks = args.Data.ReadInt8(); + var prefix = args.Data.ReadInt8(); + var type = args.Data.ReadInt16(); + + if (args.TPlayer.chest != id) + { + return false; + } + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.SendData(PacketTypes.ChestItem, "", id, slot); + return true; + } + + Item item = new Item(); + item.netDefaults(type); + if (stacks > item.maxStack || TShock.Itembans.ItemIsBanned(item.name, args.Player)) + { + return false; + } + + if (TShock.CheckTilePermission(args.Player, Main.chest[id].x, Main.chest[id].y) && TShock.Config.RegionProtectChests) + { + return false; + } + + if (TShock.CheckRangePermission(args.Player, Main.chest[id].x, Main.chest[id].y)) + { + return false; + } + + return false; + } + + private static bool HandleSign(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt16(); + var x = args.Data.ReadInt32(); + var y = args.Data.ReadInt32(); + + if (TShock.CheckTilePermission(args.Player, x, y)) + { + args.Player.SendData(PacketTypes.SignNew, "", id); + return true; + } + + if (TShock.CheckRangePermission(args.Player, x, y)) + { + args.Player.SendData(PacketTypes.SignNew, "", id); + return true; + } + return false; + } + + private static bool UpdateNPCHome(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt16(); + var x = args.Data.ReadInt16(); + var y = args.Data.ReadInt16(); + var homeless = args.Data.ReadInt8(); + + if (!args.Player.Group.HasPermission(Permissions.movenpc)) + { + args.Player.SendMessage("You do not have permission to relocate NPCs.", Color.Red); + args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY, + Convert.ToByte(Main.npc[id].homeless)); + return true; + } + + if (TShock.CheckTilePermission(args.Player, x, y)) + { + args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY, + Convert.ToByte(Main.npc[id].homeless)); + return true; + } + + if (TShock.CheckRangePermission(args.Player, x, y)) + { + args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY, + Convert.ToByte(Main.npc[id].homeless)); + return true; + } + return false; + } + + private static bool HandlePlayerBuff(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt8(); + var type = args.Data.ReadInt8(); + var time = args.Data.ReadInt16(); + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.SendData(PacketTypes.PlayerBuff, "", id); + return true; + } + if (!TShock.Players[id].TPlayer.hostile) + { + args.Player.SendData(PacketTypes.PlayerBuff, "", id); + return true; + } + if (TShock.CheckRangePermission(args.Player, TShock.Players[id].TileX, TShock.Players[id].TileY, 50)) + { + args.Player.SendData(PacketTypes.PlayerBuff, "", id); + return true; + } + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.SendData(PacketTypes.PlayerBuff, "", id); + return true; + } + + if (WhitelistBuffMaxTime[type] > 0 && time <= WhitelistBuffMaxTime[type]) + { + return false; + } + + args.Player.SendData(PacketTypes.PlayerBuff, "", id); + return true; + } + + private static bool HandleItemDrop(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt16(); + var pos = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); + var vel = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); + var stacks = args.Data.ReadInt8(); + var prefix = args.Data.ReadInt8(); + var type = args.Data.ReadInt16(); + + if (type == 0) //Item removed, let client do this to prevent item duplication client side + { + return false; + } + + if (TShock.CheckRangePermission(args.Player, (int) (pos.X/16f), (int) (pos.Y/16f))) + { + args.Player.SendData(PacketTypes.ItemDrop, "", id); + return true; + } + + Item item = new Item(); + item.netDefaults(type); + if (stacks > item.maxStack || TShock.Itembans.ItemIsBanned(item.name, args.Player)) + { + args.Player.SendData(PacketTypes.ItemDrop, "", id); + return true; + } + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.SendData(PacketTypes.ItemDrop, "", id); + return true; + } + + return false; + } + + private static bool HandlePlayerDamage(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt8(); + var direction = args.Data.ReadInt8(); + var dmg = args.Data.ReadInt16(); + var pvp = args.Data.ReadInt8(); + var crit = args.Data.ReadInt8(); + + int textlength = (int) (args.Data.Length - args.Data.Position - 1); + string deathtext = ""; + if (textlength > 0) + { + deathtext = Encoding.ASCII.GetString(args.Data.ReadBytes(textlength)); + if (!TShock.Utils.ValidString(deathtext)) + { + return true; + } + } + + if (TShock.Players[id] == null) + return true; + + if (dmg > 175) + { + args.Player.Disable(); + args.Player.SendData(PacketTypes.PlayerHp, "", id); + args.Player.SendData(PacketTypes.PlayerUpdate, "", id); + return true; + } + + if (!TShock.Players[id].TPlayer.hostile) + { + args.Player.SendData(PacketTypes.PlayerHp, "", id); + args.Player.SendData(PacketTypes.PlayerUpdate, "", id); + return true; + } + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.SendData(PacketTypes.PlayerHp, "", id); + args.Player.SendData(PacketTypes.PlayerUpdate, "", id); + return true; + } + + if (TShock.CheckRangePermission(args.Player, TShock.Players[id].TileX, TShock.Players[id].TileY, 100)) + { + args.Player.SendData(PacketTypes.PlayerHp, "", id); + args.Player.SendData(PacketTypes.PlayerUpdate, "", id); + return true; + } + + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.SendData(PacketTypes.PlayerHp, "", id); + args.Player.SendData(PacketTypes.PlayerUpdate, "", id); + return true; + } + + return false; + } + + private static bool HandleNpcStrike(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt8(); + var direction = args.Data.ReadInt8(); + var dmg = args.Data.ReadInt16(); + var pvp = args.Data.ReadInt8(); + var crit = args.Data.ReadInt8(); + + if (Main.npc[id] == null) + return true; + + if (dmg > 175) + { + args.Player.Disable(); + args.Player.SendData(PacketTypes.NpcUpdate, "", id); + return true; + } + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.SendData(PacketTypes.NpcUpdate, "", id); + return true; + } + + if (Main.npc[id].townNPC && !args.Player.Group.HasPermission(Permissions.movenpc)) + { + args.Player.SendData(PacketTypes.NpcUpdate, "", id); + return true; + } + + if (TShock.Config.RangeChecks && + TShock.CheckRangePermission(args.Player, (int) (Main.npc[id].position.X/16f), (int) (Main.npc[id].position.Y/16f), + 100)) + { + args.Player.SendData(PacketTypes.NpcUpdate, "", id); + return true; + } + + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.SendData(PacketTypes.NpcUpdate, "", id); + return true; + } + + return false; + } + + private static bool HandleSpecial(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt8(); + var type = args.Data.ReadInt8(); + + if (type == 1 && TShock.Config.DisableDungeonGuardian) + { + args.Player.SendMessage("The Dungeon Guardian returned you to your spawn point", Color.Purple); + args.Player.Spawn(); + return true; + } + + return false; + } + + private static bool HandlePlayerAnimation(GetDataHandlerArgs args) + { + if (TShock.CheckIgnores(args.Player)) + { + args.Player.SendData(PacketTypes.PlayerAnimation, "", args.Player.Index); + return true; + } + + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.SendData(PacketTypes.PlayerAnimation, "", args.Player.Index); + return true; + } + + return false; + } + + private static bool HandlePlayerBuffUpdate(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt8(); + for (int i = 0; i < 10; i++) + { + var buff = args.Data.ReadInt8(); + + if (buff == 10) + { + if (!args.Player.Group.HasPermission(Permissions.usebanneditem) && + TShock.Itembans.ItemIsBanned("Invisibility Potion", args.Player)) + buff = 0; + else if (TShock.Config.DisableInvisPvP && args.TPlayer.hostile) + buff = 0; + } + + args.TPlayer.buffType[i] = buff; + if (args.TPlayer.buffType[i] > 0) + { + args.TPlayer.buffTime[i] = 60; + } + else + { + args.TPlayer.buffTime[i] = 0; + } + } + NetMessage.SendData((int) PacketTypes.PlayerBuff, -1, args.Player.Index, "", args.Player.Index); + return true; + } + } +} \ No newline at end of file diff --git a/TShockAPI/Group.cs b/TShockAPI/Group.cs index 78877c42..18a84a5d 100644 --- a/TShockAPI/Group.cs +++ b/TShockAPI/Group.cs @@ -20,87 +20,87 @@ using System.Collections.Generic; namespace TShockAPI { - public class Group - { - public readonly List permissions = new List(); - public readonly List negatedpermissions = new List(); + public class Group + { + public readonly List permissions = new List(); + public readonly List negatedpermissions = new List(); - public string Name { get; set; } - public Group Parent { get; set; } - public int Order { get; set; } - public string Prefix { get; set; } - public string Suffix { get; set; } + public string Name { get; set; } + public Group Parent { get; set; } + public int Order { get; set; } + public string Prefix { get; set; } + public string Suffix { get; set; } - public byte R = 255; - public byte G = 255; - public byte B = 255; + public byte R = 255; + public byte G = 255; + public byte B = 255; - public Group(string groupname, Group parentgroup = null, string chatcolor = "255,255,255") - { - Name = groupname; - Parent = parentgroup; - byte.TryParse(chatcolor.Split(',')[0], out R); - byte.TryParse(chatcolor.Split(',')[1], out G); - byte.TryParse(chatcolor.Split(',')[2], out B); - } + public Group(string groupname, Group parentgroup = null, string chatcolor = "255,255,255") + { + Name = groupname; + Parent = parentgroup; + byte.TryParse(chatcolor.Split(',')[0], out R); + byte.TryParse(chatcolor.Split(',')[1], out G); + byte.TryParse(chatcolor.Split(',')[2], out B); + } - public virtual bool HasPermission(string permission) - { - var cur = this; - var traversed = new List(); - while (cur != null) - { - if (string.IsNullOrEmpty(permission)) - return true; - if (cur.negatedpermissions.Contains(permission)) - return false; - if (cur.permissions.Contains(permission)) - return true; - if (traversed.Contains(cur)) - { - throw new Exception("Infinite group parenting ({0})".SFormat(cur.Name)); - } - traversed.Add(cur); - cur = cur.Parent; - } - return false; - } + public virtual bool HasPermission(string permission) + { + var cur = this; + var traversed = new List(); + while (cur != null) + { + if (string.IsNullOrEmpty(permission)) + return true; + if (cur.negatedpermissions.Contains(permission)) + return false; + if (cur.permissions.Contains(permission)) + return true; + if (traversed.Contains(cur)) + { + throw new Exception("Infinite group parenting ({0})".SFormat(cur.Name)); + } + traversed.Add(cur); + cur = cur.Parent; + } + return false; + } - public void NegatePermission(string permission) - { - negatedpermissions.Add(permission); - } + public void NegatePermission(string permission) + { + negatedpermissions.Add(permission); + } - public void AddPermission(string permission) - { - permissions.Add(permission); - } - public void SetPermission( List permission) - { - permissions.Clear(); - foreach( string s in permission ) - { - permissions.Add( s ); - } - } - } + public void AddPermission(string permission) + { + permissions.Add(permission); + } - public class SuperAdminGroup : Group - { - public SuperAdminGroup() - : base("superadmin") - { - R = (byte)TShock.Config.SuperAdminChatRGB[0]; - G = (byte)TShock.Config.SuperAdminChatRGB[1]; - B = (byte)TShock.Config.SuperAdminChatRGB[2]; - Prefix = TShock.Config.SuperAdminChatPrefix; - Suffix = TShock.Config.SuperAdminChatSuffix; + public void SetPermission(List permission) + { + permissions.Clear(); + foreach (string s in permission) + { + permissions.Add(s); + } + } + } - } + public class SuperAdminGroup : Group + { + public SuperAdminGroup() + : base("superadmin") + { + R = (byte) TShock.Config.SuperAdminChatRGB[0]; + G = (byte) TShock.Config.SuperAdminChatRGB[1]; + B = (byte) TShock.Config.SuperAdminChatRGB[2]; + Prefix = TShock.Config.SuperAdminChatPrefix; + Suffix = TShock.Config.SuperAdminChatSuffix; + } - public override bool HasPermission(string permission) - { - return true; - } - } + public override bool HasPermission(string permission) + { + return true; + } + } } \ No newline at end of file diff --git a/TShockAPI/IPackable.cs b/TShockAPI/IPackable.cs index a28952e3..d117794d 100644 --- a/TShockAPI/IPackable.cs +++ b/TShockAPI/IPackable.cs @@ -20,20 +20,21 @@ using System.IO; namespace TShockAPI { - /// - /// Derived objects can be written to and read from streams. - /// - public interface IPackable - { - /// - /// Writes object information to the stream - /// - /// Stream to write to - void Pack(Stream stream); - /// - /// Reads object information from the stream - /// - /// Stream to read from - void Unpack(Stream stream); - } -} + /// + /// Derived objects can be written to and read from streams. + /// + public interface IPackable + { + /// + /// Writes object information to the stream + /// + /// Stream to write to + void Pack(Stream stream); + + /// + /// Reads object information from the stream + /// + /// Stream to read from + void Unpack(Stream stream); + } +} \ No newline at end of file diff --git a/TShockAPI/Log.cs b/TShockAPI/Log.cs index 3096e765..bdc17c0e 100644 --- a/TShockAPI/Log.cs +++ b/TShockAPI/Log.cs @@ -22,147 +22,147 @@ using System.IO; namespace TShockAPI { - public enum LogLevel - { - None = 0, - Debug = 1, - Info = 2, - Warning = 4, - Error = 8, - Data = 16, - All = 31 - } + public enum LogLevel + { + None = 0, + Debug = 1, + Info = 2, + Warning = 4, + Error = 8, + Data = 16, + All = 31 + } - public static class Log - { - private static string _filename; - private static LogLevel _logLevel; - private static StreamWriter _logWriter; + public static class Log + { + private static string _filename; + private static LogLevel _logLevel; + private static StreamWriter _logWriter; - /// - /// Creates the log file stream and sets the initial log level. - /// - /// The output filename. This file will be overwritten if 'clear' is set. - /// The value which sets the type of messages to output. - /// Whether or not to clear the log file on initialization. - public static void Initialize(string filename, LogLevel logLevel, bool clear) - { - _filename = filename; - _logLevel = logLevel; + /// + /// Creates the log file stream and sets the initial log level. + /// + /// The output filename. This file will be overwritten if 'clear' is set. + /// The value which sets the type of messages to output. + /// Whether or not to clear the log file on initialization. + public static void Initialize(string filename, LogLevel logLevel, bool clear) + { + _filename = filename; + _logLevel = logLevel; - _logWriter = new StreamWriter(filename, !clear); - } + _logWriter = new StreamWriter(filename, !clear); + } - /// - /// Checks whether the log level contains the specified flag. - /// - /// The value to check. - private static bool MayWriteType(LogLevel type) - { - return ((_logLevel & type) == type); - } + /// + /// Checks whether the log level contains the specified flag. + /// + /// The value to check. + private static bool MayWriteType(LogLevel type) + { + return ((_logLevel & type) == type); + } - /// - /// Writes data to the log file. - /// - /// The message to be written. - public static void Data(String message) - { - Write(message, LogLevel.Data); - } + /// + /// Writes data to the log file. + /// + /// The message to be written. + public static void Data(String message) + { + Write(message, LogLevel.Data); + } - /// - /// Writes an error to the log file. - /// - /// The message to be written. - public static void Error(String message) - { - Write(message, LogLevel.Error); - } - - /// - /// Writes an error to the log file. - /// - /// The message to be written. - public static void ConsoleError(String message) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine(message); - Console.ForegroundColor = ConsoleColor.Gray; - Write(message, LogLevel.Error); - } + /// + /// Writes an error to the log file. + /// + /// The message to be written. + public static void Error(String message) + { + Write(message, LogLevel.Error); + } - /// - /// Writes a warning to the log file. - /// - /// The message to be written. - public static void Warn(String message) - { - Write(message, LogLevel.Warning); - } + /// + /// Writes an error to the log file. + /// + /// The message to be written. + public static void ConsoleError(String message) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(message); + Console.ForegroundColor = ConsoleColor.Gray; + Write(message, LogLevel.Error); + } - /// - /// Writes an informative string to the log file. - /// - /// The message to be written. - public static void Info(String message) - { - Write(message, LogLevel.Info); - } + /// + /// Writes a warning to the log file. + /// + /// The message to be written. + public static void Warn(String message) + { + Write(message, LogLevel.Warning); + } - /// - /// Writes an informative string to the log file. Also outputs to the console. - /// - /// The message to be written. - public static void ConsoleInfo(String message) - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine(message); - Console.ForegroundColor = ConsoleColor.Gray; - Write(message, LogLevel.Info); - } + /// + /// Writes an informative string to the log file. + /// + /// The message to be written. + public static void Info(String message) + { + Write(message, LogLevel.Info); + } - /// - /// Writes a debug string to the log file. - /// - /// The message to be written. - public static void Debug(String message) - { - Write(message, LogLevel.Debug); - } + /// + /// Writes an informative string to the log file. Also outputs to the console. + /// + /// The message to be written. + public static void ConsoleInfo(String message) + { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine(message); + Console.ForegroundColor = ConsoleColor.Gray; + Write(message, LogLevel.Info); + } - /// - /// Disposes objects that are being used. - /// - public static void Dispose() - { - _logWriter.Dispose(); - } + /// + /// Writes a debug string to the log file. + /// + /// The message to be written. + public static void Debug(String message) + { + Write(message, LogLevel.Debug); + } - /// - /// Internal method which writes a message directly to the log file. - /// - private static void Write(String message, LogLevel level) - { - if (!MayWriteType(level)) - { - return; - } + /// + /// Disposes objects that are being used. + /// + public static void Dispose() + { + _logWriter.Dispose(); + } - string caller = "TShock"; + /// + /// Internal method which writes a message directly to the log file. + /// + private static void Write(String message, LogLevel level) + { + if (!MayWriteType(level)) + { + return; + } - StackFrame frame = new StackTrace().GetFrame(2); - if (frame != null) - { - var meth = frame.GetMethod(); - if (meth != null) - caller = meth.DeclaringType.Name; - } + string caller = "TShock"; - _logWriter.WriteLine(string.Format("{0} - {1}: {2}: {3}", - DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), - caller, level.ToString().ToUpper(), message)); - _logWriter.Flush(); - } - } + StackFrame frame = new StackTrace().GetFrame(2); + if (frame != null) + { + var meth = frame.GetMethod(); + if (meth != null) + caller = meth.DeclaringType.Name; + } + + _logWriter.WriteLine(string.Format("{0} - {1}: {2}: {3}", + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), + caller, level.ToString().ToUpper(), message)); + _logWriter.Flush(); + } + } } \ No newline at end of file diff --git a/TShockAPI/Net/BaseMsg.cs b/TShockAPI/Net/BaseMsg.cs index 8aa2b606..1e71a6f1 100644 --- a/TShockAPI/Net/BaseMsg.cs +++ b/TShockAPI/Net/BaseMsg.cs @@ -4,32 +4,33 @@ using System.IO.Streams; namespace TShockAPI.Net { - public class BaseMsg : IPackable - { - public virtual PacketTypes ID - { - get { throw new NotImplementedException("Msg ID not implemented"); } - } - public void PackFull(Stream stream) - { - long start = stream.Position; - stream.WriteInt32(1); - stream.WriteInt8((byte)ID); - Pack(stream); - long end = stream.Position; - stream.Position = start; - stream.WriteInt32((int)(end - start) - 4); - stream.Position = end; - } + public class BaseMsg : IPackable + { + public virtual PacketTypes ID + { + get { throw new NotImplementedException("Msg ID not implemented"); } + } - public virtual void Unpack(Stream stream) - { - throw new NotImplementedException(); - } + public void PackFull(Stream stream) + { + long start = stream.Position; + stream.WriteInt32(1); + stream.WriteInt8((byte) ID); + Pack(stream); + long end = stream.Position; + stream.Position = start; + stream.WriteInt32((int) (end - start) - 4); + stream.Position = end; + } - public virtual void Pack(Stream stream) - { - throw new NotImplementedException(); - } - } -} + public virtual void Unpack(Stream stream) + { + throw new NotImplementedException(); + } + + public virtual void Pack(Stream stream) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/TShockAPI/Net/DisconnectMsg.cs b/TShockAPI/Net/DisconnectMsg.cs index a8318e6b..879d6bff 100644 --- a/TShockAPI/Net/DisconnectMsg.cs +++ b/TShockAPI/Net/DisconnectMsg.cs @@ -4,19 +4,18 @@ using System.Text; namespace TShockAPI.Net { - class DisconnectMsg : BaseMsg - { - public override PacketTypes ID - { - get - { - return PacketTypes.Disconnect; - } - } - public string Reason {get;set;} - public override void Pack(Stream stream) - { - stream.WriteBytes(Encoding.ASCII.GetBytes(Reason)); - } - } -} + internal class DisconnectMsg : BaseMsg + { + public override PacketTypes ID + { + get { return PacketTypes.Disconnect; } + } + + public string Reason { get; set; } + + public override void Pack(Stream stream) + { + stream.WriteBytes(Encoding.ASCII.GetBytes(Reason)); + } + } +} \ No newline at end of file diff --git a/TShockAPI/Net/NetTile.cs b/TShockAPI/Net/NetTile.cs index 12e4bc80..b1ab9c31 100644 --- a/TShockAPI/Net/NetTile.cs +++ b/TShockAPI/Net/NetTile.cs @@ -23,116 +23,127 @@ using Terraria; namespace TShockAPI.Net { - public class NetTile : IPackable - { - public bool Active { get; set; } - public byte Type { get; set; } - public short FrameX { get; set; } - public short FrameY { get; set; } - public byte Wall { get; set; } - public byte Liquid { get; set; } - public bool Lava { get; set; } - public bool Wire { get; set; } + public class NetTile : IPackable + { + public bool Active { get; set; } + public byte Type { get; set; } + public short FrameX { get; set; } + public short FrameY { get; set; } + public byte Wall { get; set; } + public byte Liquid { get; set; } + public bool Lava { get; set; } + public bool Wire { get; set; } - public bool HasWall { get { return Wall > 0; } } - public bool HasLiquid { get { return Liquid > 0; } } - public bool FrameImportant { get { return Main.tileFrameImportant[Type]; } } + public bool HasWall + { + get { return Wall > 0; } + } - public NetTile() - { - Active = false; - Type = 0; - FrameX = -1; - FrameY = -1; - Wall = 0; - Liquid = 0; - Lava = false; - Wire = false; - } + public bool HasLiquid + { + get { return Liquid > 0; } + } - public NetTile(Stream stream) - : this() - { - Unpack(stream); - } + public bool FrameImportant + { + get { return Main.tileFrameImportant[Type]; } + } - public void Pack(Stream stream) - { - var flags = TileFlags.None; + public NetTile() + { + Active = false; + Type = 0; + FrameX = -1; + FrameY = -1; + Wall = 0; + Liquid = 0; + Lava = false; + Wire = false; + } - if (Active) - flags |= TileFlags.Active; + public NetTile(Stream stream) + : this() + { + Unpack(stream); + } - if (HasWall) - flags |= TileFlags.Wall; + public void Pack(Stream stream) + { + var flags = TileFlags.None; - if (HasLiquid) - flags |= TileFlags.Liquid; + if (Active) + flags |= TileFlags.Active; - if (Wire) - flags |= TileFlags.Wire; + if (HasWall) + flags |= TileFlags.Wall; - stream.WriteInt8((byte)flags); + if (HasLiquid) + flags |= TileFlags.Liquid; - if (Active) - { - stream.WriteInt8(Type); - if (FrameImportant) - { - stream.WriteInt16(FrameX); - stream.WriteInt16(FrameY); - } - } + if (Wire) + flags |= TileFlags.Wire; - if (HasWall) - stream.WriteInt8(Wall); + stream.WriteInt8((byte) flags); - if (HasLiquid) - { - stream.WriteInt8(Liquid); - stream.WriteBoolean(Lava); - } - } + if (Active) + { + stream.WriteInt8(Type); + if (FrameImportant) + { + stream.WriteInt16(FrameX); + stream.WriteInt16(FrameY); + } + } - public void Unpack(Stream stream) - { - var flags = (TileFlags)stream.ReadInt8(); + if (HasWall) + stream.WriteInt8(Wall); - Active = flags.HasFlag(TileFlags.Active); - if (Active) - { - Type = stream.ReadInt8(); - if (FrameImportant) - { - FrameX = stream.ReadInt16(); - FrameY = stream.ReadInt16(); - } - } + if (HasLiquid) + { + stream.WriteInt8(Liquid); + stream.WriteBoolean(Lava); + } + } - if (flags.HasFlag(TileFlags.Wall)) - { - Wall = stream.ReadInt8(); - } + public void Unpack(Stream stream) + { + var flags = (TileFlags) stream.ReadInt8(); - if (flags.HasFlag(TileFlags.Liquid)) - { - Liquid = stream.ReadInt8(); - Lava = stream.ReadBoolean(); - } + Active = flags.HasFlag(TileFlags.Active); + if (Active) + { + Type = stream.ReadInt8(); + if (FrameImportant) + { + FrameX = stream.ReadInt16(); + FrameY = stream.ReadInt16(); + } + } - if (flags.HasFlag(TileFlags.Wire)) - Wire = true; - } - } + if (flags.HasFlag(TileFlags.Wall)) + { + Wall = stream.ReadInt8(); + } - [Flags] - public enum TileFlags : byte - { - None = 0, - Active = 1, - Lighted = 2, - Wall = 4, - Liquid = 8, - Wire = 16 - } -} + if (flags.HasFlag(TileFlags.Liquid)) + { + Liquid = stream.ReadInt8(); + Lava = stream.ReadBoolean(); + } + + if (flags.HasFlag(TileFlags.Wire)) + Wire = true; + } + } + + [Flags] + public enum TileFlags : byte + { + None = 0, + Active = 1, + Lighted = 2, + Wall = 4, + Liquid = 8, + Wire = 16 + } +} \ No newline at end of file diff --git a/TShockAPI/Net/ProjectileRemoveMsg.cs b/TShockAPI/Net/ProjectileRemoveMsg.cs index c4c68f34..beec584c 100644 --- a/TShockAPI/Net/ProjectileRemoveMsg.cs +++ b/TShockAPI/Net/ProjectileRemoveMsg.cs @@ -3,33 +3,30 @@ using System.IO.Streams; namespace TShockAPI.Net { - public class ProjectileRemoveMsg : BaseMsg - { - public override PacketTypes ID - { - get - { - return PacketTypes.ProjectileNew; - } - } + public class ProjectileRemoveMsg : BaseMsg + { + public override PacketTypes ID + { + get { return PacketTypes.ProjectileNew; } + } - public short Index { get; set; } - public byte Owner { get; set; } + public short Index { get; set; } + public byte Owner { get; set; } - public override void Pack(Stream stream) - { - stream.WriteInt16(Index); - stream.WriteSingle(-1); - stream.WriteSingle(-1); - stream.WriteSingle(0); - stream.WriteSingle(0); - stream.WriteSingle(0); - stream.WriteInt16(0); - stream.WriteByte(Owner); - stream.WriteByte(0); - stream.WriteSingle(0); - stream.WriteSingle(0); - stream.WriteSingle(0); - } - } -} + public override void Pack(Stream stream) + { + stream.WriteInt16(Index); + stream.WriteSingle(-1); + stream.WriteSingle(-1); + stream.WriteSingle(0); + stream.WriteSingle(0); + stream.WriteSingle(0); + stream.WriteInt16(0); + stream.WriteByte(Owner); + stream.WriteByte(0); + stream.WriteSingle(0); + stream.WriteSingle(0); + stream.WriteSingle(0); + } + } +} \ No newline at end of file diff --git a/TShockAPI/Net/SpawnMsg.cs b/TShockAPI/Net/SpawnMsg.cs index dc851379..d49d0b5c 100644 --- a/TShockAPI/Net/SpawnMsg.cs +++ b/TShockAPI/Net/SpawnMsg.cs @@ -3,25 +3,22 @@ using System.IO.Streams; namespace TShockAPI.Net { - public class SpawnMsg : BaseMsg - { - public override PacketTypes ID - { - get - { - return PacketTypes.PlayerSpawn; - } - } + public class SpawnMsg : BaseMsg + { + public override PacketTypes ID + { + get { return PacketTypes.PlayerSpawn; } + } - public int TileX { get; set; } - public int TileY {get;set;} - public byte PlayerIndex { get; set; } + public int TileX { get; set; } + public int TileY { get; set; } + public byte PlayerIndex { get; set; } - public override void Pack(Stream stream) - { - stream.WriteInt8(PlayerIndex); - stream.WriteInt32(TileX); - stream.WriteInt32(TileY); - } - } -} + public override void Pack(Stream stream) + { + stream.WriteInt8(PlayerIndex); + stream.WriteInt32(TileX); + stream.WriteInt32(TileY); + } + } +} \ No newline at end of file diff --git a/TShockAPI/Net/WorldInfoMsg.cs b/TShockAPI/Net/WorldInfoMsg.cs index a01807a1..0fe02b2e 100644 --- a/TShockAPI/Net/WorldInfoMsg.cs +++ b/TShockAPI/Net/WorldInfoMsg.cs @@ -23,54 +23,54 @@ using System.Text; namespace TShockAPI.Net { - [Flags] - public enum WorldInfoFlag : byte - { - None = 0, - OrbSmashed = 1, - DownedBoss1 = 2, - DownedBoss2 = 4, - DownedBoss3 = 8, - HardMode = 16, - DownedClown = 32 - } - public class WorldInfoMsg : BaseMsg - { - public int Time { get; set; } - public bool DayTime { get; set; } - public byte MoonPhase { get; set; } - public bool BloodMoon { get; set; } - public int MaxTilesX { get; set; } - public int MaxTilesY { get; set; } - public int SpawnX { get; set; } - public int SpawnY { get; set; } - public int WorldSurface { get; set; } - public int RockLayer { get; set; } - public int WorldID { get; set; } - public WorldInfoFlag WorldFlags { get; set; } - public string WorldName { get; set; } - public override PacketTypes ID - { - get - { - return PacketTypes.WorldInfo; - } - } - public override void Pack(Stream stream) - { - stream.WriteInt32(Time); - stream.WriteBoolean(DayTime); - stream.WriteInt8(MoonPhase); - stream.WriteBoolean(BloodMoon); - stream.WriteInt32(MaxTilesX); - stream.WriteInt32(MaxTilesY); - stream.WriteInt32(SpawnX); - stream.WriteInt32(SpawnY); - stream.WriteInt32(WorldSurface); - stream.WriteInt32(RockLayer); - stream.WriteInt32(WorldID); - stream.WriteInt8((byte)WorldFlags); - stream.WriteBytes(Encoding.ASCII.GetBytes(WorldName)); - } - } -} + [Flags] + public enum WorldInfoFlag : byte + { + None = 0, + OrbSmashed = 1, + DownedBoss1 = 2, + DownedBoss2 = 4, + DownedBoss3 = 8, + HardMode = 16, + DownedClown = 32 + } + + public class WorldInfoMsg : BaseMsg + { + public int Time { get; set; } + public bool DayTime { get; set; } + public byte MoonPhase { get; set; } + public bool BloodMoon { get; set; } + public int MaxTilesX { get; set; } + public int MaxTilesY { get; set; } + public int SpawnX { get; set; } + public int SpawnY { get; set; } + public int WorldSurface { get; set; } + public int RockLayer { get; set; } + public int WorldID { get; set; } + public WorldInfoFlag WorldFlags { get; set; } + public string WorldName { get; set; } + + public override PacketTypes ID + { + get { return PacketTypes.WorldInfo; } + } + + public override void Pack(Stream stream) + { + stream.WriteInt32(Time); + stream.WriteBoolean(DayTime); + stream.WriteInt8(MoonPhase); + stream.WriteBoolean(BloodMoon); + stream.WriteInt32(MaxTilesX); + stream.WriteInt32(MaxTilesY); + stream.WriteInt32(SpawnX); + stream.WriteInt32(SpawnY); + stream.WriteInt32(WorldSurface); + stream.WriteInt32(RockLayer); + stream.WriteInt32(WorldID); + stream.WriteInt8((byte) WorldFlags); + stream.WriteBytes(Encoding.ASCII.GetBytes(WorldName)); + } + } +} \ No newline at end of file diff --git a/TShockAPI/PacketBufferer.cs b/TShockAPI/PacketBufferer.cs index 85c4b295..60b6e506 100644 --- a/TShockAPI/PacketBufferer.cs +++ b/TShockAPI/PacketBufferer.cs @@ -9,29 +9,29 @@ using Terraria; namespace TShockAPI { - public class PacketBufferer : IDisposable - { - /// - /// Maximum number of bytes to send per update per socket - /// - public int BytesPerUpdate { get; set; } + public class PacketBufferer : IDisposable + { + /// + /// Maximum number of bytes to send per update per socket + /// + public int BytesPerUpdate { get; set; } - PacketBuffer[] buffers = new PacketBuffer[Netplay.serverSock.Length]; + private PacketBuffer[] buffers = new PacketBuffer[Netplay.serverSock.Length]; - int[] Bytes = new int[52]; - int[] Packets = new int[52]; - int[] Compressed = new int[52]; + private int[] Bytes = new int[52]; + private int[] Packets = new int[52]; + private int[] Compressed = new int[52]; #if DEBUG_NET Command dump; Command flush; #endif - public PacketBufferer() - { - BytesPerUpdate = 0xFFFF; - for (int i = 0; i < buffers.Length; i++) - buffers[i] = new PacketBuffer(); + public PacketBufferer() + { + BytesPerUpdate = 0xFFFF; + for (int i = 0; i < buffers.Length; i++) + buffers[i] = new PacketBuffer(); #if DEBUG_NET dump = new Command("superadmin", Dump, "netdump"); @@ -40,113 +40,115 @@ namespace TShockAPI Commands.ChatCommands.Add(flush); #endif - NetHooks.SendBytes += ServerHooks_SendBytes; - ServerHooks.SocketReset += ServerHooks_SocketReset; - GameHooks.PostUpdate += GameHooks_Update; - } + NetHooks.SendBytes += ServerHooks_SendBytes; + ServerHooks.SocketReset += ServerHooks_SocketReset; + GameHooks.PostUpdate += GameHooks_Update; + } - ~PacketBufferer() - { - Dispose(false); - } + ~PacketBufferer() + { + Dispose(false); + } - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } - protected virtual void Dispose(bool disposing) - { - if (disposing) - { + protected virtual void Dispose(bool disposing) + { + if (disposing) + { #if DEBUG_NET Commands.ChatCommands.Remove(dump); Commands.ChatCommands.Remove(flush); #endif - NetHooks.SendBytes -= ServerHooks_SendBytes; - ServerHooks.SocketReset -= ServerHooks_SocketReset; - GameHooks.PostUpdate -= GameHooks_Update; - } - } + NetHooks.SendBytes -= ServerHooks_SendBytes; + ServerHooks.SocketReset -= ServerHooks_SocketReset; + GameHooks.PostUpdate -= GameHooks_Update; + } + } - void Dump(CommandArgs args) - { - var sb = new StringBuilder(); - sb.AppendLine("{0,-25}{1,-25}{2,-25}{3}".SFormat("Name:", "Packets", "Bytes", "Compression")); - for (int i = 1; i < Bytes.Length; i++) - { - sb.AppendLine("{0,-25}{1,-25}{2,-25}{3}".SFormat(Enum.GetName(typeof(PacketTypes), i) + ":", Packets[i], Bytes[i], Compressed[i])); - } - File.WriteAllText(Path.Combine(TShock.SavePath, "dmp.txt"), sb.ToString()); - } + private void Dump(CommandArgs args) + { + var sb = new StringBuilder(); + sb.AppendLine("{0,-25}{1,-25}{2,-25}{3}".SFormat("Name:", "Packets", "Bytes", "Compression")); + for (int i = 1; i < Bytes.Length; i++) + { + sb.AppendLine("{0,-25}{1,-25}{2,-25}{3}".SFormat(Enum.GetName(typeof (PacketTypes), i) + ":", Packets[i], Bytes[i], + Compressed[i])); + } + File.WriteAllText(Path.Combine(TShock.SavePath, "dmp.txt"), sb.ToString()); + } - void Flush(CommandArgs args) - { - Bytes = new int[52]; - Packets = new int[52]; - Compressed = new int[52]; - } + private void Flush(CommandArgs args) + { + Bytes = new int[52]; + Packets = new int[52]; + Compressed = new int[52]; + } - void GameHooks_Update() - { - FlushAll(); - } + private void GameHooks_Update() + { + FlushAll(); + } - public void FlushAll() - { - for (int i = 0; i < Netplay.serverSock.Length; i++) - { - Flush(Netplay.serverSock[i]); - } - } + public void FlushAll() + { + for (int i = 0; i < Netplay.serverSock.Length; i++) + { + Flush(Netplay.serverSock[i]); + } + } - public bool Flush(ServerSock socket) - { - try - { - if (socket == null || !socket.active) - return false; + public bool Flush(ServerSock socket) + { + try + { + if (socket == null || !socket.active) + return false; - if (buffers[socket.whoAmI].Count < 1) - return false; + if (buffers[socket.whoAmI].Count < 1) + return false; - byte[] buff = buffers[socket.whoAmI].GetBytes(BytesPerUpdate); - if (buff == null) - return false; + byte[] buff = buffers[socket.whoAmI].GetBytes(BytesPerUpdate); + if (buff == null) + return false; - if (SendBytes(socket, buff)) - { - buffers[socket.whoAmI].Pop(buff.Length); - return true; - } - } - catch (Exception e) - { - Log.ConsoleError(e.ToString()); - } - return false; - } + if (SendBytes(socket, buff)) + { + buffers[socket.whoAmI].Pop(buff.Length); + return true; + } + } + catch (Exception e) + { + Log.ConsoleError(e.ToString()); + } + return false; + } - void ServerHooks_SocketReset(ServerSock socket) - { - buffers[socket.whoAmI] = new PacketBuffer(); - } + private void ServerHooks_SocketReset(ServerSock socket) + { + buffers[socket.whoAmI] = new PacketBuffer(); + } - public bool SendBytes(ServerSock socket, byte[] buffer) - { - return SendBytes(socket, buffer, 0, buffer.Length); - } - public void BufferBytes(ServerSock socket, byte[] buffer) - { - BufferBytes(socket, buffer, 0, buffer.Length); - } + public bool SendBytes(ServerSock socket, byte[] buffer) + { + return SendBytes(socket, buffer, 0, buffer.Length); + } - public void BufferBytes(ServerSock socket, byte[] buffer, int offset, int count) - { - lock (buffers[socket.whoAmI]) - { + public void BufferBytes(ServerSock socket, byte[] buffer) + { + BufferBytes(socket, buffer, 0, buffer.Length); + } + + public void BufferBytes(ServerSock socket, byte[] buffer, int offset, int count) + { + lock (buffers[socket.whoAmI]) + { #if DEBUG_NET int size = (count - offset); var pt = buffer[offset + 4]; @@ -155,43 +157,44 @@ namespace TShockAPI Bytes[pt] += size; Compressed[pt] += Compress(buffer, offset, count); #endif - using (var ms = new MemoryStream(buffer, offset, count)) - { - buffers[socket.whoAmI].AddRange(ms.ToArray()); - } - } - } + using (var ms = new MemoryStream(buffer, offset, count)) + { + buffers[socket.whoAmI].AddRange(ms.ToArray()); + } + } + } - public bool SendBytes(ServerSock socket, byte[] buffer, int offset, int count) - { - try - { - if (socket.tcpClient.Client != null && socket.tcpClient.Client.Poll(0, SelectMode.SelectWrite)) - { - if (Main.runningMono) - socket.networkStream.Write(buffer, offset, count); - else - socket.tcpClient.Client.Send(buffer, offset, count, SocketFlags.None); - return true; - } - } - catch (ObjectDisposedException) - { - } - catch (SocketException) - { - } - catch (IOException) - { - } - return false; - } + public bool SendBytes(ServerSock socket, byte[] buffer, int offset, int count) + { + try + { + if (socket.tcpClient.Client != null && socket.tcpClient.Client.Poll(0, SelectMode.SelectWrite)) + { + if (Main.runningMono) + socket.networkStream.Write(buffer, offset, count); + else + socket.tcpClient.Client.Send(buffer, offset, count, SocketFlags.None); + return true; + } + } + catch (ObjectDisposedException) + { + } + catch (SocketException) + { + } + catch (IOException) + { + } + return false; + } + + private void ServerHooks_SendBytes(ServerSock socket, byte[] buffer, int offset, int count, HandledEventArgs e) + { + e.Handled = true; + BufferBytes(socket, buffer, offset, count); + } - void ServerHooks_SendBytes(ServerSock socket, byte[] buffer, int offset, int count, HandledEventArgs e) - { - e.Handled = true; - BufferBytes(socket, buffer, offset, count); - } #if DEBUG_NET static int Compress(byte[] buffer, int offset, int count) { @@ -205,29 +208,29 @@ namespace TShockAPI } } #endif - } + } - public class PacketBuffer : List - { - public byte[] GetBytes(int max) - { - lock (this) - { - if (this.Count < 1) - return null; + public class PacketBuffer : List + { + public byte[] GetBytes(int max) + { + lock (this) + { + if (this.Count < 1) + return null; - var ret = new byte[Math.Min(max, this.Count)]; - this.CopyTo(0, ret, 0, ret.Length); - return ret; - } - } + var ret = new byte[Math.Min(max, this.Count)]; + this.CopyTo(0, ret, 0, ret.Length); + return ret; + } + } - public void Pop(int count) - { - lock (this) - { - this.RemoveRange(0, count); - } - } - } -} + public void Pop(int count) + { + lock (this) + { + this.RemoveRange(0, count); + } + } + } +} \ No newline at end of file diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs index 5618ed98..449e556d 100644 --- a/TShockAPI/Permissions.cs +++ b/TShockAPI/Permissions.cs @@ -7,238 +7,193 @@ using System.Text; namespace TShockAPI { - public static class Permissions - { - //Permissions with blank descriptions basically means its described by the commands it gives access to. + public static class Permissions + { + //Permissions with blank descriptions basically means its described by the commands it gives access to. - [Description("")] - public static readonly string causeevents; + [Description("")] public static readonly string causeevents; - [Description("Required to be able to build (modify tiles and liquid)")] - public static readonly string canbuild; + [Description("Required to be able to build (modify tiles and liquid)")] public static readonly string canbuild; - [Description("")] - public static readonly string kill; + [Description("")] public static readonly string kill; - [Description("Allows you to use banned items")] - public static readonly string usebanneditem; + [Description("Allows you to use banned items")] public static readonly string usebanneditem; - [Description("Allows you to edit the spawn")] - public static readonly string editspawn; + [Description("Allows you to edit the spawn")] public static readonly string editspawn; - [Description("Prevents you from being kicked")] - public static readonly string immunetokick; + [Description("Prevents you from being kicked")] public static readonly string immunetokick; - [Description("Prevents you from being banned")] - public static readonly string immunetoban; + [Description("Prevents you from being banned")] public static readonly string immunetoban; - [Description("Prevents you from being reverted by kill tile abuse detection")] - public static readonly string ignorekilltiledetection; + [Description("Prevents you from being reverted by kill tile abuse detection")] public static readonly string + ignorekilltiledetection; - [Description("Prevents you from being reverted by place tile abuse detection")] - public static readonly string ignoreplacetiledetection; + [Description("Prevents you from being reverted by place tile abuse detection")] public static readonly string + ignoreplacetiledetection; - [Description("Prevents you from being disabled by liquid set abuse detection")] - public static readonly string ignoreliquidsetdetection; + [Description("Prevents you from being disabled by liquid set abuse detection")] public static readonly string + ignoreliquidsetdetection; - [Description("Prevents you from being disabled by liquid set abuse detection")] - public static readonly string ignoreprojectiledetection; + [Description("Prevents you from being disabled by liquid set abuse detection")] public static readonly string + ignoreprojectiledetection; - [Description("Prevents you from being reverted by no clip detection")] - public static readonly string ignorenoclipdetection; + [Description("Prevents you from being reverted by no clip detection")] public static readonly string + ignorenoclipdetection; - [Description("Prevents you from being disabled by stack hack detection")] - public static readonly string ignorestackhackdetection; + [Description("Prevents you from being disabled by stack hack detection")] public static readonly string + ignorestackhackdetection; - [Description("Prevents you from being kicked by hacked health detection")] - public static readonly string ignorestathackdetection; + [Description("Prevents you from being kicked by hacked health detection")] public static readonly string + ignorestathackdetection; - [Description("Specific log messages are sent to users with this permission")] - public static readonly string logs; + [Description("Specific log messages are sent to users with this permission")] public static readonly string logs; - [Description("Allows you to bypass the max slots for up to 5 slots above your max")] - public static readonly string reservedslot; + [Description("Allows you to bypass the max slots for up to 5 slots above your max")] public static readonly string + reservedslot; - [Description("User is notified when an update is available")] - public static readonly string maintenance; + [Description("User is notified when an update is available")] public static readonly string maintenance; - [Description("User can kick others")] - public static readonly string kick; + [Description("User can kick others")] public static readonly string kick; - [Description("User can ban others")] - public static readonly string ban; + [Description("User can ban others")] public static readonly string ban; - [Description("User can modify the whitelist")] - public static readonly string whitelist; + [Description("User can modify the whitelist")] public static readonly string whitelist; - [Description("User can spawn bosses")] - public static readonly string spawnboss; + [Description("User can spawn bosses")] public static readonly string spawnboss; - [Description("User can spawn npcs")] - public static readonly string spawnmob; + [Description("User can spawn npcs")] public static readonly string spawnmob; - [Description("User can teleport")] - public static readonly string tp; + [Description("User can teleport")] public static readonly string tp; - [Description("User can teleport people to them")] - public static readonly string tphere; + [Description("User can teleport people to them")] public static readonly string tphere; - [Description("User can use warps")] - public static readonly string warp; + [Description("User can use warps")] public static readonly string warp; - [Description("User can manage warps")] - public static readonly string managewarp; + [Description("User can manage warps")] public static readonly string managewarp; - [Description("User can manage item bans")] - public static readonly string manageitem; + [Description("User can manage item bans")] public static readonly string manageitem; - [Description("User can manage groups")] - public static readonly string managegroup; + [Description("User can manage groups")] public static readonly string managegroup; - [Description("User can edit sevrer configurations")] - public static readonly string cfg; + [Description("User can edit sevrer configurations")] public static readonly string cfg; - [Description("")] - public static readonly string time; + [Description("")] public static readonly string time; - [Description("")] - public static readonly string pvpfun; + [Description("")] public static readonly string pvpfun; - [Description("User can edit regions")] - public static readonly string manageregion; + [Description("User can edit regions")] public static readonly string manageregion; - [Description("Meant for super admins only")] - public static readonly string rootonly; + [Description("Meant for super admins only")] public static readonly string rootonly; - [Description("User can whisper to others")] - public static readonly string whisper; + [Description("User can whisper to others")] public static readonly string whisper; - [Description("")] - public static readonly string annoy; + [Description("")] public static readonly string annoy; - [Description("User can kill all enemy npcs")] - public static readonly string butcher; + [Description("User can kill all enemy npcs")] public static readonly string butcher; - [Description("User can spawn items")] - public static readonly string item; + [Description("User can spawn items")] public static readonly string item; - [Description("User can clear item drops.")] - public static readonly string clearitems; + [Description("User can clear item drops.")] public static readonly string clearitems; - [Description("")] - public static readonly string heal; + [Description("")] public static readonly string heal; - [Description("User can buff self")] - public static readonly string buff; + [Description("User can buff self")] public static readonly string buff; - [Description("User can buff other players")] - public static readonly string buffplayer; + [Description("User can buff other players")] public static readonly string buffplayer; - [Description("")] - public static readonly string grow; + [Description("")] public static readonly string grow; - [Description("User can change hardmode state.")] - public static readonly string hardmode; + [Description("User can change hardmode state.")] public static readonly string hardmode; - [Description("User can change the homes of NPCs.")] - public static readonly string movenpc; + [Description("User can change the homes of NPCs.")] public static readonly string movenpc; - [Description("Users can stop people from TPing to them")] - public static readonly string tpallow; + [Description("Users can stop people from TPing to them")] public static readonly string tpallow; - [Description("Users can tp to anyone")] - public static readonly string tpall; + [Description("Users can tp to anyone")] public static readonly string tpall; - [Description("Users can tp to people without showing a notice")] - public static readonly string tphide; + [Description("Users can tp to people without showing a notice")] public static readonly string tphide; - [Description("User can convert hallow into corruption and vice-versa")] - public static readonly string converthardmode; + [Description("User can convert hallow into corruption and vice-versa")] public static readonly string converthardmode; - [Description("User can mute and unmute users")] - public static readonly string mute; - - [Description("User can register account in game")] - public static readonly string canregister; - - [Description("User can login in game")] - public static readonly string canlogin; - - [Description("User can change password in game")] - public static readonly string canchangepassword; - - [Description("User can use party chat in game")] - public static readonly string canpartychat; - - [Description("User can talk in third person")] - public static readonly string cantalkinthird; + [Description("User can mute and unmute users")] public static readonly string mute; - [Description("Bypass Server Side Inventory checks")] - public static readonly string bypassinventorychecks; + [Description("User can register account in game")] public static readonly string canregister; - [Description("Allow unrestricted Send Tile Square usage, for client side world editing")] - public static readonly string allowclientsideworldedit; - + [Description("User can login in game")] public static readonly string canlogin; - static Permissions() - { - foreach (var field in typeof(Permissions).GetFields()) - { - field.SetValue(null, field.Name); - } - } + [Description("User can change password in game")] public static readonly string canchangepassword; - static List GetCommands(string perm) - { - if (Commands.ChatCommands.Count < 1) - Commands.InitCommands(); - return Commands.ChatCommands.Where(c => c.Permission == perm).ToList(); - } + [Description("User can use party chat in game")] public static readonly string canpartychat; - static void DumpDescriptions() - { - var sb = new StringBuilder(); - foreach (var field in typeof(Permissions).GetFields()) - { - var name = field.Name; + [Description("User can talk in third person")] public static readonly string cantalkinthird; - var descattr = field.GetCustomAttributes(false).FirstOrDefault(o => o is DescriptionAttribute) as DescriptionAttribute; - var desc = descattr != null && !string.IsNullOrWhiteSpace(descattr.Description) ? descattr.Description : "None"; + [Description("Bypass Server Side Inventory checks")] public static readonly string bypassinventorychecks; - var commands = GetCommands(name); - foreach (var c in commands) - { - for (var i = 0; i < c.Names.Count; i++) - { - c.Names[i] = "/" + c.Names[i]; - } - } - var strs = commands.Select(c => c.Name + (c.Names.Count > 1 ? "({0})".SFormat(string.Join(" ", c.Names.ToArray(), 1, c.Names.Count - 1)) : "")); + [Description("Allow unrestricted Send Tile Square usage, for client side world editing")] public static readonly + string allowclientsideworldedit; - sb.AppendLine("## {0} ".SFormat(name)); - sb.AppendLine("**Description:** {0} ".SFormat(desc)); - sb.AppendLine("**Commands:** {0} ".SFormat(strs.Count() > 0 ? string.Join(" ", strs) : "None")); - sb.AppendLine(); - } - File.WriteAllText("PermissionsDescriptions.txt", sb.ToString()); - } - } + static Permissions() + { + foreach (var field in typeof (Permissions).GetFields()) + { + field.SetValue(null, field.Name); + } + } - [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] - public sealed class TodoAttribute : Attribute - { - public string Info { get; private set; } + private static List GetCommands(string perm) + { + if (Commands.ChatCommands.Count < 1) + Commands.InitCommands(); + return Commands.ChatCommands.Where(c => c.Permission == perm).ToList(); + } - public TodoAttribute(string info) - { - Info = info; + private static void DumpDescriptions() + { + var sb = new StringBuilder(); + foreach (var field in typeof (Permissions).GetFields()) + { + var name = field.Name; - } - public TodoAttribute() - { - } + var descattr = + field.GetCustomAttributes(false).FirstOrDefault(o => o is DescriptionAttribute) as DescriptionAttribute; + var desc = descattr != null && !string.IsNullOrWhiteSpace(descattr.Description) ? descattr.Description : "None"; - } + var commands = GetCommands(name); + foreach (var c in commands) + { + for (var i = 0; i < c.Names.Count; i++) + { + c.Names[i] = "/" + c.Names[i]; + } + } + var strs = + commands.Select( + c => + c.Name + (c.Names.Count > 1 ? "({0})".SFormat(string.Join(" ", c.Names.ToArray(), 1, c.Names.Count - 1)) : "")); -} + sb.AppendLine("## {0} ".SFormat(name)); + sb.AppendLine("**Description:** {0} ".SFormat(desc)); + sb.AppendLine("**Commands:** {0} ".SFormat(strs.Count() > 0 ? string.Join(" ", strs) : "None")); + sb.AppendLine(); + } + + File.WriteAllText("PermissionsDescriptions.txt", sb.ToString()); + } + } + + [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class TodoAttribute : Attribute + { + public string Info { get; private set; } + + public TodoAttribute(string info) + { + Info = info; + } + + public TodoAttribute() + { + } + } +} \ No newline at end of file diff --git a/TShockAPI/RconHandler.cs b/TShockAPI/RconHandler.cs index 74902216..ceaa27b0 100644 --- a/TShockAPI/RconHandler.cs +++ b/TShockAPI/RconHandler.cs @@ -28,420 +28,429 @@ using Terraria; namespace TShockAPI { - class RconHandler - { - public static string Password = ""; - private static DateTime LastRequest; - private static DateTime LastHeartbeat; - public static int ListenPort; - public static bool ContinueServer = true; - public static string Response = ""; - private static bool Started; - private static UdpClient listener; - private static Thread startThread; - private static Thread heartbeat; - private static Thread listen; + internal class RconHandler + { + public static string Password = ""; + private static DateTime LastRequest; + private static DateTime LastHeartbeat; + public static int ListenPort; + public static bool ContinueServer = true; + public static string Response = ""; + private static bool Started; + private static UdpClient listener; + private static Thread startThread; + private static Thread heartbeat; + private static Thread listen; - public static void ShutdownAllThreads() - { - if (Started) - { - startThread.Abort(); - heartbeat.Abort(); - listen.Abort(); - Started = false; - } - } + public static void ShutdownAllThreads() + { + if (Started) + { + startThread.Abort(); + heartbeat.Abort(); + listen.Abort(); + Started = false; + } + } - public static void StartThread() - { - if (!Started) - { - startThread = new Thread(Start); - startThread.Start(); + public static void StartThread() + { + if (!Started) + { + startThread = new Thread(Start); + startThread.Start(); - heartbeat = new Thread(SendHeartbeat); - heartbeat.Start(); - } - Started = true; - } + heartbeat = new Thread(SendHeartbeat); + heartbeat.Start(); + } + Started = true; + } - public static void Start() - { - Log.Info("Starting RconHandler."); - try - { - Console.WriteLine(string.Format("RconHandler is running at UDP port {0} and password is {1}", - ListenPort, - Password)); - listen = new Thread(Listener); - listen.Start(); - while (true) - { - if (listen.ThreadState != ThreadState.Running) - { - listen.Abort(); - while (listen.ThreadState != ThreadState.Stopped) - continue; - listen.Start(); - } - Thread.Sleep(3000); - } - } - catch (Exception e) - { - Log.Error(e.ToString()); - } - } + public static void Start() + { + Log.Info("Starting RconHandler."); + try + { + Console.WriteLine(string.Format("RconHandler is running at UDP port {0} and password is {1}", + ListenPort, + Password)); + listen = new Thread(Listener); + listen.Start(); + while (true) + { + if (listen.ThreadState != ThreadState.Running) + { + listen.Abort(); + while (listen.ThreadState != ThreadState.Stopped) + continue; + listen.Start(); + } + Thread.Sleep(3000); + } + } + catch (Exception e) + { + Log.Error(e.ToString()); + } + } - private static void Listener() - { - if (listener == null) - try - { - listener = new UdpClient(ListenPort); - } - catch (SocketException e) - { - if (e.SocketErrorCode == SocketError.AddressAlreadyInUse) - Log.ConsoleError("Could not bind to " + ListenPort + ". Are you sure you don't have another instance running?"); - } - catch (Exception e) - { - Log.Error(e.ToString()); - } - while (ContinueServer) - { - try - { - var listenEP = new IPEndPoint(IPAddress.Any, ListenPort); - LastRequest = DateTime.Now; - byte[] bytes = listener.Receive(ref listenEP); - var packet = ParsePacket(bytes, listenEP); - listener.Send(packet, packet.Length, listenEP); - } - catch (Exception e) - { - Log.Error(e.ToString()); - } - } + private static void Listener() + { + if (listener == null) + try + { + listener = new UdpClient(ListenPort); + } + catch (SocketException e) + { + if (e.SocketErrorCode == SocketError.AddressAlreadyInUse) + Log.ConsoleError("Could not bind to " + ListenPort + ". Are you sure you don't have another instance running?"); + } + catch (Exception e) + { + Log.Error(e.ToString()); + } + while (ContinueServer) + { + try + { + var listenEP = new IPEndPoint(IPAddress.Any, ListenPort); + LastRequest = DateTime.Now; + byte[] bytes = listener.Receive(ref listenEP); + var packet = ParsePacket(bytes, listenEP); + listener.Send(packet, packet.Length, listenEP); + } + catch (Exception e) + { + Log.Error(e.ToString()); + } + } + } - } + private static string SendPacket(byte[] bytes, string hostname, int port) + { + var response = Encoding.UTF8.GetString(new byte[] {0xFF, 0xFF, 0xFF, 0xFF}) + "disconnect"; + try + { + var EP = new IPEndPoint(IPAddress.Any, port); + using (var client = new UdpClient()) + { + client.Connect(hostname, port); + client.Client.ReceiveTimeout = 500; + client.Send(bytes, bytes.Length); + response = Encoding.UTF8.GetString(client.Receive(ref EP)); + } + } + catch (Exception e) + { + Log.Error(e.ToString()); + } + return response; + } - private static string SendPacket(byte[] bytes, string hostname, int port) - { - var response = Encoding.UTF8.GetString(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF }) + "disconnect"; - try - { - var EP = new IPEndPoint(IPAddress.Any, port); - using (var client = new UdpClient()) - { - client.Connect(hostname, port); - client.Client.ReceiveTimeout = 500; - client.Send(bytes, bytes.Length); - response = Encoding.UTF8.GetString(client.Receive(ref EP)); - } - } - catch (Exception e) - { - Log.Error(e.ToString()); - } - return response; - } + private static byte[] ParsePacket(byte[] bytes, IPEndPoint EP) + { + string response = ""; + var packetstring = Encoding.UTF8.GetString(PadPacket(bytes)); + var redirect = false; + var print = true; + if ((DateTime.Now - LastRequest).Milliseconds >= 100) + { + if (packetstring.StartsWith("rcon") || packetstring.Substring(4).StartsWith("rcon") || + packetstring.Substring(5).StartsWith("rcon")) + { + if (!string.IsNullOrEmpty(Password)) + { + var args = ParseParameters(packetstring); + if (args.Count >= 3) + { + if (args[1] == Password) + { + args[1] = args[0] = ""; + string command = string.Join(" ", args.ToArray()); + command = command.TrimEnd(' ').TrimEnd('\0').TrimStart(' '); + Log.ConsoleInfo("Rcon from " + EP + ":" + command); + Response = ""; + response = ExecuteCommand(command); + response += "\n" + Response; + Response = ""; + response = response.TrimStart('\n'); + } + else + { + response = "Bad rcon password.\n"; + Log.ConsoleInfo("Bad rcon password from " + EP); + } + } + else + response = ""; + } + else + { + response = "No rcon password set on the server.\n"; + Log.Info("No password for rcon set"); + } + } + else + redirect = true; + } + if (packetstring.StartsWith("getinfo") + || packetstring.Substring(4).StartsWith("getinfo") + || packetstring.Substring(5).StartsWith("getinfo")) + { + var challenge = ""; + if (packetstring.Split(' ').Length == 2) + challenge = packetstring.Split(' ')[1]; + response = "infoResponse\n"; + var infostring = + string.Format( + @"\_TShock_ver\{6}\mapname\{1}\sv_maxclients\{2}\clients\{3}\sv_privateClients\{4}\hconly\{5}\gamename\TERRARIA\protocol\100\sv_hostname\{0}\g_needPass\{7}", + TShock.Config.ServerName, Main.worldName, Main.maxNetPlayers, + TShock.Utils.ActivePlayers(), Main.maxNetPlayers - TShock.Config.MaxSlots, + TShock.Config.HardcoreOnly ? 1 : 0, TShock.VersionNum, + Netplay.password != "" ? 1 : 0); + if (challenge != "") + infostring += @"\challenge\" + challenge; + response += infostring; + print = false; + redirect = false; + } + else if (packetstring.StartsWith("getstatus") + || packetstring.Substring(4).StartsWith("getstatus") + || packetstring.Substring(5).StartsWith("getstatus")) + { + var challenge = ""; + if (packetstring.Split(' ').Length == 2) + challenge = packetstring.Split(' ')[1]; + response = "statusResponse\n"; + var statusstring = string.Format( + @"\_TShock_ver\{6}\mapname\{1}\sv_maxclients\{2}\clients\{3}\sv_privateClients\{4}\hconly\{5}\gamename\TERRARIA\protocol\100\sv_hostname\{0}\g_needPass\{7}", + TShock.Config.ServerName, Main.worldName, Main.maxNetPlayers, + TShock.Utils.ActivePlayers(), Main.maxNetPlayers - TShock.Config.MaxSlots, + TShock.Config.HardcoreOnly ? 1 : 0, TShock.VersionNum, + Netplay.password != "" ? 1 : 0) + "\n"; + if (challenge != "") + statusstring += @"\challenge\" + challenge; + foreach (TSPlayer player in TShock.Players) + { + if (player != null && player.Active) + statusstring += (string.Format("0 0 {0}\n", player.Name)); + } + response += statusstring; + print = false; + redirect = false; + } + if (!redirect) + return (ConstructPacket(response, print)); + else + return (ConstructPacket("disconnect", false)); + } - private static byte[] ParsePacket(byte[] bytes, IPEndPoint EP) - { - string response = ""; - var packetstring = Encoding.UTF8.GetString(PadPacket(bytes)); - var redirect = false; - var print = true; - if ((DateTime.Now - LastRequest).Milliseconds >= 100) - { - if (packetstring.StartsWith("rcon") || packetstring.Substring(4).StartsWith("rcon") || packetstring.Substring(5).StartsWith("rcon")) - { - if (!string.IsNullOrEmpty(Password)) - { - var args = ParseParameters(packetstring); - if (args.Count >= 3) - { - if (args[1] == Password) - { - args[1] = args[0] = ""; - string command = string.Join(" ", args.ToArray()); - command = command.TrimEnd(' ').TrimEnd('\0').TrimStart(' '); - Log.ConsoleInfo("Rcon from " + EP + ":" + command); - Response = ""; - response = ExecuteCommand(command); - response += "\n" + Response; - Response = ""; - response = response.TrimStart('\n'); - } - else - { - response = "Bad rcon password.\n"; - Log.ConsoleInfo("Bad rcon password from " + EP); - } - } - else - response = ""; - } - else - { - response = "No rcon password set on the server.\n"; - Log.Info("No password for rcon set"); - } - } - else - redirect = true; - } - if (packetstring.StartsWith("getinfo") - || packetstring.Substring(4).StartsWith("getinfo") - || packetstring.Substring(5).StartsWith("getinfo")) - { - var challenge = ""; - if (packetstring.Split(' ').Length == 2) - challenge = packetstring.Split(' ')[1]; - response = "infoResponse\n"; - var infostring = string.Format(@"\_TShock_ver\{6}\mapname\{1}\sv_maxclients\{2}\clients\{3}\sv_privateClients\{4}\hconly\{5}\gamename\TERRARIA\protocol\100\sv_hostname\{0}\g_needPass\{7}", - TShock.Config.ServerName, Main.worldName, Main.maxNetPlayers, - TShock.Utils.ActivePlayers(), Main.maxNetPlayers - TShock.Config.MaxSlots, - TShock.Config.HardcoreOnly ? 1 : 0, TShock.VersionNum, - Netplay.password != "" ? 1 : 0); - if (challenge != "") - infostring += @"\challenge\" + challenge; - response += infostring; - print = false; - redirect = false; - } - else if (packetstring.StartsWith("getstatus") - || packetstring.Substring(4).StartsWith("getstatus") - || packetstring.Substring(5).StartsWith("getstatus")) - { - var challenge = ""; - if (packetstring.Split(' ').Length == 2) - challenge = packetstring.Split(' ')[1]; - response = "statusResponse\n"; - var statusstring = string.Format(@"\_TShock_ver\{6}\mapname\{1}\sv_maxclients\{2}\clients\{3}\sv_privateClients\{4}\hconly\{5}\gamename\TERRARIA\protocol\100\sv_hostname\{0}\g_needPass\{7}", - TShock.Config.ServerName, Main.worldName, Main.maxNetPlayers, - TShock.Utils.ActivePlayers(), Main.maxNetPlayers - TShock.Config.MaxSlots, - TShock.Config.HardcoreOnly ? 1 : 0, TShock.VersionNum, - Netplay.password != "" ? 1 : 0) + "\n"; - if (challenge != "") - statusstring += @"\challenge\" + challenge; - foreach (TSPlayer player in TShock.Players) - { - if (player != null && player.Active) - statusstring += (string.Format("0 0 {0}\n", player.Name)); - } - response += statusstring; - print = false; - redirect = false; - } - if (!redirect) - return (ConstructPacket(response, print)); - else - return (ConstructPacket("disconnect", false)); - } + private static string ExecuteCommand(string text) + { + if (Main.rand == null) + Main.rand = new Random(); + if (WorldGen.genRand == null) + WorldGen.genRand = new Random(); + if (text.StartsWith("exit")) + { + TShock.Utils.ForceKickAll("Server shutting down!"); + WorldGen.saveWorld(false); + Netplay.disconnect = true; + return "Server shutting down."; + } + else if (text.StartsWith("playing") || text.StartsWith("/playing")) + { + int count = 0; + foreach (TSPlayer player in TShock.Players) + { + if (player != null && player.Active) + { + count++; + TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}] <{3}>", player.Name, player.IP, player.Group.Name, + player.UserAccountName)); + } + } + TSPlayer.Server.SendMessage(string.Format("{0} players connected.", count)); + } + else if (text.StartsWith("status")) + { + Response += "map: " + Main.worldName + "\n"; + Response += "num score ping name lastmsg address qport rate\n"; + int count = 0; + foreach (TSPlayer player in TShock.Players) + { + if (player != null && player.Active) + { + count++; + Response += + (string.Format("{0} 0 0 {1}({2}) {3} {4} 0 0", count, player.Name, player.Group.Name, + Netplay.serverSock[player.Index].tcpClient.Client.RemoteEndPoint, "")) + "\n"; + } + } + } + else if (text.StartsWith("say ")) + { + Log.Info(string.Format("Server said: {0}", text.Remove(0, 4))); + return string.Format("Server said: {0}", text.Remove(0, 4)); + } + else if (text == "autosave") + { + Main.autoSave = TShock.Config.AutoSave = !TShock.Config.AutoSave; + Log.ConsoleInfo("AutoSave " + (TShock.Config.AutoSave ? "Enabled" : "Disabled")); + return "AutoSave " + (TShock.Config.AutoSave ? "Enabled" : "Disabled"); + } + else if (text.StartsWith("/")) + { + if (!Commands.HandleCommand(TSPlayer.Server, text)) + return "Invalid command."; + } + else if (!Commands.HandleCommand(TSPlayer.Server, "/" + text)) + return "Invalid command."; + return ""; + } - private static string ExecuteCommand(string text) - { - if (Main.rand == null) - Main.rand = new Random(); - if (WorldGen.genRand == null) - WorldGen.genRand = new Random(); - if (text.StartsWith("exit")) - { - TShock.Utils.ForceKickAll("Server shutting down!"); - WorldGen.saveWorld(false); - Netplay.disconnect = true; - return "Server shutting down."; - } - else if (text.StartsWith("playing") || text.StartsWith("/playing")) - { - int count = 0; - foreach (TSPlayer player in TShock.Players) - { - if (player != null && player.Active) - { - count++; - TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}] <{3}>", player.Name, player.IP, player.Group.Name, player.UserAccountName)); - } - } - TSPlayer.Server.SendMessage(string.Format("{0} players connected.", count)); - } - else if (text.StartsWith("status")) - { - Response += "map: " + Main.worldName + "\n"; - Response += "num score ping name lastmsg address qport rate\n"; - int count = 0; - foreach (TSPlayer player in TShock.Players) - { - if (player != null && player.Active) - { - count++; - Response += (string.Format("{0} 0 0 {1}({2}) {3} {4} 0 0", count, player.Name, player.Group.Name, Netplay.serverSock[player.Index].tcpClient.Client.RemoteEndPoint, "")) + "\n"; - } - } - } - else if (text.StartsWith("say ")) - { - Log.Info(string.Format("Server said: {0}", text.Remove(0, 4))); - return string.Format("Server said: {0}", text.Remove(0, 4)); - } - else if (text == "autosave") - { - Main.autoSave = TShock.Config.AutoSave = !TShock.Config.AutoSave; - Log.ConsoleInfo("AutoSave " + (TShock.Config.AutoSave ? "Enabled" : "Disabled")); - return "AutoSave " + (TShock.Config.AutoSave ? "Enabled" : "Disabled"); - } - else if (text.StartsWith("/")) - { - if (!Commands.HandleCommand(TSPlayer.Server, text)) - return "Invalid command."; - } - else - if (!Commands.HandleCommand(TSPlayer.Server, "/" + text)) - return "Invalid command."; - return ""; - } + private static byte[] ConstructPacket(string response, bool print) + { + var oob = new byte[] {0xFF, 0xFF, 0xFF, 0xFF}; + using (var stream = new MemoryStream()) + { + stream.WriteBytes(oob); + if (print) + stream.WriteBytes(Encoding.UTF8.GetBytes(string.Format("print\n{0}", response))); + else + stream.WriteBytes(Encoding.UTF8.GetBytes(response)); + var trimmedpacket = new byte[(int) stream.Length]; + var packet = stream.GetBuffer(); + Array.Copy(packet, trimmedpacket, (int) stream.Length); + return trimmedpacket; + } + } - private static byte[] ConstructPacket(string response, bool print) - { - var oob = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF }; - using (var stream = new MemoryStream()) - { - stream.WriteBytes(oob); - if (print) - stream.WriteBytes(Encoding.UTF8.GetBytes(string.Format("print\n{0}", response))); - else - stream.WriteBytes(Encoding.UTF8.GetBytes(response)); - var trimmedpacket = new byte[(int)stream.Length]; - var packet = stream.GetBuffer(); - Array.Copy(packet, trimmedpacket, (int)stream.Length); - return trimmedpacket; - } - } + private static byte[] PadPacket(byte[] packet) + { + var returnpacket = new byte[(4 + packet.Length)]; + int h = 0; + if (packet[0] != 0xFF) + { + for (int i = 0; i < 4; i++) + returnpacket[i] = 0xFF; + for (int i = 4; i < returnpacket.Length; i++) + returnpacket[i] = packet[h++]; + } + else + returnpacket = packet; + return returnpacket; + } - private static byte[] PadPacket(byte[] packet) - { - var returnpacket = new byte[(4 + packet.Length)]; - int h = 0; - if (packet[0] != 0xFF) - { - for (int i = 0; i < 4; i++) - returnpacket[i] = 0xFF; - for (int i = 4; i < returnpacket.Length; i++) - returnpacket[i] = packet[h++]; - } - else - returnpacket = packet; - return returnpacket; - } + private static void SendHeartbeat() + { + LastHeartbeat = DateTime.UtcNow.Subtract(new TimeSpan(0, 0, 30)); + while (true) + { + if ((DateTime.UtcNow - LastHeartbeat).Seconds >= 30) + { + var packet = ConstructPacket("heartbeat TerrariaShock", false); + if (listener == null) + try + { + listener = new UdpClient(ListenPort); + } + catch (SocketException e) + { + if (e.SocketErrorCode == SocketError.AddressAlreadyInUse) + Log.ConsoleError("Could not bind to " + ListenPort + ". Are you sure you don't have another instance running?"); + } + catch (Exception e) + { + Log.Error(e.ToString()); + } + listener.Send(packet, packet.Length, TShock.Config.MasterServer, 27950); + LastHeartbeat = DateTime.UtcNow; + } + Thread.Sleep(10000); + } + } - private static void SendHeartbeat() - { - LastHeartbeat = DateTime.UtcNow.Subtract(new TimeSpan(0, 0, 30)); - while (true) - { - if ((DateTime.UtcNow - LastHeartbeat).Seconds >= 30) - { - var packet = ConstructPacket("heartbeat TerrariaShock", false); - if (listener == null) - try - { - listener = new UdpClient(ListenPort); - } - catch (SocketException e) - { - if (e.SocketErrorCode == SocketError.AddressAlreadyInUse) - Log.ConsoleError("Could not bind to " + ListenPort + ". Are you sure you don't have another instance running?"); - } - catch (Exception e) - { - Log.Error(e.ToString()); - } - listener.Send(packet, packet.Length, TShock.Config.MasterServer, 27950); - LastHeartbeat = DateTime.UtcNow; - } - Thread.Sleep(10000); - } - } + #region ParseParams - #region ParseParams - 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]; + 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()); + 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'; - } - #endregion - } -} + 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'; + } + + #endregion + } +} \ No newline at end of file diff --git a/TShockAPI/Rest/Rest.cs b/TShockAPI/Rest/Rest.cs index 4c9c9e9f..31043f8e 100644 --- a/TShockAPI/Rest/Rest.cs +++ b/TShockAPI/Rest/Rest.cs @@ -10,132 +10,142 @@ using HttpListener = HttpServer.HttpListener; namespace Rests { - /// - /// Rest command delegate - /// - /// Parameters in the url - /// {x} in urltemplate - /// Response object or null to not handle request - public delegate object RestCommandD(RestVerbs verbs, IParameterCollection parameters); - public class Rest : IDisposable - { - readonly List commands = new List(); - HttpListener listener; - public IPAddress Ip { get; set; } - public int Port { get; set; } + /// + /// Rest command delegate + /// + /// Parameters in the url + /// {x} in urltemplate + /// Response object or null to not handle request + public delegate object RestCommandD(RestVerbs verbs, IParameterCollection parameters); - public Rest(IPAddress ip, int port) - { - Ip = ip; - Port = port; - } - public virtual void Start() - { - if (listener == null) - { - listener = HttpListener.Create(Ip, Port); - listener.RequestReceived += OnRequest; - listener.Start(int.MaxValue); - } - } - public void Start(IPAddress ip, int port) - { - Ip = ip; - Port = port; - Start(); - } - public virtual void Stop() - { - listener.Stop(); - } + public class Rest : IDisposable + { + private readonly List commands = new List(); + private HttpListener listener; + public IPAddress Ip { get; set; } + public int Port { get; set; } - public void Register(string path, RestCommandD callback) - { - AddCommand(new RestCommand(path, callback)); - } + public Rest(IPAddress ip, int port) + { + Ip = ip; + Port = port; + } - public void Register(RestCommand com) - { - AddCommand(com); - } + public virtual void Start() + { + if (listener == null) + { + listener = HttpListener.Create(Ip, Port); + listener.RequestReceived += OnRequest; + listener.Start(int.MaxValue); + } + } - protected void AddCommand(RestCommand com) - { - commands.Add(com); - } + public void Start(IPAddress ip, int port) + { + Ip = ip; + Port = port; + Start(); + } - protected virtual void OnRequest(object sender, RequestEventArgs e) - { - var obj = ProcessRequest(sender, e); - if (obj == null) - throw new NullReferenceException("obj"); + public virtual void Stop() + { + listener.Stop(); + } - var str = JsonConvert.SerializeObject(obj, Formatting.Indented); - e.Response.Connection.Type = ConnectionType.Close; - e.Response.Body.Write(Encoding.ASCII.GetBytes(str), 0, str.Length); - e.Response.Status = HttpStatusCode.OK; - return; - } + public void Register(string path, RestCommandD callback) + { + AddCommand(new RestCommand(path, callback)); + } - protected virtual object ProcessRequest(object sender, RequestEventArgs e) - { - var uri = e.Request.Uri.AbsolutePath; - uri = uri.TrimEnd('/'); + public void Register(RestCommand com) + { + AddCommand(com); + } - foreach (var com in commands) - { - var verbs = new RestVerbs(); - if (com.HasVerbs) - { - var match = Regex.Match(uri, com.UriVerbMatch); - if (!match.Success) - continue; - if ((match.Groups.Count - 1) != com.UriVerbs.Length) - continue; + protected void AddCommand(RestCommand com) + { + commands.Add(com); + } - for (int i = 0; i < com.UriVerbs.Length; i++) - verbs.Add(com.UriVerbs[i], match.Groups[i + 1].Value); - } - else if (com.UriTemplate.ToLower() != uri.ToLower()) - { - continue; - } + protected virtual void OnRequest(object sender, RequestEventArgs e) + { + var obj = ProcessRequest(sender, e); + if (obj == null) + throw new NullReferenceException("obj"); - var obj = ExecuteCommand(com, verbs, e.Request.Parameters); - if (obj != null) - return obj; + var str = JsonConvert.SerializeObject(obj, Formatting.Indented); + e.Response.Connection.Type = ConnectionType.Close; + e.Response.Body.Write(Encoding.ASCII.GetBytes(str), 0, str.Length); + e.Response.Status = HttpStatusCode.OK; + return; + } - } - return new Dictionary { { "status", "404" }, { "error", "Specified API endpoint doesn't exist. Refer to the documentation for a list of valid endpoints." } }; - } + protected virtual object ProcessRequest(object sender, RequestEventArgs e) + { + var uri = e.Request.Uri.AbsolutePath; + uri = uri.TrimEnd('/'); - protected virtual object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms) - { - return cmd.Callback(verbs, parms); - } + foreach (var com in commands) + { + var verbs = new RestVerbs(); + if (com.HasVerbs) + { + var match = Regex.Match(uri, com.UriVerbMatch); + if (!match.Success) + continue; + if ((match.Groups.Count - 1) != com.UriVerbs.Length) + continue; - #region Dispose - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (listener != null) - { - listener.Stop(); - listener = null; - } - } - } - ~Rest() - { - Dispose(false); - } + for (int i = 0; i < com.UriVerbs.Length; i++) + verbs.Add(com.UriVerbs[i], match.Groups[i + 1].Value); + } + else if (com.UriTemplate.ToLower() != uri.ToLower()) + { + continue; + } - #endregion - } -} + var obj = ExecuteCommand(com, verbs, e.Request.Parameters); + if (obj != null) + return obj; + } + return new Dictionary + { + {"status", "404"}, + {"error", "Specified API endpoint doesn't exist. Refer to the documentation for a list of valid endpoints."} + }; + } + + protected virtual object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms) + { + return cmd.Callback(verbs, parms); + } + + #region Dispose + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (listener != null) + { + listener.Stop(); + listener = null; + } + } + } + + ~Rest() + { + Dispose(false); + } + + #endregion + } +} \ No newline at end of file diff --git a/TShockAPI/Rest/RestCommand.cs b/TShockAPI/Rest/RestCommand.cs index 5409282f..f720c50d 100644 --- a/TShockAPI/Rest/RestCommand.cs +++ b/TShockAPI/Rest/RestCommand.cs @@ -3,45 +3,45 @@ using System.Text.RegularExpressions; namespace Rests { - public class RestCommand - { - public string Name { get; protected set; } - public string UriTemplate { get; protected set; } - public string UriVerbMatch { get; protected set; } - public string[] UriVerbs { get; protected set; } - public RestCommandD Callback { get; protected set; } - public bool RequiresToken { get; set; } + public class RestCommand + { + public string Name { get; protected set; } + public string UriTemplate { get; protected set; } + public string UriVerbMatch { get; protected set; } + public string[] UriVerbs { get; protected set; } + public RestCommandD Callback { get; protected set; } + public bool RequiresToken { get; set; } - /// - /// - /// - /// Used for identification - /// Url template - /// Rest Command callback - public RestCommand(string name, string uritemplate, RestCommandD callback) - { - Name = name; - UriTemplate = uritemplate; - UriVerbMatch = string.Format("^{0}$", string.Join("([^/]*)", Regex.Split(uritemplate, "\\{[^\\{\\}]*\\}"))); - var matches = Regex.Matches(uritemplate, "\\{([^\\{\\}]*)\\}"); - UriVerbs = (from Match match in matches select match.Groups[1].Value).ToArray(); - Callback = callback; - RequiresToken = true; - } - /// - /// - /// - /// Url template - /// Rest Command callback - public RestCommand(string uritemplate, RestCommandD callback) - : this(string.Empty, uritemplate, callback) - { + /// + /// + /// + /// Used for identification + /// Url template + /// Rest Command callback + public RestCommand(string name, string uritemplate, RestCommandD callback) + { + Name = name; + UriTemplate = uritemplate; + UriVerbMatch = string.Format("^{0}$", string.Join("([^/]*)", Regex.Split(uritemplate, "\\{[^\\{\\}]*\\}"))); + var matches = Regex.Matches(uritemplate, "\\{([^\\{\\}]*)\\}"); + UriVerbs = (from Match match in matches select match.Groups[1].Value).ToArray(); + Callback = callback; + RequiresToken = true; + } - } + /// + /// + /// + /// Url template + /// Rest Command callback + public RestCommand(string uritemplate, RestCommandD callback) + : this(string.Empty, uritemplate, callback) + { + } - public bool HasVerbs - { - get { return UriVerbs.Length > 0; } - } - } + public bool HasVerbs + { + get { return UriVerbs.Length > 0; } + } + } } \ No newline at end of file diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index 86a866c9..10fe0ad0 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -8,441 +8,451 @@ using TShockAPI.DB; namespace TShockAPI { + public class RestManager + { + private Rest Rest; - public class RestManager - { - private Rest Rest; - public RestManager(Rest rest) - { - Rest = rest; - } + public RestManager(Rest rest) + { + Rest = rest; + } - public void RegisterRestfulCommands() - { - Rest.Register(new RestCommand("/status", Status) { RequiresToken = false }); - Rest.Register(new RestCommand("/tokentest", TokenTest) { RequiresToken = true }); + public void RegisterRestfulCommands() + { + Rest.Register(new RestCommand("/status", Status) {RequiresToken = false}); + Rest.Register(new RestCommand("/tokentest", TokenTest) {RequiresToken = true}); - Rest.Register(new RestCommand("/users/read/{user}/info", UserInfo) { RequiresToken = true }); - Rest.Register(new RestCommand("/users/destroy/{user}", UserDestroy) { RequiresToken = true }); - Rest.Register(new RestCommand("/users/update/{user}", UserUpdate) { RequiresToken = true }); + Rest.Register(new RestCommand("/users/read/{user}/info", UserInfo) {RequiresToken = true}); + Rest.Register(new RestCommand("/users/destroy/{user}", UserDestroy) {RequiresToken = true}); + Rest.Register(new RestCommand("/users/update/{user}", UserUpdate) {RequiresToken = true}); - Rest.Register(new RestCommand("/bans/create", BanCreate) { RequiresToken = true }); - Rest.Register(new RestCommand("/bans/read/{user}/info", BanInfo) { RequiresToken = true }); - Rest.Register(new RestCommand("/bans/destroy/{user}", BanDestroy) { RequiresToken = true }); + Rest.Register(new RestCommand("/bans/create", BanCreate) {RequiresToken = true}); + Rest.Register(new RestCommand("/bans/read/{user}/info", BanInfo) {RequiresToken = true}); + Rest.Register(new RestCommand("/bans/destroy/{user}", BanDestroy) {RequiresToken = true}); - Rest.Register(new RestCommand("/lists/players", UserList) { RequiresToken = true }); + Rest.Register(new RestCommand("/lists/players", UserList) {RequiresToken = true}); - Rest.Register(new RestCommand("/world/read", WorldRead) { RequiresToken = true }); - Rest.Register(new RestCommand("/world/meteor", WorldMeteor) { RequiresToken = true }); - Rest.Register(new RestCommand("/world/bloodmoon/{bool}", WorldBloodmoon) { RequiresToken = true }); + Rest.Register(new RestCommand("/world/read", WorldRead) {RequiresToken = true}); + Rest.Register(new RestCommand("/world/meteor", WorldMeteor) {RequiresToken = true}); + Rest.Register(new RestCommand("/world/bloodmoon/{bool}", WorldBloodmoon) {RequiresToken = true}); - Rest.Register(new RestCommand("/players/read/{player}", PlayerRead) { RequiresToken = true }); - Rest.Register(new RestCommand("/players/{player}/kick", PlayerKick) { RequiresToken = true }); - Rest.Register(new RestCommand("/players/{player}/ban", PlayerBan) { RequiresToken = true }); - //RegisterExamples(); - } + Rest.Register(new RestCommand("/players/read/{player}", PlayerRead) {RequiresToken = true}); + Rest.Register(new RestCommand("/players/{player}/kick", PlayerKick) {RequiresToken = true}); + Rest.Register(new RestCommand("/players/{player}/ban", PlayerBan) {RequiresToken = true}); + //RegisterExamples(); + } - #region RestMethods + #region RestMethods - object TokenTest(RestVerbs verbs, IParameterCollection parameters) - { - return new Dictionary { { "status", "200" }, { "response", "Token is valid and was passed through correctly." } }; - } + private object TokenTest(RestVerbs verbs, IParameterCollection parameters) + { + return new Dictionary + {{"status", "200"}, {"response", "Token is valid and was passed through correctly."}}; + } - object Status(RestVerbs verbs, IParameterCollection parameters) - { - if (TShock.Config.EnableTokenEndpointAuthentication) - return new RestObject("403") { Error = "Server settings require a token for this API call." }; + private object Status(RestVerbs verbs, IParameterCollection parameters) + { + if (TShock.Config.EnableTokenEndpointAuthentication) + return new RestObject("403") {Error = "Server settings require a token for this API call."}; - var activeplayers = Main.player.Where(p => p != null && p.active).ToList(); - string currentPlayers = string.Join(", ", activeplayers.Select(p => p.name)); + var activeplayers = Main.player.Where(p => p != null && p.active).ToList(); + string currentPlayers = string.Join(", ", activeplayers.Select(p => p.name)); - var ret = new RestObject("200"); - ret["name"] = TShock.Config.ServerNickname; - ret["port"] = Convert.ToString(TShock.Config.ServerPort); - ret["playercount"] = Convert.ToString(activeplayers.Count()); - ret["players"] = currentPlayers; + var ret = new RestObject("200"); + ret["name"] = TShock.Config.ServerNickname; + ret["port"] = Convert.ToString(TShock.Config.ServerPort); + ret["playercount"] = Convert.ToString(activeplayers.Count()); + ret["players"] = currentPlayers; - return ret; - } + return ret; + } - #endregion + #endregion - #region RestUserMethods + #region RestUserMethods - object UserList(RestVerbs verbs, IParameterCollection parameters) - { - var activeplayers = Main.player.Where(p => p != null && p.active).ToList(); - string currentPlayers = string.Join(", ", activeplayers.Select(p => p.name)); - var ret = new RestObject("200"); - ret["players"] = currentPlayers; - return ret; - } + private object UserList(RestVerbs verbs, IParameterCollection parameters) + { + var activeplayers = Main.player.Where(p => p != null && p.active).ToList(); + string currentPlayers = string.Join(", ", activeplayers.Select(p => p.name)); + var ret = new RestObject("200"); + ret["players"] = currentPlayers; + return ret; + } - object UserUpdate(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - var password = parameters["password"]; - var group = parameters["group"]; + private object UserUpdate(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var password = parameters["password"]; + var group = parameters["group"]; - if (group == null && password == null) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "No parameters were passed."); - return returnBlock; - } + if (group == null && password == null) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "No parameters were passed."); + return returnBlock; + } - var user = TShock.Users.GetUserByName(verbs["user"]); - if (user == null) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "The specefied user doesn't exist."); - return returnBlock; - } + var user = TShock.Users.GetUserByName(verbs["user"]); + if (user == null) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "The specefied user doesn't exist."); + return returnBlock; + } - if (password != null) - { - TShock.Users.SetUserPassword(user, password); - returnBlock.Add("password-response", "Password updated successfully."); - } + if (password != null) + { + TShock.Users.SetUserPassword(user, password); + returnBlock.Add("password-response", "Password updated successfully."); + } - if (group != null) - { - TShock.Users.SetUserGroup(user, group); - returnBlock.Add("group-response", "Group updated successfully."); - } + if (group != null) + { + TShock.Users.SetUserGroup(user, group); + returnBlock.Add("group-response", "Group updated successfully."); + } - returnBlock.Add("status", "200"); - return returnBlock; - } + returnBlock.Add("status", "200"); + return returnBlock; + } - object UserDestroy(RestVerbs verbs, IParameterCollection parameters) - { - var user = TShock.Users.GetUserByName(verbs["user"]); - if (user == null) - { - return new Dictionary { { "status", "400" }, { "error", "The specified user account does not exist." } }; - } - var returnBlock = new Dictionary(); - try - { - TShock.Users.RemoveUser(user); - } - catch (Exception) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "The specified user was unable to be removed."); - return returnBlock; - } - returnBlock.Add("status", "200"); - returnBlock.Add("response", "User deleted successfully."); - return returnBlock; - } + private object UserDestroy(RestVerbs verbs, IParameterCollection parameters) + { + var user = TShock.Users.GetUserByName(verbs["user"]); + if (user == null) + { + return new Dictionary {{"status", "400"}, {"error", "The specified user account does not exist."}}; + } + var returnBlock = new Dictionary(); + try + { + TShock.Users.RemoveUser(user); + } + catch (Exception) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "The specified user was unable to be removed."); + return returnBlock; + } + returnBlock.Add("status", "200"); + returnBlock.Add("response", "User deleted successfully."); + return returnBlock; + } - object UserInfo(RestVerbs verbs, IParameterCollection parameters) - { - var user = TShock.Users.GetUserByName(verbs["user"]); - if (user == null) - { - return new Dictionary { { "status", "400" }, { "error", "The specified user account does not exist." } }; - } + private object UserInfo(RestVerbs verbs, IParameterCollection parameters) + { + var user = TShock.Users.GetUserByName(verbs["user"]); + if (user == null) + { + return new Dictionary {{"status", "400"}, {"error", "The specified user account does not exist."}}; + } - var returnBlock = new Dictionary(); - returnBlock.Add("status", "200"); - returnBlock.Add("group", user.Group); - returnBlock.Add("id", user.ID.ToString()); - return returnBlock; - } + var returnBlock = new Dictionary(); + returnBlock.Add("status", "200"); + returnBlock.Add("group", user.Group); + returnBlock.Add("id", user.ID.ToString()); + return returnBlock; + } - #endregion + #endregion - #region RestBanMethods + #region RestBanMethods - object BanCreate(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - var ip = parameters["ip"]; - var name = parameters["name"]; - var reason = parameters["reason"]; + private object BanCreate(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var ip = parameters["ip"]; + var name = parameters["name"]; + var reason = parameters["reason"]; - if (ip == null && name == null) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Required parameters were missing from this API endpoint."); - return returnBlock; - } + if (ip == null && name == null) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Required parameters were missing from this API endpoint."); + return returnBlock; + } - if (ip == null) - { - ip = ""; - } + if (ip == null) + { + ip = ""; + } - if (name == null) - { - name = ""; - } + if (name == null) + { + name = ""; + } - if (reason == null) - { - reason = ""; - } + if (reason == null) + { + reason = ""; + } - try - { - TShock.Bans.AddBan(ip, name, reason); - } - catch (Exception) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "The specified ban was unable to be created."); - return returnBlock; - } - returnBlock.Add("status", "200"); - returnBlock.Add("response", "Ban created successfully."); - return returnBlock; - } + try + { + TShock.Bans.AddBan(ip, name, reason); + } + catch (Exception) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "The specified ban was unable to be created."); + return returnBlock; + } + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Ban created successfully."); + return returnBlock; + } - object BanDestroy(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); + private object BanDestroy(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); - var type = parameters["type"]; - if (type == null) - { - returnBlock.Add("Error", "Invalid Type"); - return returnBlock; - } + var type = parameters["type"]; + if (type == null) + { + returnBlock.Add("Error", "Invalid Type"); + return returnBlock; + } - var ban = new Ban(); - if (type == "ip") ban = TShock.Bans.GetBanByIp(verbs["user"]); - else if (type == "name") ban = TShock.Bans.GetBanByName(verbs["user"]); - else - { - returnBlock.Add("Error", "Invalid Type"); - return returnBlock; - } + var ban = new Ban(); + if (type == "ip") ban = TShock.Bans.GetBanByIp(verbs["user"]); + else if (type == "name") ban = TShock.Bans.GetBanByName(verbs["user"]); + else + { + returnBlock.Add("Error", "Invalid Type"); + return returnBlock; + } - if (ban == null) - { - return new Dictionary { { "status", "400" }, { "error", "The specified ban does not exist." } }; - } + if (ban == null) + { + return new Dictionary {{"status", "400"}, {"error", "The specified ban does not exist."}}; + } - try - { - TShock.Bans.RemoveBan(ban.IP); - } - catch (Exception) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "The specified ban was unable to be removed."); - return returnBlock; - } - returnBlock.Add("status", "200"); - returnBlock.Add("response", "Ban deleted successfully."); - return returnBlock; - } + try + { + TShock.Bans.RemoveBan(ban.IP); + } + catch (Exception) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "The specified ban was unable to be removed."); + return returnBlock; + } + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Ban deleted successfully."); + return returnBlock; + } - object BanInfo(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); + private object BanInfo(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); - var type = parameters["type"]; - if (type == null) - { - returnBlock.Add("Error", "Invalid Type"); - return returnBlock; - } + var type = parameters["type"]; + if (type == null) + { + returnBlock.Add("Error", "Invalid Type"); + return returnBlock; + } - var ban = new Ban(); - if (type == "ip") ban = TShock.Bans.GetBanByIp(verbs["user"]); - else if (type == "name") ban = TShock.Bans.GetBanByName(verbs["user"]); - else - { - returnBlock.Add("Error", "Invalid Type"); - return returnBlock; - } + var ban = new Ban(); + if (type == "ip") ban = TShock.Bans.GetBanByIp(verbs["user"]); + else if (type == "name") ban = TShock.Bans.GetBanByName(verbs["user"]); + else + { + returnBlock.Add("Error", "Invalid Type"); + return returnBlock; + } - if (ban == null) - { - return new Dictionary { { "status", "400" }, { "error", "The specified ban does not exist." } }; - } + if (ban == null) + { + return new Dictionary {{"status", "400"}, {"error", "The specified ban does not exist."}}; + } - returnBlock.Add("status", "200"); - returnBlock.Add("name", ban.Name); - returnBlock.Add("ip", ban.IP); - returnBlock.Add("reason", ban.Reason); - return returnBlock; - } + returnBlock.Add("status", "200"); + returnBlock.Add("name", ban.Name); + returnBlock.Add("ip", ban.IP); + returnBlock.Add("reason", ban.Reason); + return returnBlock; + } - #endregion + #endregion - #region RestWorldMethods - object WorldRead(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - returnBlock.Add("status", "200"); - returnBlock.Add("name", Main.worldName); - returnBlock.Add("size", Main.maxTilesX + "*" + Main.maxTilesY); - returnBlock.Add("time", Main.time); - returnBlock.Add("daytime", Main.dayTime); - returnBlock.Add("bloodmoon", Main.bloodMoon); - returnBlock.Add("invasionsize", Main.invasionSize); - return returnBlock; - } + #region RestWorldMethods - object WorldMeteor(RestVerbs verbs, IParameterCollection parameters) - { - WorldGen.dropMeteor(); - var returnBlock = new Dictionary(); - returnBlock.Add("status", "200"); - returnBlock.Add("response", "Meteor has been spawned."); - return returnBlock; - } + private object WorldRead(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + returnBlock.Add("status", "200"); + returnBlock.Add("name", Main.worldName); + returnBlock.Add("size", Main.maxTilesX + "*" + Main.maxTilesY); + returnBlock.Add("time", Main.time); + returnBlock.Add("daytime", Main.dayTime); + returnBlock.Add("bloodmoon", Main.bloodMoon); + returnBlock.Add("invasionsize", Main.invasionSize); + return returnBlock; + } - object WorldBloodmoon(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - var bloodmoonVerb = verbs["bool"]; - bool bloodmoon; - if (bloodmoonVerb == null) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "No parameter was passed."); - return returnBlock; - } - if (!bool.TryParse(bloodmoonVerb, out bloodmoon)) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Unable to parse parameter."); - return returnBlock; - } - Main.bloodMoon = bloodmoon; - returnBlock.Add("status", "200"); - returnBlock.Add("response", "Blood Moon has been set to " + bloodmoon); - return returnBlock; - } - #endregion + private object WorldMeteor(RestVerbs verbs, IParameterCollection parameters) + { + WorldGen.dropMeteor(); + var returnBlock = new Dictionary(); + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Meteor has been spawned."); + return returnBlock; + } - #region RestPlayerMethods - object PlayerRead(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - var playerParam = parameters["player"]; - var found = TShock.Utils.FindPlayer(playerParam); - if (found.Count == 0) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " was not found"); - } - else if (found.Count > 1) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); - } - else if (found.Count == 1) - { - var player = found[0]; - returnBlock.Add("status", "200"); - returnBlock.Add("nickname", player.Name); - returnBlock.Add("username", player.UserAccountName == null ? "" : player.UserAccountName); - returnBlock.Add("ip", player.IP); - returnBlock.Add("group", player.Group.Name); - returnBlock.Add("position", player.TileX + "," + player.TileY); - var activeItems = player.TPlayer.inventory.Where(p => p.active).ToList(); - returnBlock.Add("inventory", string.Join(", ", activeItems.Select(p => p.name))); - returnBlock.Add("buffs", string.Join(", ", player.TPlayer.buffType)); - } - return returnBlock; - } - object PlayerKick(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - var playerParam = parameters["player"]; - var found = TShock.Utils.FindPlayer(playerParam); - var reason = verbs["reason"]; - if (found.Count == 0) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " was not found"); - } - else if (found.Count > 1) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); - } - else if (found.Count == 1) - { - var player = found[0]; - TShock.Utils.ForceKick(player, reason == null ? "Kicked via web" : reason); - returnBlock.Add("status", "200"); - returnBlock.Add("response", "Player " + player.Name + " was kicked"); - } - return returnBlock; - } - object PlayerBan(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - var playerParam = parameters["player"]; - var found = TShock.Utils.FindPlayer(playerParam); - var reason = verbs["reason"]; - if (found.Count == 0) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " was not found"); - } - else if (found.Count > 1) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); - } - else if (found.Count == 1) - { - var player = found[0]; - TShock.Bans.AddBan(player.IP, player.Name, reason == null ? "Banned via web" : reason); - TShock.Utils.ForceKick(player, reason == null ? "Banned via web" : reason); - returnBlock.Add("status", "200"); - returnBlock.Add("response", "Player " + player.Name + " was banned"); - } - return returnBlock; - } - #endregion + private object WorldBloodmoon(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var bloodmoonVerb = verbs["bool"]; + bool bloodmoon; + if (bloodmoonVerb == null) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "No parameter was passed."); + return returnBlock; + } + if (!bool.TryParse(bloodmoonVerb, out bloodmoon)) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Unable to parse parameter."); + return returnBlock; + } + Main.bloodMoon = bloodmoon; + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Blood Moon has been set to " + bloodmoon); + return returnBlock; + } - #region RestExampleMethods + #endregion - public void RegisterExamples() - { - Rest.Register(new RestCommand("/HelloWorld/name/{username}", UserTest) { RequiresToken = false }); - Rest.Register(new RestCommand("/wizard/{username}", Wizard) { RequiresToken = false }); - } + #region RestPlayerMethods - //The Wizard example, for demonstrating the response convention: - object Wizard(RestVerbs verbs, IParameterCollection parameters) - { - var returnBack = new Dictionary(); - returnBack.Add("status", "200"); //Keep this in everything, 200 = ok, etc. Standard http status codes. - returnBack.Add("error", "(If this failed, you would have a different status code and provide the error object.)"); //And only include this if the status isn't 200 or a failure - returnBack.Add("Verified Wizard", "You're a wizard, " + verbs["username"]); //Outline any api calls and possible responses in some form of documentation somewhere - return returnBack; - } + private object PlayerRead(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var playerParam = parameters["player"]; + var found = TShock.Utils.FindPlayer(playerParam); + if (found.Count == 0) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " was not found"); + } + else if (found.Count > 1) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); + } + else if (found.Count == 1) + { + var player = found[0]; + returnBlock.Add("status", "200"); + returnBlock.Add("nickname", player.Name); + returnBlock.Add("username", player.UserAccountName == null ? "" : player.UserAccountName); + returnBlock.Add("ip", player.IP); + returnBlock.Add("group", player.Group.Name); + returnBlock.Add("position", player.TileX + "," + player.TileY); + var activeItems = player.TPlayer.inventory.Where(p => p.active).ToList(); + returnBlock.Add("inventory", string.Join(", ", activeItems.Select(p => p.name))); + returnBlock.Add("buffs", string.Join(", ", player.TPlayer.buffType)); + } + return returnBlock; + } - //http://127.0.0.1:8080/HelloWorld/name/{username}?type=status - object UserTest(RestVerbs verbs, IParameterCollection parameters) - { - var ret = new Dictionary(); - var type = parameters["type"]; - if (type == null) - { - ret.Add("Error", "Invalid Type"); - return ret; - } - if (type == "status") - { - ret.Add("Users", "Info here"); - return ret; - } - return null; - } - #endregion - } -} + private object PlayerKick(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var playerParam = parameters["player"]; + var found = TShock.Utils.FindPlayer(playerParam); + var reason = verbs["reason"]; + if (found.Count == 0) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " was not found"); + } + else if (found.Count > 1) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); + } + else if (found.Count == 1) + { + var player = found[0]; + TShock.Utils.ForceKick(player, reason == null ? "Kicked via web" : reason); + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Player " + player.Name + " was kicked"); + } + return returnBlock; + } + + private object PlayerBan(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var playerParam = parameters["player"]; + var found = TShock.Utils.FindPlayer(playerParam); + var reason = verbs["reason"]; + if (found.Count == 0) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " was not found"); + } + else if (found.Count > 1) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); + } + else if (found.Count == 1) + { + var player = found[0]; + TShock.Bans.AddBan(player.IP, player.Name, reason == null ? "Banned via web" : reason); + TShock.Utils.ForceKick(player, reason == null ? "Banned via web" : reason); + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Player " + player.Name + " was banned"); + } + return returnBlock; + } + + #endregion + + #region RestExampleMethods + + public void RegisterExamples() + { + Rest.Register(new RestCommand("/HelloWorld/name/{username}", UserTest) {RequiresToken = false}); + Rest.Register(new RestCommand("/wizard/{username}", Wizard) {RequiresToken = false}); + } + + //The Wizard example, for demonstrating the response convention: + private object Wizard(RestVerbs verbs, IParameterCollection parameters) + { + var returnBack = new Dictionary(); + returnBack.Add("status", "200"); //Keep this in everything, 200 = ok, etc. Standard http status codes. + returnBack.Add("error", "(If this failed, you would have a different status code and provide the error object.)"); + //And only include this if the status isn't 200 or a failure + returnBack.Add("Verified Wizard", "You're a wizard, " + verbs["username"]); + //Outline any api calls and possible responses in some form of documentation somewhere + return returnBack; + } + + //http://127.0.0.1:8080/HelloWorld/name/{username}?type=status + private object UserTest(RestVerbs verbs, IParameterCollection parameters) + { + var ret = new Dictionary(); + var type = parameters["type"]; + if (type == null) + { + ret.Add("Error", "Invalid Type"); + return ret; + } + if (type == "status") + { + ret.Add("Users", "Info here"); + return ret; + } + return null; + } + + #endregion + } +} \ No newline at end of file diff --git a/TShockAPI/Rest/RestObject.cs b/TShockAPI/Rest/RestObject.cs index eb0631d9..610749cd 100644 --- a/TShockAPI/Rest/RestObject.cs +++ b/TShockAPI/Rest/RestObject.cs @@ -3,61 +3,63 @@ using System.Collections.Generic; namespace Rests { - [Serializable] - public class RestObject : Dictionary - { - public string Status - { - get { return this["status"] as string; } - set { this["status"] = value; } - } - public string Error - { - get { return this["error"] as string; } - set { this["error"] = value; } - } - public string Response - { - get { return this["response"] as string; } - set { this["response"] = value; } - } + [Serializable] + public class RestObject : Dictionary + { + public string Status + { + get { return this["status"] as string; } + set { this["status"] = value; } + } - public RestObject(string status) - { - Status = status; - } + public string Error + { + get { return this["error"] as string; } + set { this["error"] = value; } + } - /// - /// Gets value safely, if it does not exist, return null. Sets/Adds value safely, if null it will remove. - /// - /// - /// - /// Returns null if key does not exist. - public new object this[string key] - { - get - { - object ret; - if (TryGetValue(key, out ret)) - return ret; - return null; - } - set - { - if (!ContainsKey(key)) - { - if (value == null) - return; - Add(key, value); - } - else - { - if (value != null) - base[key] = value; - else - Remove(key); - } - } - } - } + public string Response + { + get { return this["response"] as string; } + set { this["response"] = value; } + } + + public RestObject(string status) + { + Status = status; + } + + /// + /// Gets value safely, if it does not exist, return null. Sets/Adds value safely, if null it will remove. + /// + /// + /// + /// Returns null if key does not exist. + public new object this[string key] + { + get + { + object ret; + if (TryGetValue(key, out ret)) + return ret; + return null; + } + set + { + if (!ContainsKey(key)) + { + if (value == null) + return; + Add(key, value); + } + else + { + if (value != null) + base[key] = value; + else + Remove(key); + } + } + } + } } \ No newline at end of file diff --git a/TShockAPI/Rest/RestVerbs.cs b/TShockAPI/Rest/RestVerbs.cs index bbad41d3..cda3fe21 100644 --- a/TShockAPI/Rest/RestVerbs.cs +++ b/TShockAPI/Rest/RestVerbs.cs @@ -3,40 +3,40 @@ using System.Collections.Generic; namespace Rests { - [Serializable] - public class RestVerbs : Dictionary - { - /// - /// Gets value safely, if it does not exist, return null. Sets/Adds value safely, if null it will remove. - /// - /// - /// - /// Returns null if key does not exist. - public new string this[string key] - { - get - { - string ret; - if (TryGetValue(key, out ret)) - return ret; - return null; - } - set - { - if (!ContainsKey(key)) - { - if (value == null) - return; - Add(key, value); - } - else - { - if (value != null) - base[key] = value; - else - Remove(key); - } - } - } - } + [Serializable] + public class RestVerbs : Dictionary + { + /// + /// Gets value safely, if it does not exist, return null. Sets/Adds value safely, if null it will remove. + /// + /// + /// + /// Returns null if key does not exist. + public new string this[string key] + { + get + { + string ret; + if (TryGetValue(key, out ret)) + return ret; + return null; + } + set + { + if (!ContainsKey(key)) + { + if (value == null) + return; + Add(key, value); + } + else + { + if (value != null) + base[key] = value; + else + Remove(key); + } + } + } + } } \ No newline at end of file diff --git a/TShockAPI/Rest/SecureRest.cs b/TShockAPI/Rest/SecureRest.cs index 4563f4b6..913532cf 100644 --- a/TShockAPI/Rest/SecureRest.cs +++ b/TShockAPI/Rest/SecureRest.cs @@ -6,84 +6,96 @@ using HttpServer; namespace Rests { - /// - /// - /// - /// Username to verify - /// Password to verify - /// Returning a restobject with a null error means a successful verification. - public delegate RestObject VerifyD(string username, string password); - public class SecureRest : Rest - { - public Dictionary Tokens { get; protected set; } - public event VerifyD Verify; - public SecureRest(IPAddress ip, int port) - : base(ip, port) - { - Tokens = new Dictionary(); - Register(new RestCommand("/token/create/{username}/{password}", NewToken) { RequiresToken = false }); - Register(new RestCommand("/token/destroy/{token}", DestroyToken) { RequiresToken = true }); - } + /// + /// + /// + /// Username to verify + /// Password to verify + /// Returning a restobject with a null error means a successful verification. + public delegate RestObject VerifyD(string username, string password); - object DestroyToken(RestVerbs verbs, IParameterCollection parameters) - { - var token = verbs["token"]; - try - { - Tokens.Remove(token); - } - catch (Exception) - { - return new Dictionary { { "status", "400" }, { "error", "The specified token queued for destruction failed to be deleted." } }; - } - return new Dictionary { { "status", "200" }, { "response", "Requested token was successfully destroyed." } }; - } + public class SecureRest : Rest + { + public Dictionary Tokens { get; protected set; } + public event VerifyD Verify; - object NewToken(RestVerbs verbs, IParameterCollection parameters) - { - var user = verbs["username"]; - var pass = verbs["password"]; + public SecureRest(IPAddress ip, int port) + : base(ip, port) + { + Tokens = new Dictionary(); + Register(new RestCommand("/token/create/{username}/{password}", NewToken) {RequiresToken = false}); + Register(new RestCommand("/token/destroy/{token}", DestroyToken) {RequiresToken = true}); + } - RestObject obj = null; - if (Verify != null) - obj = Verify(user, pass); + private object DestroyToken(RestVerbs verbs, IParameterCollection parameters) + { + var token = verbs["token"]; + try + { + Tokens.Remove(token); + } + catch (Exception) + { + return new Dictionary + {{"status", "400"}, {"error", "The specified token queued for destruction failed to be deleted."}}; + } + return new Dictionary + {{"status", "200"}, {"response", "Requested token was successfully destroyed."}}; + } - if (obj == null) - obj = new RestObject("401") { Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair." }; + private object NewToken(RestVerbs verbs, IParameterCollection parameters) + { + var user = verbs["username"]; + var pass = verbs["password"]; - if (obj.Error != null) - return obj; + RestObject obj = null; + if (Verify != null) + obj = Verify(user, pass); - string hash; - var rand = new Random(); - var randbytes = new byte[32]; - do - { - rand.NextBytes(randbytes); - hash = randbytes.Aggregate("", (s, b) => s + b.ToString("X2")); - } while (Tokens.ContainsKey(hash)); + if (obj == null) + obj = new RestObject("401") + {Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair."}; - Tokens.Add(hash, user); + if (obj.Error != null) + return obj; - obj["token"] = hash; - return obj; - } + string hash; + var rand = new Random(); + var randbytes = new byte[32]; + do + { + rand.NextBytes(randbytes); + hash = randbytes.Aggregate("", (s, b) => s + b.ToString("X2")); + } while (Tokens.ContainsKey(hash)); + + Tokens.Add(hash, user); + + obj["token"] = hash; + return obj; + } + protected override object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms) + { + if (cmd.RequiresToken) + { + var strtoken = parms["token"]; + if (strtoken == null) + return new Dictionary + {{"status", "401"}, {"error", "Not authorized. The specified API endpoint requires a token."}}; - protected override object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms) - { - if (cmd.RequiresToken) - { - var strtoken = parms["token"]; - if (strtoken == null) - return new Dictionary { { "status", "401" }, { "error", "Not authorized. The specified API endpoint requires a token." } }; - - object token; - if (!Tokens.TryGetValue(strtoken, out token)) - return new Dictionary { { "status", "403" }, { "error", "Not authorized. The specified API endpoint requires a token, but the provided token was not valid." } }; - } - return base.ExecuteCommand(cmd, verbs, parms); - } - } -} + object token; + if (!Tokens.TryGetValue(strtoken, out token)) + return new Dictionary + { + {"status", "403"}, + { + "error", + "Not authorized. The specified API endpoint requires a token, but the provided token was not valid." + } + }; + } + return base.ExecuteCommand(cmd, verbs, parms); + } + } +} \ No newline at end of file diff --git a/TShockAPI/StatTracker.cs b/TShockAPI/StatTracker.cs index 5cf75f74..9c8c9923 100644 --- a/TShockAPI/StatTracker.cs +++ b/TShockAPI/StatTracker.cs @@ -8,13 +8,13 @@ namespace TShockAPI { public class StatTracker { - Utils Utils = TShock.Utils; + private Utils Utils = TShock.Utils; public DateTime lastcheck = DateTime.MinValue; - readonly int checkinFrequency = 5; + private readonly int checkinFrequency = 5; public void checkin() { - if ((DateTime.Now - lastcheck).TotalMinutes >= checkinFrequency) + if ((DateTime.Now - lastcheck).TotalMinutes >= checkinFrequency) { ThreadPool.QueueUserWorkItem(callHome); lastcheck = DateTime.Now; @@ -51,17 +51,23 @@ namespace TShockAPI using (var client = new WebClient()) { client.Headers.Add("user-agent", - "TShock (" + TShock.VersionNum + ")"); + "TShock (" + TShock.VersionNum + ")"); try { string response; if (TShock.Config.DisablePlayerCountReporting) { - response = client.DownloadString("http://tshock.co/tickto.php?do=log&fp=" + fp + "&ver=" + TShock.VersionNum + "&os=" + Environment.OSVersion + "&mono=" + Main.runningMono + "&port=" + Netplay.serverPort + "&plcount=0"); + response = + client.DownloadString("http://tshock.co/tickto.php?do=log&fp=" + fp + "&ver=" + TShock.VersionNum + "&os=" + + Environment.OSVersion + "&mono=" + Main.runningMono + "&port=" + Netplay.serverPort + + "&plcount=0"); } else { - response = client.DownloadString("http://tshock.co/tickto.php?do=log&fp=" + fp + "&ver=" + TShock.VersionNum + "&os=" + Environment.OSVersion + "&mono=" + Main.runningMono + "&port=" + Netplay.serverPort + "&plcount=" + TShock.Utils.ActivePlayers()); + response = + client.DownloadString("http://tshock.co/tickto.php?do=log&fp=" + fp + "&ver=" + TShock.VersionNum + "&os=" + + Environment.OSVersion + "&mono=" + Main.runningMono + "&port=" + Netplay.serverPort + + "&plcount=" + TShock.Utils.ActivePlayers()); } Log.ConsoleInfo("Stat Tracker: " + response + "\n"); } @@ -72,4 +78,4 @@ namespace TShockAPI } } } -} +} \ No newline at end of file diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 0f3ebf85..3fea44f0 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -25,595 +25,610 @@ using TShockAPI.Net; namespace TShockAPI { - public class TSPlayer - { - public static readonly TSServerPlayer Server = new TSServerPlayer(); - public static readonly TSPlayer All = new TSPlayer("All"); - public int TileKillThreshold { get; set; } - public int TilePlaceThreshold { get; set; } - public int TileLiquidThreshold { get; set; } - public int ProjectileThreshold { get; set; } - public Dictionary TilesDestroyed { get; protected set; } - public Dictionary TilesCreated { get; protected set; } - public int FirstMaxHP { get; set; } - public int FirstMaxMP { get; set; } - public Group Group { get; set; } - public bool ReceivedInfo { get; set; } - public int Index { get; protected set; } - public DateTime LastPvpChange; - public Point[] TempPoints = new Point[2]; - public int AwaitingTempPoint { get; set; } - public bool AwaitingName { get; set; } - public DateTime LastThreat { get; set; } - public DateTime LastTileChangeNotify { get; set; } - public bool InitSpawn; - public bool DisplayLogs = true; - public Vector2 oldSpawn = Vector2.Zero; - public TSPlayer LastWhisper; - public int LoginAttempts { get; set; } - public Vector2 TeleportCoords = new Vector2(-1, -1); - public Vector2 LastNetPosition = Vector2.Zero; - public string UserAccountName { get; set; } - public bool HasBeenSpammedWithBuildMessage; - public bool IsLoggedIn; - public int UserID = -1; - public bool HasBeenNaggedAboutLoggingIn; - public bool TPAllow = true; - public bool mute; - public bool TpLock; - Player FakePlayer; - public bool RequestedSection; - public DateTime LastDeath { get; set; } - public bool Dead; - public string Country = "??"; - public int Difficulty; - private string CacheIP; - public string IgnoreActionsForInventory = "none"; - public string IgnoreActionsForCheating = "none"; - public string IgnoreActionsForDisabledArmor = "none"; - public bool IgnoreActionsForClearingTrashCan; - public PlayerData PlayerData; - public bool RequiresPassword; + public class TSPlayer + { + public static readonly TSServerPlayer Server = new TSServerPlayer(); + public static readonly TSPlayer All = new TSPlayer("All"); + public int TileKillThreshold { get; set; } + public int TilePlaceThreshold { get; set; } + public int TileLiquidThreshold { get; set; } + public int ProjectileThreshold { get; set; } + public Dictionary TilesDestroyed { get; protected set; } + public Dictionary TilesCreated { get; protected set; } + public int FirstMaxHP { get; set; } + public int FirstMaxMP { get; set; } + public Group Group { get; set; } + public bool ReceivedInfo { get; set; } + public int Index { get; protected set; } + public DateTime LastPvpChange; + public Point[] TempPoints = new Point[2]; + public int AwaitingTempPoint { get; set; } + public bool AwaitingName { get; set; } + public DateTime LastThreat { get; set; } + public DateTime LastTileChangeNotify { get; set; } + public bool InitSpawn; + public bool DisplayLogs = true; + public Vector2 oldSpawn = Vector2.Zero; + public TSPlayer LastWhisper; + public int LoginAttempts { get; set; } + public Vector2 TeleportCoords = new Vector2(-1, -1); + public Vector2 LastNetPosition = Vector2.Zero; + public string UserAccountName { get; set; } + public bool HasBeenSpammedWithBuildMessage; + public bool IsLoggedIn; + public int UserID = -1; + public bool HasBeenNaggedAboutLoggingIn; + public bool TPAllow = true; + public bool mute; + public bool TpLock; + private Player FakePlayer; + public bool RequestedSection; + public DateTime LastDeath { get; set; } + public bool Dead; + public string Country = "??"; + public int Difficulty; + private string CacheIP; + public string IgnoreActionsForInventory = "none"; + public string IgnoreActionsForCheating = "none"; + public string IgnoreActionsForDisabledArmor = "none"; + public bool IgnoreActionsForClearingTrashCan; + public PlayerData PlayerData; + public bool RequiresPassword; - public bool RealPlayer - { - get { return Index >= 0 && Index < Main.maxNetPlayers && Main.player[Index] != null; } - } - public bool ConnectionAlive - { - get { return RealPlayer && (Netplay.serverSock[Index] != null && Netplay.serverSock[Index].active && !Netplay.serverSock[Index].kill); } - } + public bool RealPlayer + { + get { return Index >= 0 && Index < Main.maxNetPlayers && Main.player[Index] != null; } + } - public int State - { - get { return Netplay.serverSock[Index].state; } - set { Netplay.serverSock[Index].state = value; } - } + public bool ConnectionAlive + { + get + { + return RealPlayer && + (Netplay.serverSock[Index] != null && Netplay.serverSock[Index].active && !Netplay.serverSock[Index].kill); + } + } - public string IP - { - get - { - if (string.IsNullOrEmpty(CacheIP)) - return CacheIP = RealPlayer ? (Netplay.serverSock[Index].tcpClient.Connected ? TShock.Utils.GetRealIP(Netplay.serverSock[Index].tcpClient.Client.RemoteEndPoint.ToString()) : "") : ""; - else - return CacheIP; - } - } - /// - /// Terraria Player - /// - public Player TPlayer - { - get - { - return FakePlayer ?? Main.player[Index]; - } - } - public string Name - { - get { return TPlayer.name; } - } - public bool Active - { - get { return TPlayer != null && TPlayer.active; } - } - public int Team - { - get { return TPlayer.team; } - } - public float X - { - get - { + public int State + { + get { return Netplay.serverSock[Index].state; } + set { Netplay.serverSock[Index].state = value; } + } - return RealPlayer ? TPlayer.position.X : Main.spawnTileX * 16; - } - } - public float Y - { - get - { - return RealPlayer ? TPlayer.position.Y : Main.spawnTileY * 16; - } - } - public int TileX - { - get { return (int)(X / 16); } - } - public int TileY - { - get { return (int)(Y / 16); } - } - public bool InventorySlotAvailable - { - get - { - bool flag = false; - if (RealPlayer) - { - for (int i = 0; i < 40; i++) //41 is trash can, 42-45 is coins, 46-49 is ammo - { - if (TPlayer.inventory[i] == null || !TPlayer.inventory[i].active || TPlayer.inventory[i].name == "") - { - flag = true; - break; - } - } - } - return flag; - } - } + public string IP + { + get + { + if (string.IsNullOrEmpty(CacheIP)) + return + CacheIP = + RealPlayer + ? (Netplay.serverSock[Index].tcpClient.Connected + ? TShock.Utils.GetRealIP(Netplay.serverSock[Index].tcpClient.Client.RemoteEndPoint.ToString()) + : "") + : ""; + else + return CacheIP; + } + } - public TSPlayer(int index) - { - TilesDestroyed = new Dictionary(); - TilesCreated = new Dictionary(); - Index = index; - Group = new Group(TShock.Config.DefaultGuestGroupName); - } + /// + /// Terraria Player + /// + public Player TPlayer + { + get { return FakePlayer ?? Main.player[Index]; } + } - protected TSPlayer(String playerName) - { - TilesDestroyed = new Dictionary(); - TilesCreated = new Dictionary(); - Index = -1; - FakePlayer = new Player { name = playerName, whoAmi = -1 }; - Group = new Group(TShock.Config.DefaultGuestGroupName); - } + public string Name + { + get { return TPlayer.name; } + } - public virtual void Disconnect(string reason) - { - SendData(PacketTypes.Disconnect, reason); - } + public bool Active + { + get { return TPlayer != null && TPlayer.active; } + } - public virtual void Flush() - { - var sock = Netplay.serverSock[Index]; - if (sock == null) - return; + public int Team + { + get { return TPlayer.team; } + } - TShock.PacketBuffer.Flush(sock); - } + public float X + { + get { return RealPlayer ? TPlayer.position.X : Main.spawnTileX*16; } + } + + public float Y + { + get { return RealPlayer ? TPlayer.position.Y : Main.spawnTileY*16; } + } + + public int TileX + { + get { return (int) (X/16); } + } + + public int TileY + { + get { return (int) (Y/16); } + } + + public bool InventorySlotAvailable + { + get + { + bool flag = false; + if (RealPlayer) + { + for (int i = 0; i < 40; i++) //41 is trash can, 42-45 is coins, 46-49 is ammo + { + if (TPlayer.inventory[i] == null || !TPlayer.inventory[i].active || TPlayer.inventory[i].name == "") + { + flag = true; + break; + } + } + } + return flag; + } + } + + public TSPlayer(int index) + { + TilesDestroyed = new Dictionary(); + TilesCreated = new Dictionary(); + Index = index; + Group = new Group(TShock.Config.DefaultGuestGroupName); + } + + protected TSPlayer(String playerName) + { + TilesDestroyed = new Dictionary(); + TilesCreated = new Dictionary(); + Index = -1; + FakePlayer = new Player {name = playerName, whoAmi = -1}; + Group = new Group(TShock.Config.DefaultGuestGroupName); + } + + public virtual void Disconnect(string reason) + { + SendData(PacketTypes.Disconnect, reason); + } + + public virtual void Flush() + { + var sock = Netplay.serverSock[Index]; + if (sock == null) + return; + + TShock.PacketBuffer.Flush(sock); + } - void SendWorldInfo(int tilex, int tiley, bool fakeid) - { - using (var ms = new MemoryStream()) - { - var msg = new WorldInfoMsg - { - Time = (int)Main.time, - DayTime = Main.dayTime, - MoonPhase = (byte)Main.moonPhase, - BloodMoon = Main.bloodMoon, - MaxTilesX = Main.maxTilesX, - MaxTilesY = Main.maxTilesY, - SpawnX = tilex, - SpawnY = tiley, - WorldSurface = (int)Main.worldSurface, - RockLayer = (int)Main.rockLayer, - //Sending a fake world id causes the client to not be able to find a stored spawnx/y. - //This fixes the bed spawn point bug. With a fake world id it wont be able to find the bed spawn. - WorldID = !fakeid ? Main.worldID : -1, - WorldFlags = (WorldGen.shadowOrbSmashed ? WorldInfoFlag.OrbSmashed : WorldInfoFlag.None) | - (NPC.downedBoss1 ? WorldInfoFlag.DownedBoss1 : WorldInfoFlag.None) | - (NPC.downedBoss2 ? WorldInfoFlag.DownedBoss2 : WorldInfoFlag.None) | - (NPC.downedBoss3 ? WorldInfoFlag.DownedBoss3 : WorldInfoFlag.None) | - (Main.hardMode ? WorldInfoFlag.HardMode : WorldInfoFlag.None) | - (NPC.downedClown ? WorldInfoFlag.DownedClown : WorldInfoFlag.None), - WorldName = Main.worldName - }; - msg.PackFull(ms); - SendRawData(ms.ToArray()); - } - } + private void SendWorldInfo(int tilex, int tiley, bool fakeid) + { + using (var ms = new MemoryStream()) + { + var msg = new WorldInfoMsg + { + Time = (int) Main.time, + DayTime = Main.dayTime, + MoonPhase = (byte) Main.moonPhase, + BloodMoon = Main.bloodMoon, + MaxTilesX = Main.maxTilesX, + MaxTilesY = Main.maxTilesY, + SpawnX = tilex, + SpawnY = tiley, + WorldSurface = (int) Main.worldSurface, + RockLayer = (int) Main.rockLayer, + //Sending a fake world id causes the client to not be able to find a stored spawnx/y. + //This fixes the bed spawn point bug. With a fake world id it wont be able to find the bed spawn. + WorldID = !fakeid ? Main.worldID : -1, + WorldFlags = (WorldGen.shadowOrbSmashed ? WorldInfoFlag.OrbSmashed : WorldInfoFlag.None) | + (NPC.downedBoss1 ? WorldInfoFlag.DownedBoss1 : WorldInfoFlag.None) | + (NPC.downedBoss2 ? WorldInfoFlag.DownedBoss2 : WorldInfoFlag.None) | + (NPC.downedBoss3 ? WorldInfoFlag.DownedBoss3 : WorldInfoFlag.None) | + (Main.hardMode ? WorldInfoFlag.HardMode : WorldInfoFlag.None) | + (NPC.downedClown ? WorldInfoFlag.DownedClown : WorldInfoFlag.None), + WorldName = Main.worldName + }; + msg.PackFull(ms); + SendRawData(ms.ToArray()); + } + } - public bool Teleport(int tilex, int tiley) - { - InitSpawn = false; + public bool Teleport(int tilex, int tiley) + { + InitSpawn = false; - SendWorldInfo(tilex, tiley, true); + SendWorldInfo(tilex, tiley, true); - //150 Should avoid all client crash errors - //The error occurs when a tile trys to update which the client hasnt load yet, Clients only update tiles withen 150 blocks - //Try 300 if it does not work (Higher number - Longer load times - Less chance of error) - //Should we properly send sections so that clients don't get tiles twice? - if (!SendTileSquare(tilex, tiley)) - { - InitSpawn = true; - SendWorldInfo(Main.spawnTileX, Main.spawnTileY, false); - return false; - } + //150 Should avoid all client crash errors + //The error occurs when a tile trys to update which the client hasnt load yet, Clients only update tiles withen 150 blocks + //Try 300 if it does not work (Higher number - Longer load times - Less chance of error) + //Should we properly send sections so that clients don't get tiles twice? + if (!SendTileSquare(tilex, tiley)) + { + InitSpawn = true; + SendWorldInfo(Main.spawnTileX, Main.spawnTileY, false); + return false; + } - Spawn(-1, -1); + Spawn(-1, -1); - SendWorldInfo(Main.spawnTileX, Main.spawnTileY, false); + SendWorldInfo(Main.spawnTileX, Main.spawnTileY, false); - TPlayer.position.X = tilex; - TPlayer.position.Y = tiley; + TPlayer.position.X = tilex; + TPlayer.position.Y = tiley; - return true; - } + return true; + } - public void Spawn() - { - Spawn(TPlayer.SpawnX, TPlayer.SpawnY); - } + public void Spawn() + { + Spawn(TPlayer.SpawnX, TPlayer.SpawnY); + } - public void Spawn(int tilex, int tiley) - { - using (var ms = new MemoryStream()) - { - var msg = new SpawnMsg - { - PlayerIndex = (byte)Index, - TileX = tilex, - TileY = tiley - }; - msg.PackFull(ms); - SendRawData(ms.ToArray()); - } - } + public void Spawn(int tilex, int tiley) + { + using (var ms = new MemoryStream()) + { + var msg = new SpawnMsg + { + PlayerIndex = (byte) Index, + TileX = tilex, + TileY = tiley + }; + msg.PackFull(ms); + SendRawData(ms.ToArray()); + } + } - public void RemoveProjectile(int index, int owner) - { - using (var ms = new MemoryStream()) - { - var msg = new ProjectileRemoveMsg - { - Index = (short)index, - Owner = (byte)owner - }; - msg.PackFull(ms); - SendRawData(ms.ToArray()); - } - } + public void RemoveProjectile(int index, int owner) + { + using (var ms = new MemoryStream()) + { + var msg = new ProjectileRemoveMsg + { + Index = (short) index, + Owner = (byte) owner + }; + msg.PackFull(ms); + SendRawData(ms.ToArray()); + } + } - public virtual bool SendTileSquare(int x, int y, int size = 10) - { - try - { - int num = (size - 1) / 2; - SendData(PacketTypes.TileSendSquare, "", size, (x - num), (y - num)); - return true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - return false; - } + public virtual bool SendTileSquare(int x, int y, int size = 10) + { + try + { + int num = (size - 1)/2; + SendData(PacketTypes.TileSendSquare, "", size, (x - num), (y - num)); + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; + } - public virtual void GiveItem(int type, string name, int width, int height, int stack, int prefix = 0) - { - int itemid = Item.NewItem((int)X, (int)Y, width, height, type, stack, true, prefix); - // This is for special pickaxe/hammers/swords etc - Main.item[itemid].SetDefaults(name); - // The set default overrides the wet and stack set by NewItem - Main.item[itemid].wet = Collision.WetCollision(Main.item[itemid].position, Main.item[itemid].width, Main.item[itemid].height); - Main.item[itemid].stack = stack; - Main.item[itemid].owner = Index; - Main.item[itemid].prefix = (byte) prefix; - NetMessage.SendData((int)PacketTypes.ItemDrop, -1, -1, "", itemid, 0f, 0f, 0f); - NetMessage.SendData((int)PacketTypes.ItemOwner, -1, -1, "", itemid, 0f, 0f, 0f); - } + public virtual void GiveItem(int type, string name, int width, int height, int stack, int prefix = 0) + { + int itemid = Item.NewItem((int) X, (int) Y, width, height, type, stack, true, prefix); + // This is for special pickaxe/hammers/swords etc + Main.item[itemid].SetDefaults(name); + // The set default overrides the wet and stack set by NewItem + Main.item[itemid].wet = Collision.WetCollision(Main.item[itemid].position, Main.item[itemid].width, + Main.item[itemid].height); + Main.item[itemid].stack = stack; + Main.item[itemid].owner = Index; + Main.item[itemid].prefix = (byte) prefix; + NetMessage.SendData((int) PacketTypes.ItemDrop, -1, -1, "", itemid, 0f, 0f, 0f); + NetMessage.SendData((int) PacketTypes.ItemOwner, -1, -1, "", itemid, 0f, 0f, 0f); + } - public virtual void SendMessage(string msg) - { - SendMessage(msg, 0, 255, 0); - } + public virtual void SendMessage(string msg) + { + SendMessage(msg, 0, 255, 0); + } - public virtual void SendMessage(string msg, Color color) - { - SendMessage(msg, color.R, color.G, color.B); - } + public virtual void SendMessage(string msg, Color color) + { + SendMessage(msg, color.R, color.G, color.B); + } - public virtual void SendMessage(string msg, byte red, byte green, byte blue) - { - SendData(PacketTypes.ChatText, msg, 255, red, green, blue); - } + public virtual void SendMessage(string msg, byte red, byte green, byte blue) + { + SendData(PacketTypes.ChatText, msg, 255, red, green, blue); + } - public virtual void DamagePlayer(int damage) - { - NetMessage.SendData((int)PacketTypes.PlayerDamage, -1, -1, "", Index, ((new Random()).Next(-1, 1)), damage, (float)0); - } + public virtual void DamagePlayer(int damage) + { + NetMessage.SendData((int) PacketTypes.PlayerDamage, -1, -1, "", Index, ((new Random()).Next(-1, 1)), damage, + (float) 0); + } - public virtual void SetTeam(int team) - { - Main.player[Index].team = team; - SendData(PacketTypes.PlayerTeam, "", Index); - } + public virtual void SetTeam(int team) + { + Main.player[Index].team = team; + SendData(PacketTypes.PlayerTeam, "", Index); + } - public virtual void Disable() - { - LastThreat = DateTime.UtcNow; - SetBuff(33, 330, true); //Weak - SetBuff(32, 330, true); //Slow - SetBuff(23, 330, true); //Cursed - } + public virtual void Disable() + { + LastThreat = DateTime.UtcNow; + SetBuff(33, 330, true); //Weak + SetBuff(32, 330, true); //Slow + SetBuff(23, 330, true); //Cursed + } - public virtual void Whoopie(object time) - { - var time2 = (int)time; - var launch = DateTime.UtcNow; - var startname = Name; - SendMessage("You are now being annoyed.", Color.Red); - while ((DateTime.UtcNow - launch).TotalSeconds < time2 && startname == Name) - { - SendData(PacketTypes.NpcSpecial, number: Index, number2: 2f); - Thread.Sleep(50); - } - } + public virtual void Whoopie(object time) + { + var time2 = (int) time; + var launch = DateTime.UtcNow; + var startname = Name; + SendMessage("You are now being annoyed.", Color.Red); + while ((DateTime.UtcNow - launch).TotalSeconds < time2 && startname == Name) + { + SendData(PacketTypes.NpcSpecial, number: Index, number2: 2f); + Thread.Sleep(50); + } + } - public virtual void SetBuff(int type, int time = 3600, bool bypass = false) - { - if ((DateTime.UtcNow - LastThreat).TotalMilliseconds < 5000 && !bypass) - return; + public virtual void SetBuff(int type, int time = 3600, bool bypass = false) + { + if ((DateTime.UtcNow - LastThreat).TotalMilliseconds < 5000 && !bypass) + return; - SendData(PacketTypes.PlayerAddBuff, number: Index, number2: type, number3: time); - } + SendData(PacketTypes.PlayerAddBuff, number: Index, number2: type, number3: time); + } - //Todo: Separate this into a few functions. SendTo, SendToAll, etc - public virtual void SendData(PacketTypes msgType, string text = "", int number = 0, float number2 = 0f, float number3 = 0f, float number4 = 0f, int number5 = 0) - { - if (RealPlayer && !ConnectionAlive) - return; + //Todo: Separate this into a few functions. SendTo, SendToAll, etc + public virtual void SendData(PacketTypes msgType, string text = "", int number = 0, float number2 = 0f, + float number3 = 0f, float number4 = 0f, int number5 = 0) + { + if (RealPlayer && !ConnectionAlive) + return; - NetMessage.SendData((int)msgType, Index, -1, text, number, number2, number3, number4, number5); - } + NetMessage.SendData((int) msgType, Index, -1, text, number, number2, number3, number4, number5); + } - public virtual bool SendRawData(byte[] data) - { - if (!RealPlayer || !ConnectionAlive) - return false; + public virtual bool SendRawData(byte[] data) + { + if (!RealPlayer || !ConnectionAlive) + return false; - return TShock.SendBytes(Netplay.serverSock[Index], data); - } - } + return TShock.SendBytes(Netplay.serverSock[Index], data); + } + } - public class TSServerPlayer : TSPlayer - { - public TSServerPlayer() - : base("Server") - { - Group = new SuperAdminGroup(); - } + public class TSServerPlayer : TSPlayer + { + public TSServerPlayer() + : base("Server") + { + Group = new SuperAdminGroup(); + } - public override void SendMessage(string msg) - { - SendMessage(msg, 0, 255, 0); - } + public override void SendMessage(string msg) + { + SendMessage(msg, 0, 255, 0); + } - public override void SendMessage(string msg, Color color) - { - SendMessage(msg, color.R, color.G, color.B); - } + public override void SendMessage(string msg, Color color) + { + SendMessage(msg, color.R, color.G, color.B); + } - public override void SendMessage(string msg, byte red, byte green, byte blue) - { - Console.WriteLine(msg); - //RconHandler.Response += msg + "\n"; - } - - public void SetFullMoon(bool fullmoon) - { - Main.moonPhase = 0; - SetTime(false, 0); - } + public override void SendMessage(string msg, byte red, byte green, byte blue) + { + Console.WriteLine(msg); + //RconHandler.Response += msg + "\n"; + } - public void SetBloodMoon(bool bloodMoon) - { - Main.bloodMoon = bloodMoon; - SetTime(false, 0); - } + public void SetFullMoon(bool fullmoon) + { + Main.moonPhase = 0; + SetTime(false, 0); + } - public void SetTime(bool dayTime, double time) - { - Main.dayTime = dayTime; - Main.time = time; - NetMessage.SendData((int)PacketTypes.TimeSet, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); - NetMessage.syncPlayers(); - } + public void SetBloodMoon(bool bloodMoon) + { + Main.bloodMoon = bloodMoon; + SetTime(false, 0); + } - public void SpawnNPC(int type, string name, int amount, int startTileX, int startTileY, int tileXRange = 100, int tileYRange = 50) - { - for (int i = 0; i < amount; i++) - { - int spawnTileX; - int spawnTileY; - TShock.Utils.GetRandomClearTileWithInRange(startTileX, startTileY, tileXRange, tileYRange, out spawnTileX, out spawnTileY); - int npcid = NPC.NewNPC(spawnTileX * 16, spawnTileY * 16, type, 0); - // This is for special slimes - Main.npc[npcid].SetDefaults(name); - } - } + public void SetTime(bool dayTime, double time) + { + Main.dayTime = dayTime; + Main.time = time; + NetMessage.SendData((int) PacketTypes.TimeSet, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); + NetMessage.syncPlayers(); + } - public void StrikeNPC(int npcid, int damage, float knockBack, int hitDirection) - { - Main.npc[npcid].StrikeNPC(damage, knockBack, hitDirection); - NetMessage.SendData((int)PacketTypes.NpcStrike, -1, -1, "", npcid, damage, knockBack, hitDirection); - } + public void SpawnNPC(int type, string name, int amount, int startTileX, int startTileY, int tileXRange = 100, + int tileYRange = 50) + { + for (int i = 0; i < amount; i++) + { + int spawnTileX; + int spawnTileY; + TShock.Utils.GetRandomClearTileWithInRange(startTileX, startTileY, tileXRange, tileYRange, out spawnTileX, + out spawnTileY); + int npcid = NPC.NewNPC(spawnTileX*16, spawnTileY*16, type, 0); + // This is for special slimes + Main.npc[npcid].SetDefaults(name); + } + } - public void RevertTiles(Dictionary tiles) - { - // Update Main.Tile first so that when tile sqaure is sent it is correct - foreach (KeyValuePair entry in tiles) - { - Main.tile[(int)entry.Key.X, (int)entry.Key.Y].Data = entry.Value; - } - // Send all players updated tile sqaures - foreach (Vector2 coords in tiles.Keys) - { - All.SendTileSquare((int)coords.X, (int)coords.Y, 3); - } - } - } + public void StrikeNPC(int npcid, int damage, float knockBack, int hitDirection) + { + Main.npc[npcid].StrikeNPC(damage, knockBack, hitDirection); + NetMessage.SendData((int) PacketTypes.NpcStrike, -1, -1, "", npcid, damage, knockBack, hitDirection); + } - public class PlayerData - { - public NetItem[] inventory = new NetItem[NetItem.maxNetInventory]; - public int maxHealth = 100; - //public int maxMana = 100; - public bool exists; + public void RevertTiles(Dictionary tiles) + { + // Update Main.Tile first so that when tile sqaure is sent it is correct + foreach (KeyValuePair entry in tiles) + { + Main.tile[(int) entry.Key.X, (int) entry.Key.Y].Data = entry.Value; + } + // Send all players updated tile sqaures + foreach (Vector2 coords in tiles.Keys) + { + All.SendTileSquare((int) coords.X, (int) coords.Y, 3); + } + } + } - public PlayerData(TSPlayer player) - { - for (int i = 0; i < NetItem.maxNetInventory; i++) - { - this.inventory[i] = new NetItem(); - } - this.inventory[0].netID = -15; - this.inventory[0].stack = 1; - if(player.TPlayer.inventory[0] != null && player.TPlayer.inventory[0].netID == -15) - this.inventory[0].prefix = player.TPlayer.inventory[0].prefix; - this.inventory[1].netID = -13; - this.inventory[1].stack = 1; - if (player.TPlayer.inventory[1] != null && player.TPlayer.inventory[1].netID == -13) - this.inventory[1].prefix = player.TPlayer.inventory[1].prefix; - this.inventory[2].netID = -16; - this.inventory[2].stack = 1; - if (player.TPlayer.inventory[2] != null && player.TPlayer.inventory[2].netID == -16) - this.inventory[2].prefix = player.TPlayer.inventory[2].prefix; - } + public class PlayerData + { + public NetItem[] inventory = new NetItem[NetItem.maxNetInventory]; + public int maxHealth = 100; + //public int maxMana = 100; + public bool exists; - public void StoreSlot(int slot, int netID, int prefix, int stack) - { - this.inventory[slot].netID = netID; - if (this.inventory[slot].netID != 0) - { - this.inventory[slot].stack = stack; - this.inventory[slot].prefix = prefix; - } - else - { - this.inventory[slot].stack = 0; - this.inventory[slot].prefix = 0; - } - } + public PlayerData(TSPlayer player) + { + for (int i = 0; i < NetItem.maxNetInventory; i++) + { + this.inventory[i] = new NetItem(); + } + this.inventory[0].netID = -15; + this.inventory[0].stack = 1; + if (player.TPlayer.inventory[0] != null && player.TPlayer.inventory[0].netID == -15) + this.inventory[0].prefix = player.TPlayer.inventory[0].prefix; + this.inventory[1].netID = -13; + this.inventory[1].stack = 1; + if (player.TPlayer.inventory[1] != null && player.TPlayer.inventory[1].netID == -13) + this.inventory[1].prefix = player.TPlayer.inventory[1].prefix; + this.inventory[2].netID = -16; + this.inventory[2].stack = 1; + if (player.TPlayer.inventory[2] != null && player.TPlayer.inventory[2].netID == -16) + this.inventory[2].prefix = player.TPlayer.inventory[2].prefix; + } - public void CopyInventory(TSPlayer player) - { - this.maxHealth = player.TPlayer.statLifeMax; - Item[] inventory = player.TPlayer.inventory; - Item[] armor = player.TPlayer.armor; - for (int i = 0; i < NetItem.maxNetInventory; i++) - { - if (i < 49) - { - if (player.TPlayer.inventory[i] != null) - { - this.inventory[i].netID = inventory[i].netID; - } - else - { - this.inventory[i].netID = 0; - } + public void StoreSlot(int slot, int netID, int prefix, int stack) + { + this.inventory[slot].netID = netID; + if (this.inventory[slot].netID != 0) + { + this.inventory[slot].stack = stack; + this.inventory[slot].prefix = prefix; + } + else + { + this.inventory[slot].stack = 0; + this.inventory[slot].prefix = 0; + } + } - if (this.inventory[i].netID != 0) - { - this.inventory[i].stack = inventory[i].stack; - this.inventory[i].prefix = inventory[i].prefix; - } - else - { - this.inventory[i].stack = 0; - this.inventory[i].prefix = 0; - } - } - else - { - if (player.TPlayer.armor[i - 48] != null) - { - this.inventory[i].netID = armor[i - 48].netID; - } - else - { - this.inventory[i].netID = 0; - } + public void CopyInventory(TSPlayer player) + { + this.maxHealth = player.TPlayer.statLifeMax; + Item[] inventory = player.TPlayer.inventory; + Item[] armor = player.TPlayer.armor; + for (int i = 0; i < NetItem.maxNetInventory; i++) + { + if (i < 49) + { + if (player.TPlayer.inventory[i] != null) + { + this.inventory[i].netID = inventory[i].netID; + } + else + { + this.inventory[i].netID = 0; + } - if (this.inventory[i].netID != 0) - { - this.inventory[i].stack = armor[i - 48].stack; - this.inventory[i].prefix = armor[i - 48].prefix; - } - else - { - this.inventory[i].stack = 0; - this.inventory[i].prefix = 0; - } - } - } - } - } + if (this.inventory[i].netID != 0) + { + this.inventory[i].stack = inventory[i].stack; + this.inventory[i].prefix = inventory[i].prefix; + } + else + { + this.inventory[i].stack = 0; + this.inventory[i].prefix = 0; + } + } + else + { + if (player.TPlayer.armor[i - 48] != null) + { + this.inventory[i].netID = armor[i - 48].netID; + } + else + { + this.inventory[i].netID = 0; + } - public class NetItem - { - public static int maxNetInventory = 59; - public int netID; - public int stack; - public int prefix; + if (this.inventory[i].netID != 0) + { + this.inventory[i].stack = armor[i - 48].stack; + this.inventory[i].prefix = armor[i - 48].prefix; + } + else + { + this.inventory[i].stack = 0; + this.inventory[i].prefix = 0; + } + } + } + } + } - public static string ToString(NetItem[] inventory) - { - string inventoryString = ""; - for (int i = 0; i < maxNetInventory; i++) - { - if (i != 0) - inventoryString += "~"; - inventoryString += inventory[i].netID; - if (inventory[i].netID != 0) - { - inventoryString += "," + inventory[i].stack; - inventoryString += "," + inventory[i].prefix; - } - else - { - inventoryString += ",0,0"; - } - } - return inventoryString; - } + public class NetItem + { + public static int maxNetInventory = 59; + public int netID; + public int stack; + public int prefix; - public static NetItem[] Parse(string data) - { - NetItem[] inventory = new NetItem[maxNetInventory]; - int i; - for (i = 0; i < maxNetInventory; i++) - { - inventory[i] = new NetItem(); - } - string[] items = data.Split('~'); - i = 0; - foreach (string item in items) - { - string[] idata = item.Split(','); - inventory[i].netID = int.Parse(idata[0]); - inventory[i].stack = int.Parse(idata[1]); - inventory[i].prefix = int.Parse(idata[2]); - i++; - } - return inventory; - } - } + public static string ToString(NetItem[] inventory) + { + string inventoryString = ""; + for (int i = 0; i < maxNetInventory; i++) + { + if (i != 0) + inventoryString += "~"; + inventoryString += inventory[i].netID; + if (inventory[i].netID != 0) + { + inventoryString += "," + inventory[i].stack; + inventoryString += "," + inventory[i].prefix; + } + else + { + inventoryString += ",0,0"; + } + } + return inventoryString; + } + + public static NetItem[] Parse(string data) + { + NetItem[] inventory = new NetItem[maxNetInventory]; + int i; + for (i = 0; i < maxNetInventory; i++) + { + inventory[i] = new NetItem(); + } + string[] items = data.Split('~'); + i = 0; + foreach (string item in items) + { + string[] idata = item.Split(','); + inventory[i].netID = int.Parse(idata[0]); + inventory[i].stack = int.Parse(idata[1]); + inventory[i].prefix = int.Parse(idata[2]); + i++; + } + return inventory; + } + } } \ No newline at end of file diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 72be512b..5332001e 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -44,385 +44,390 @@ using TShockAPI.Net; namespace TShockAPI { - [APIVersion(1, 10)] - public class TShock : TerrariaPlugin - { + [APIVersion(1, 10)] + public class TShock : TerrariaPlugin + { public static readonly Version VersionNum = Assembly.GetExecutingAssembly().GetName().Version; - public static readonly string VersionCodename = "Zidonuke fixin' what Redigit doesn't"; + public static readonly string VersionCodename = "This code is a mess"; - public static string SavePath = "tshock"; + public static string SavePath = "tshock"; - public static TSPlayer[] Players = new TSPlayer[Main.maxPlayers]; - public static BanManager Bans; - public static WarpManager Warps; - public static RegionManager Regions; - public static BackupManager Backups; - public static GroupManager Groups; - public static UserManager Users; - public static ItemManager Itembans; - public static RemeberedPosManager RememberedPos; - public static InventoryManager InventoryDB; - public static ConfigFile Config { get; set; } - public static IDbConnection DB; - public static bool OverridePort; - public static PacketBufferer PacketBuffer; - public static GeoIPCountry Geo; - public static SecureRest RestApi; - public static RestManager RestManager; + public static TSPlayer[] Players = new TSPlayer[Main.maxPlayers]; + public static BanManager Bans; + public static WarpManager Warps; + public static RegionManager Regions; + public static BackupManager Backups; + public static GroupManager Groups; + public static UserManager Users; + public static ItemManager Itembans; + public static RemeberedPosManager RememberedPos; + public static InventoryManager InventoryDB; + public static ConfigFile Config { get; set; } + public static IDbConnection DB; + public static bool OverridePort; + public static PacketBufferer PacketBuffer; + public static GeoIPCountry Geo; + public static SecureRest RestApi; + public static RestManager RestManager; public static Utils Utils = new Utils(); public static StatTracker StatTracker = new StatTracker(); - /// - /// Called after TShock is initialized. Useful for plugins that needs hooks before tshock but also depend on tshock being loaded. - /// - public static event Action Initialized; + + /// + /// Called after TShock is initialized. Useful for plugins that needs hooks before tshock but also depend on tshock being loaded. + /// + public static event Action Initialized; - public override Version Version - { - get { return VersionNum; } - } + public override Version Version + { + get { return VersionNum; } + } - public override string Name - { - get { return "TShock"; } - } + public override string Name + { + get { return "TShock"; } + } - public override string Author - { - get { return "The Nyx Team"; } - } + public override string Author + { + get { return "The Nyx Team"; } + } - public override string Description - { - get { return "The administration modification of the future."; } - } + public override string Description + { + get { return "The administration modification of the future."; } + } - public TShock(Main game) - : base(game) - { - Config = new ConfigFile(); - Order = 0; - } + public TShock(Main game) + : base(game) + { + Config = new ConfigFile(); + Order = 0; + } + [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] + public override void Initialize() + { + HandleCommandLine(Environment.GetCommandLineArgs()); - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] - public override void Initialize() - { - HandleCommandLine(Environment.GetCommandLineArgs()); - - if (!Directory.Exists(SavePath)) - Directory.CreateDirectory(SavePath); + if (!Directory.Exists(SavePath)) + Directory.CreateDirectory(SavePath); #if DEBUG Log.Initialize(Path.Combine(SavePath, "log.txt"), LogLevel.All, false); #else - Log.Initialize(Path.Combine(SavePath, "log.txt"), LogLevel.All & ~LogLevel.Debug, false); + Log.Initialize(Path.Combine(SavePath, "log.txt"), LogLevel.All & ~LogLevel.Debug, false); #endif - AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; - try - { - if (File.Exists(Path.Combine(SavePath, "tshock.pid"))) - { - Log.ConsoleInfo("TShock was improperly shut down. Please avoid this in the future, world corruption may result from this."); - File.Delete(Path.Combine(SavePath, "tshock.pid")); - } - File.WriteAllText(Path.Combine(SavePath, "tshock.pid"), Process.GetCurrentProcess().Id.ToString()); + try + { + if (File.Exists(Path.Combine(SavePath, "tshock.pid"))) + { + Log.ConsoleInfo( + "TShock was improperly shut down. Please avoid this in the future, world corruption may result from this."); + File.Delete(Path.Combine(SavePath, "tshock.pid")); + } + File.WriteAllText(Path.Combine(SavePath, "tshock.pid"), Process.GetCurrentProcess().Id.ToString()); - ConfigFile.ConfigRead += OnConfigRead; - FileTools.SetupConfig(); + ConfigFile.ConfigRead += OnConfigRead; + FileTools.SetupConfig(); - HandleCommandLine_Port(Environment.GetCommandLineArgs()); + HandleCommandLine_Port(Environment.GetCommandLineArgs()); - if (Config.StorageType.ToLower() == "sqlite") - { - string sql = Path.Combine(SavePath, "tshock.sqlite"); - DB = new SqliteConnection(string.Format("uri=file://{0},Version=3", sql)); - } - else if (Config.StorageType.ToLower() == "mysql") - { - try - { - var hostport = Config.MySqlHost.Split(':'); - DB = new MySqlConnection(); - DB.ConnectionString = - String.Format("Server={0}; Port={1}; Database={2}; Uid={3}; Pwd={4};", - hostport[0], - hostport.Length > 1 ? hostport[1] : "3306", - Config.MySqlDbName, - Config.MySqlUsername, - Config.MySqlPassword - ); - } - catch (MySqlException ex) - { - Log.Error(ex.ToString()); - throw new Exception("MySql not setup correctly"); - } - } - else - { - throw new Exception("Invalid storage type"); - } + if (Config.StorageType.ToLower() == "sqlite") + { + string sql = Path.Combine(SavePath, "tshock.sqlite"); + DB = new SqliteConnection(string.Format("uri=file://{0},Version=3", sql)); + } + else if (Config.StorageType.ToLower() == "mysql") + { + try + { + var hostport = Config.MySqlHost.Split(':'); + DB = new MySqlConnection(); + DB.ConnectionString = + String.Format("Server={0}; Port={1}; Database={2}; Uid={3}; Pwd={4};", + hostport[0], + hostport.Length > 1 ? hostport[1] : "3306", + Config.MySqlDbName, + Config.MySqlUsername, + Config.MySqlPassword + ); + } + catch (MySqlException ex) + { + Log.Error(ex.ToString()); + throw new Exception("MySql not setup correctly"); + } + } + else + { + throw new Exception("Invalid storage type"); + } - Backups = new BackupManager(Path.Combine(SavePath, "backups")); - Backups.KeepFor = Config.BackupKeepFor; - Backups.Interval = Config.BackupInterval; - Bans = new BanManager(DB); - Warps = new WarpManager(DB); - Users = new UserManager(DB); - Groups = new GroupManager(DB); - Groups.LoadPermisions(); - Regions = new RegionManager(DB); - Itembans = new ItemManager(DB); - RememberedPos = new RemeberedPosManager(DB); - InventoryDB = new InventoryManager(DB); - RestApi = new SecureRest(Netplay.serverListenIP, 8080); - RestApi.Verify += RestApi_Verify; - RestApi.Port = Config.RestApiPort; - RestManager = new RestManager(RestApi); - RestManager.RegisterRestfulCommands(); + Backups = new BackupManager(Path.Combine(SavePath, "backups")); + Backups.KeepFor = Config.BackupKeepFor; + Backups.Interval = Config.BackupInterval; + Bans = new BanManager(DB); + Warps = new WarpManager(DB); + Users = new UserManager(DB); + Groups = new GroupManager(DB); + Groups.LoadPermisions(); + Regions = new RegionManager(DB); + Itembans = new ItemManager(DB); + RememberedPos = new RemeberedPosManager(DB); + InventoryDB = new InventoryManager(DB); + RestApi = new SecureRest(Netplay.serverListenIP, 8080); + RestApi.Verify += RestApi_Verify; + RestApi.Port = Config.RestApiPort; + RestManager = new RestManager(RestApi); + RestManager.RegisterRestfulCommands(); - var geoippath = Path.Combine(SavePath, "GeoIP.dat"); - if (Config.EnableGeoIP && File.Exists(geoippath)) - Geo = new GeoIPCountry(geoippath); + var geoippath = Path.Combine(SavePath, "GeoIP.dat"); + if (Config.EnableGeoIP && File.Exists(geoippath)) + Geo = new GeoIPCountry(geoippath); - Console.Title = string.Format("TerrariaShock Version {0} ({1})", Version, VersionCodename); - Log.ConsoleInfo(string.Format("TerrariaShock Version {0} ({1}) now running.", Version, VersionCodename)); + Console.Title = string.Format("TerrariaShock Version {0} ({1})", Version, VersionCodename); + Log.ConsoleInfo(string.Format("TerrariaShock Version {0} ({1}) now running.", Version, VersionCodename)); - GameHooks.PostInitialize += OnPostInit; - GameHooks.Update += OnUpdate; - ServerHooks.Connect += OnConnect; - ServerHooks.Join += OnJoin; - ServerHooks.Leave += OnLeave; - ServerHooks.Chat += OnChat; - ServerHooks.Command += ServerHooks_OnCommand; - NetHooks.GetData += OnGetData; - NetHooks.SendData += NetHooks_SendData; - NetHooks.GreetPlayer += OnGreetPlayer; - NpcHooks.StrikeNpc += NpcHooks_OnStrikeNpc; - ProjectileHooks.SetDefaults += OnProjectileSetDefaults; - WorldHooks.StartHardMode += OnStartHardMode; + GameHooks.PostInitialize += OnPostInit; + GameHooks.Update += OnUpdate; + ServerHooks.Connect += OnConnect; + ServerHooks.Join += OnJoin; + ServerHooks.Leave += OnLeave; + ServerHooks.Chat += OnChat; + ServerHooks.Command += ServerHooks_OnCommand; + NetHooks.GetData += OnGetData; + NetHooks.SendData += NetHooks_SendData; + NetHooks.GreetPlayer += OnGreetPlayer; + NpcHooks.StrikeNpc += NpcHooks_OnStrikeNpc; + ProjectileHooks.SetDefaults += OnProjectileSetDefaults; + WorldHooks.StartHardMode += OnStartHardMode; - GetDataHandlers.InitGetDataHandler(); - Commands.InitCommands(); - //RconHandler.StartThread(); + GetDataHandlers.InitGetDataHandler(); + Commands.InitCommands(); + //RconHandler.StartThread(); - if (Config.BufferPackets) - PacketBuffer = new PacketBufferer(); + if (Config.BufferPackets) + PacketBuffer = new PacketBufferer(); - Log.ConsoleInfo("AutoSave " + (Config.AutoSave ? "Enabled" : "Disabled")); - Log.ConsoleInfo("Backups " + (Backups.Interval > 0 ? "Enabled" : "Disabled")); + Log.ConsoleInfo("AutoSave " + (Config.AutoSave ? "Enabled" : "Disabled")); + Log.ConsoleInfo("Backups " + (Backups.Interval > 0 ? "Enabled" : "Disabled")); - if (Initialized != null) - Initialized(); - } - catch (Exception ex) - { - Log.Error("Fatal Startup Exception"); - Log.Error(ex.ToString()); - Environment.Exit(1); - } + if (Initialized != null) + Initialized(); + } + catch (Exception ex) + { + Log.Error("Fatal Startup Exception"); + Log.Error(ex.ToString()); + Environment.Exit(1); + } + } - } - + private RestObject RestApi_Verify(string username, string password) + { + var userAccount = Users.GetUserByName(username); + if (userAccount == null) + { + return new RestObject("401") + {Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair."}; + } - RestObject RestApi_Verify(string username, string password) - { - var userAccount = Users.GetUserByName(username); - if (userAccount == null) - { - return new RestObject("401") { Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair." }; - } + if (Utils.HashPassword(password).ToUpper() != userAccount.Password.ToUpper()) + { + return new RestObject("401") + {Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair."}; + } - if (Utils.HashPassword(password).ToUpper() != userAccount.Password.ToUpper()) - { - return new RestObject("401") { Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair." }; - } + if (!Utils.GetGroup(userAccount.Group).HasPermission("api") && userAccount.Group != "superadmin") + { + return new RestObject("403") + { + Error = + "Although your account was successfully found and identified, your account lacks the permission required to use the API. (api)" + }; + } - if (!Utils.GetGroup(userAccount.Group).HasPermission("api") && userAccount.Group != "superadmin") - { - return new RestObject("403") { Error = "Although your account was successfully found and identified, your account lacks the permission required to use the API. (api)" }; - } + return new RestObject("200") {Response = "Successful login"}; //Maybe return some user info too? + } - return new RestObject("200") { Response = "Successful login" }; //Maybe return some user info too? - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { + protected override void Dispose(bool disposing) + { + if (disposing) + { if (Geo != null) { - Geo.Dispose(); + Geo.Dispose(); } - GameHooks.PostInitialize -= OnPostInit; - GameHooks.Update -= OnUpdate; - ServerHooks.Join -= OnJoin; - ServerHooks.Leave -= OnLeave; - ServerHooks.Chat -= OnChat; - ServerHooks.Command -= ServerHooks_OnCommand; - NetHooks.GetData -= OnGetData; - NetHooks.SendData -= NetHooks_SendData; - NetHooks.GreetPlayer -= OnGreetPlayer; - NpcHooks.StrikeNpc -= NpcHooks_OnStrikeNpc; - ProjectileHooks.SetDefaults -= OnProjectileSetDefaults; - if (File.Exists(Path.Combine(SavePath, "tshock.pid"))) - { - File.Delete(Path.Combine(SavePath, "tshock.pid")); - } - RestApi.Dispose(); - Log.Dispose(); - } + GameHooks.PostInitialize -= OnPostInit; + GameHooks.Update -= OnUpdate; + ServerHooks.Join -= OnJoin; + ServerHooks.Leave -= OnLeave; + ServerHooks.Chat -= OnChat; + ServerHooks.Command -= ServerHooks_OnCommand; + NetHooks.GetData -= OnGetData; + NetHooks.SendData -= NetHooks_SendData; + NetHooks.GreetPlayer -= OnGreetPlayer; + NpcHooks.StrikeNpc -= NpcHooks_OnStrikeNpc; + ProjectileHooks.SetDefaults -= OnProjectileSetDefaults; + if (File.Exists(Path.Combine(SavePath, "tshock.pid"))) + { + File.Delete(Path.Combine(SavePath, "tshock.pid")); + } + RestApi.Dispose(); + Log.Dispose(); + } - base.Dispose(disposing); - } + base.Dispose(disposing); + } - /// - /// Handles exceptions that we didn't catch or that Red fucked up - /// - /// - /// - private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) - { - Log.Error(e.ExceptionObject.ToString()); + /// + /// Handles exceptions that we didn't catch or that Red fucked up + /// + /// + /// + private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + Log.Error(e.ExceptionObject.ToString()); - if (e.ExceptionObject.ToString().Contains("Terraria.Netplay.ListenForClients") || - e.ExceptionObject.ToString().Contains("Terraria.Netplay.ServerLoop")) - { - var sb = new List(); - for (int i = 0; i < Netplay.serverSock.Length; i++) - { - if (Netplay.serverSock[i] == null) - { - sb.Add("Sock[" + i + "]"); - } - else if (Netplay.serverSock[i].tcpClient == null) - { - sb.Add("Tcp[" + i + "]"); - } - } - Log.Error(string.Join(", ", sb)); - } + if (e.ExceptionObject.ToString().Contains("Terraria.Netplay.ListenForClients") || + e.ExceptionObject.ToString().Contains("Terraria.Netplay.ServerLoop")) + { + var sb = new List(); + for (int i = 0; i < Netplay.serverSock.Length; i++) + { + if (Netplay.serverSock[i] == null) + { + sb.Add("Sock[" + i + "]"); + } + else if (Netplay.serverSock[i].tcpClient == null) + { + sb.Add("Tcp[" + i + "]"); + } + } + Log.Error(string.Join(", ", sb)); + } - if (e.IsTerminating) - { - if (Main.worldPathName != null && Config.SaveWorldOnCrash) - { - Main.worldPathName += ".crash"; - WorldGen.saveWorld(); - } - } - } + if (e.IsTerminating) + { + if (Main.worldPathName != null && Config.SaveWorldOnCrash) + { + Main.worldPathName += ".crash"; + WorldGen.saveWorld(); + } + } + } - private void HandleCommandLine(string[] parms) - { - for (int i = 0; i < parms.Length; i++) - { - if (parms[i].ToLower() == "-ip") - { - IPAddress ip; - if (IPAddress.TryParse(parms[++i], out ip)) - { - Netplay.serverListenIP = ip; - Console.Write("Using IP: {0}", ip); - } - else - { - Console.WriteLine("Bad IP: {0}", parms[i]); - } - } - if (parms[i].ToLower() == "-configpath") - { - var path = parms[++i]; - if (path.IndexOfAny(Path.GetInvalidPathChars()) == -1) - { - SavePath = path; - Log.ConsoleInfo("Config path has been set to " + path); - } - } - if (parms[i].ToLower() == "-worldpath") - { - var path = parms[++i]; - if (path.IndexOfAny(Path.GetInvalidPathChars()) == -1) - { - Main.WorldPath = path; - Log.ConsoleInfo("World path has been set to " + path); - } - } - } - } + private void HandleCommandLine(string[] parms) + { + for (int i = 0; i < parms.Length; i++) + { + if (parms[i].ToLower() == "-ip") + { + IPAddress ip; + if (IPAddress.TryParse(parms[++i], out ip)) + { + Netplay.serverListenIP = ip; + Console.Write("Using IP: {0}", ip); + } + else + { + Console.WriteLine("Bad IP: {0}", parms[i]); + } + } + if (parms[i].ToLower() == "-configpath") + { + var path = parms[++i]; + if (path.IndexOfAny(Path.GetInvalidPathChars()) == -1) + { + SavePath = path; + Log.ConsoleInfo("Config path has been set to " + path); + } + } + if (parms[i].ToLower() == "-worldpath") + { + var path = parms[++i]; + if (path.IndexOfAny(Path.GetInvalidPathChars()) == -1) + { + Main.WorldPath = path; + Log.ConsoleInfo("World path has been set to " + path); + } + } + } + } - private void HandleCommandLine_Port(string[] parms) - { - for (int i = 0; i < parms.Length; i++) - { - if (parms[i].ToLower() == "-port") - { - int port = Convert.ToInt32(parms[++i]); - Netplay.serverPort = port; - Config.ServerPort = port; - OverridePort = true; - Log.ConsoleInfo("Port overridden by startup argument. Set to " + port); - } - } - } + private void HandleCommandLine_Port(string[] parms) + { + for (int i = 0; i < parms.Length; i++) + { + if (parms[i].ToLower() == "-port") + { + int port = Convert.ToInt32(parms[++i]); + Netplay.serverPort = port; + Config.ServerPort = port; + OverridePort = true; + Log.ConsoleInfo("Port overridden by startup argument. Set to " + port); + } + } + } - /* + /* * Hooks: * */ - public static int AuthToken = -1; + public static int AuthToken = -1; + + private void OnPostInit() + { + if (!File.Exists(Path.Combine(SavePath, "auth.lck")) && !File.Exists(Path.Combine(SavePath, "authcode.txt"))) + { + var r = new Random((int) DateTime.Now.ToBinary()); + AuthToken = r.Next(100000, 10000000); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine("TShock Notice: To become SuperAdmin, join the game and type /auth " + AuthToken); + Console.WriteLine("This token will display until disabled by verification. (/auth-verify)"); + Console.ForegroundColor = ConsoleColor.Gray; + FileTools.CreateFile(Path.Combine(SavePath, "authcode.txt")); + using (var tw = new StreamWriter(Path.Combine(SavePath, "authcode.txt"))) + { + tw.WriteLine(AuthToken); + } + } + else if (File.Exists(Path.Combine(SavePath, "authcode.txt"))) + { + using (var tr = new StreamReader(Path.Combine(SavePath, "authcode.txt"))) + { + AuthToken = Convert.ToInt32(tr.ReadLine()); + } + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine( + "TShock Notice: authcode.txt is still present, and the AuthToken located in that file will be used."); + Console.WriteLine("To become superadmin, join the game and type /auth " + AuthToken); + Console.WriteLine("This token will display until disabled by verification. (/auth-verify)"); + Console.ForegroundColor = ConsoleColor.Gray; + } + else + { + AuthToken = 0; + } + Regions.ReloadAllRegions(); + if (Config.RestApiEnabled) + RestApi.Start(); - private void OnPostInit() - { - if (!File.Exists(Path.Combine(SavePath, "auth.lck")) && !File.Exists(Path.Combine(SavePath, "authcode.txt"))) - { - var r = new Random((int)DateTime.Now.ToBinary()); - AuthToken = r.Next(100000, 10000000); - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine("TShock Notice: To become SuperAdmin, join the game and type /auth " + AuthToken); - Console.WriteLine("This token will display until disabled by verification. (/auth-verify)"); - Console.ForegroundColor = ConsoleColor.Gray; - FileTools.CreateFile(Path.Combine(SavePath, "authcode.txt")); - using (var tw = new StreamWriter(Path.Combine(SavePath, "authcode.txt"))) - { - tw.WriteLine(AuthToken); - } - } - else if (File.Exists(Path.Combine(SavePath, "authcode.txt"))) - { - using (var tr = new StreamReader(Path.Combine(SavePath, "authcode.txt"))) - { - AuthToken = Convert.ToInt32(tr.ReadLine()); - } - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine("TShock Notice: authcode.txt is still present, and the AuthToken located in that file will be used."); - Console.WriteLine("To become superadmin, join the game and type /auth " + AuthToken); - Console.WriteLine("This token will display until disabled by verification. (/auth-verify)"); - Console.ForegroundColor = ConsoleColor.Gray; - } - else - { - AuthToken = 0; - } - Regions.ReloadAllRegions(); - if (Config.RestApiEnabled) - RestApi.Start(); - StatTracker.checkin(); - FixChestStacks(); + FixChestStacks(); + } - } - - private void FixChestStacks() - { - foreach(Chest chest in Main.chest) - { + private void FixChestStacks() + { + foreach (Chest chest in Main.chest) + { if (chest != null) { foreach (Item item in chest.item) @@ -431,877 +436,904 @@ namespace TShockAPI item.stack = item.maxStack; } } - } - } + } + } - private DateTime LastCheck = DateTime.UtcNow; - private DateTime LastSave = DateTime.UtcNow; + private DateTime LastCheck = DateTime.UtcNow; + private DateTime LastSave = DateTime.UtcNow; - private void OnUpdate() - { - UpdateManager.UpdateProcedureCheck(); + private void OnUpdate() + { + UpdateManager.UpdateProcedureCheck(); StatTracker.checkin(); - if (Backups.IsBackupTime) - Backups.Backup(); + if (Backups.IsBackupTime) + Backups.Backup(); - //call these every second, not every update - if ((DateTime.UtcNow - LastCheck).TotalSeconds >= 1) - { - OnSecondUpdate(); - LastCheck = DateTime.UtcNow; - } + //call these every second, not every update + if ((DateTime.UtcNow - LastCheck).TotalSeconds >= 1) + { + OnSecondUpdate(); + LastCheck = DateTime.UtcNow; + } - if ((DateTime.UtcNow - LastSave).TotalMinutes >= 15) - { - foreach (TSPlayer player in Players) - { - // prevent null point exceptions - if (player != null && player.IsLoggedIn) - { - InventoryDB.InsertPlayerData(player); - } - } - LastSave = DateTime.UtcNow; - } - } + if ((DateTime.UtcNow - LastSave).TotalMinutes >= 15) + { + foreach (TSPlayer player in Players) + { + // prevent null point exceptions + if (player != null && player.IsLoggedIn) + { + InventoryDB.InsertPlayerData(player); + } + } + LastSave = DateTime.UtcNow; + } + } - private void OnSecondUpdate() - { - if (Config.ForceTime != "normal") - { - switch(Config.ForceTime) - { - case "day": - TSPlayer.Server.SetTime(true, 27000.0); - break; - case "night": - TSPlayer.Server.SetTime(false, 16200.0); - break; - } - } - int count = 0; - foreach (TSPlayer player in Players) - { - if (player != null && player.Active) - { - count++; - if (player.TilesDestroyed != null) - { - if (player.TileKillThreshold >= Config.TileKillThreshold) - { - player.Disable(); - TSPlayer.Server.RevertTiles(player.TilesDestroyed); - player.TilesDestroyed.Clear(); - } - } - if (player.TileKillThreshold > 0) - { - player.TileKillThreshold = 0; - } - if (player.TilesCreated != null) - { - if (player.TilePlaceThreshold >= Config.TilePlaceThreshold) - { - player.Disable(); - TSPlayer.Server.RevertTiles(player.TilesCreated); - player.TilesCreated.Clear(); - } - } - if (player.TilePlaceThreshold > 0) - { - player.TilePlaceThreshold = 0; - } - if(player.TileLiquidThreshold >= Config.TileLiquidThreshold) - { - player.Disable(); - } - if (player.TileLiquidThreshold > 0) - { - player.TileLiquidThreshold = 0; - } - if (player.ProjectileThreshold >= Config.ProjectileThreshold) - { - player.Disable(); - } - if (player.ProjectileThreshold > 0) - { - player.ProjectileThreshold = 0; - } - if (player.Dead && (DateTime.Now - player.LastDeath).Seconds >= 3 && player.Difficulty != 2) - { - player.Spawn(); - } - string check = "none"; - foreach (Item item in player.TPlayer.inventory) - { - if (!player.Group.HasPermission(Permissions.ignorestackhackdetection) && item.stack > item.maxStack && item.type != 0) - { - check = "Remove Item " + item.name + " (" + item.stack + ") exceeds max stack of " + item.maxStack; - } - } - player.IgnoreActionsForCheating = check; - check = "none"; - foreach (Item item in player.TPlayer.armor) - { - if (!player.Group.HasPermission(Permissions.usebanneditem) && Itembans.ItemIsBanned(item.name, player)) - { - player.SetBuff(30, 120); //Bleeding - player.SetBuff(36, 120); //Broken Armor - check = "Remove Armor/Accessory " + item.name; - } - } - player.IgnoreActionsForDisabledArmor = check; - if (CheckIgnores(player)) - { - player.SetBuff(33, 120); //Weak - player.SetBuff(32, 120); //Slow - player.SetBuff(23, 120); //Cursed - } - else if(!player.Group.HasPermission(Permissions.usebanneditem) && Itembans.ItemIsBanned(player.TPlayer.inventory[player.TPlayer.selectedItem].name, player)) - { - player.SetBuff(23, 120); //Cursed - } - } - } - Console.Title = string.Format("TerrariaShock Version {0} ({1}) ({2}/{3})", Version, VersionCodename, count, Config.MaxSlots); - } + private void OnSecondUpdate() + { + if (Config.ForceTime != "normal") + { + switch (Config.ForceTime) + { + case "day": + TSPlayer.Server.SetTime(true, 27000.0); + break; + case "night": + TSPlayer.Server.SetTime(false, 16200.0); + break; + } + } + int count = 0; + foreach (TSPlayer player in Players) + { + if (player != null && player.Active) + { + count++; + if (player.TilesDestroyed != null) + { + if (player.TileKillThreshold >= Config.TileKillThreshold) + { + player.Disable(); + TSPlayer.Server.RevertTiles(player.TilesDestroyed); + player.TilesDestroyed.Clear(); + } + } + if (player.TileKillThreshold > 0) + { + player.TileKillThreshold = 0; + } + if (player.TilesCreated != null) + { + if (player.TilePlaceThreshold >= Config.TilePlaceThreshold) + { + player.Disable(); + TSPlayer.Server.RevertTiles(player.TilesCreated); + player.TilesCreated.Clear(); + } + } + if (player.TilePlaceThreshold > 0) + { + player.TilePlaceThreshold = 0; + } + if (player.TileLiquidThreshold >= Config.TileLiquidThreshold) + { + player.Disable(); + } + if (player.TileLiquidThreshold > 0) + { + player.TileLiquidThreshold = 0; + } + if (player.ProjectileThreshold >= Config.ProjectileThreshold) + { + player.Disable(); + } + if (player.ProjectileThreshold > 0) + { + player.ProjectileThreshold = 0; + } + if (player.Dead && (DateTime.Now - player.LastDeath).Seconds >= 3 && player.Difficulty != 2) + { + player.Spawn(); + } + string check = "none"; + foreach (Item item in player.TPlayer.inventory) + { + if (!player.Group.HasPermission(Permissions.ignorestackhackdetection) && item.stack > item.maxStack && + item.type != 0) + { + check = "Remove Item " + item.name + " (" + item.stack + ") exceeds max stack of " + item.maxStack; + } + } + player.IgnoreActionsForCheating = check; + check = "none"; + foreach (Item item in player.TPlayer.armor) + { + if (!player.Group.HasPermission(Permissions.usebanneditem) && Itembans.ItemIsBanned(item.name, player)) + { + player.SetBuff(30, 120); //Bleeding + player.SetBuff(36, 120); //Broken Armor + check = "Remove Armor/Accessory " + item.name; + } + } + player.IgnoreActionsForDisabledArmor = check; + if (CheckIgnores(player)) + { + player.SetBuff(33, 120); //Weak + player.SetBuff(32, 120); //Slow + player.SetBuff(23, 120); //Cursed + } + else if (!player.Group.HasPermission(Permissions.usebanneditem) && + Itembans.ItemIsBanned(player.TPlayer.inventory[player.TPlayer.selectedItem].name, player)) + { + player.SetBuff(23, 120); //Cursed + } + } + } + Console.Title = string.Format("TerrariaShock Version {0} ({1}) ({2}/{3})", Version, VersionCodename, count, + Config.MaxSlots); + } - private void OnConnect(int ply, HandledEventArgs handler) - { - var player = new TSPlayer(ply); - if (Config.EnableDNSHostResolution) - { - player.Group = Users.GetGroupForIPExpensive(player.IP); - } - else - { - player.Group = Users.GetGroupForIP(player.IP); - } + private void OnConnect(int ply, HandledEventArgs handler) + { + var player = new TSPlayer(ply); + if (Config.EnableDNSHostResolution) + { + player.Group = Users.GetGroupForIPExpensive(player.IP); + } + else + { + player.Group = Users.GetGroupForIP(player.IP); + } - if (Utils.ActivePlayers() + 1 > Config.MaxSlots + 20) - { - Utils.ForceKick(player, Config.ServerFullNoReservedReason); - handler.Handled = true; - return; - } + if (Utils.ActivePlayers() + 1 > Config.MaxSlots + 20) + { + Utils.ForceKick(player, Config.ServerFullNoReservedReason); + handler.Handled = true; + return; + } - var ipban = Bans.GetBanByIp(player.IP); - Ban ban = null; - if (ipban != null && Config.EnableIPBans) - ban = ipban; + var ipban = Bans.GetBanByIp(player.IP); + Ban ban = null; + if (ipban != null && Config.EnableIPBans) + ban = ipban; - if (ban != null) - { - Utils.ForceKick(player, string.Format("You are banned: {0}", ban.Reason)); - handler.Handled = true; - return; - } + if (ban != null) + { + Utils.ForceKick(player, string.Format("You are banned: {0}", ban.Reason)); + handler.Handled = true; + return; + } - if (!FileTools.OnWhitelist(player.IP)) - { - Utils.ForceKick(player, "Not on whitelist."); - handler.Handled = true; - return; - } + if (!FileTools.OnWhitelist(player.IP)) + { + Utils.ForceKick(player, "Not on whitelist."); + handler.Handled = true; + return; + } - if (Geo != null) - { - var code = Geo.TryGetCountryCode(IPAddress.Parse(player.IP)); - player.Country = code == null ? "N/A" : GeoIPCountry.GetCountryNameByCode(code); - if (code == "A1") - { - if (Config.KickProxyUsers) - { - Utils.ForceKick(player, "Proxies are not allowed"); - handler.Handled = true; - return; - } - } - } - Players[ply] = player; - } + if (Geo != null) + { + var code = Geo.TryGetCountryCode(IPAddress.Parse(player.IP)); + player.Country = code == null ? "N/A" : GeoIPCountry.GetCountryNameByCode(code); + if (code == "A1") + { + if (Config.KickProxyUsers) + { + Utils.ForceKick(player, "Proxies are not allowed"); + handler.Handled = true; + return; + } + } + } + Players[ply] = player; + } - private void OnJoin(int ply, HandledEventArgs handler) - { - var player = Players[ply]; - if (player == null) - { - handler.Handled = true; - return; - } + private void OnJoin(int ply, HandledEventArgs handler) + { + var player = Players[ply]; + if (player == null) + { + handler.Handled = true; + return; + } - var nameban = Bans.GetBanByName(player.Name); - Ban ban = null; - if (nameban != null && Config.EnableBanOnUsernames) - ban = nameban; + var nameban = Bans.GetBanByName(player.Name); + Ban ban = null; + if (nameban != null && Config.EnableBanOnUsernames) + ban = nameban; - if (ban != null) - { - Utils.ForceKick(player, string.Format("You are banned: {0}", ban.Reason)); - handler.Handled = true; - return; - } - } + if (ban != null) + { + Utils.ForceKick(player, string.Format("You are banned: {0}", ban.Reason)); + handler.Handled = true; + return; + } + } - private void OnLeave(int ply) - { - var tsplr = Players[ply]; - Players[ply] = null; + private void OnLeave(int ply) + { + var tsplr = Players[ply]; + Players[ply] = null; - if (tsplr != null && tsplr.ReceivedInfo) - { - Utils.Broadcast(tsplr.Name + " has left", Color.Yellow); - Log.Info(string.Format("{0} left.", tsplr.Name)); + if (tsplr != null && tsplr.ReceivedInfo) + { + Utils.Broadcast(tsplr.Name + " has left", Color.Yellow); + Log.Info(string.Format("{0} left.", tsplr.Name)); - if (tsplr.IsLoggedIn) - { - tsplr.PlayerData.CopyInventory(tsplr); - InventoryDB.InsertPlayerData(tsplr); - } + if (tsplr.IsLoggedIn) + { + tsplr.PlayerData.CopyInventory(tsplr); + InventoryDB.InsertPlayerData(tsplr); + } - if (Config.RememberLeavePos) - { - RememberedPos.InsertLeavePos(tsplr.Name, tsplr.IP, (int)(tsplr.X / 16), (int)(tsplr.Y / 16)); - } - } - } + if (Config.RememberLeavePos) + { + RememberedPos.InsertLeavePos(tsplr.Name, tsplr.IP, (int) (tsplr.X/16), (int) (tsplr.Y/16)); + } + } + } - private void OnChat(messageBuffer msg, int ply, string text, HandledEventArgs e) - { - if (e.Handled) - return; + private void OnChat(messageBuffer msg, int ply, string text, HandledEventArgs e) + { + if (e.Handled) + return; - var tsplr = Players[msg.whoAmI]; - if (tsplr == null) - { - e.Handled = true; - return; - } + var tsplr = Players[msg.whoAmI]; + if (tsplr == null) + { + e.Handled = true; + return; + } - if (!Utils.ValidString(text)) - { - e.Handled = true; - return; - } + if (!Utils.ValidString(text)) + { + e.Handled = true; + return; + } - if (text.StartsWith("/")) - { - try - { - e.Handled = Commands.HandleCommand(tsplr, text); - } - catch (Exception ex) - { - Log.ConsoleError("Command exception"); - Log.Error(ex.ToString()); - } - } - else if (!tsplr.mute) - { - Utils.Broadcast(String.Format(Config.ChatFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix, text), tsplr.Group.R, tsplr.Group.G, tsplr.Group.B); - e.Handled = true; - } - else if (tsplr.mute) - { - tsplr.SendMessage("You are muted!"); - e.Handled = true; - } - } + if (text.StartsWith("/")) + { + try + { + e.Handled = Commands.HandleCommand(tsplr, text); + } + catch (Exception ex) + { + Log.ConsoleError("Command exception"); + Log.Error(ex.ToString()); + } + } + else if (!tsplr.mute) + { + Utils.Broadcast( + String.Format(Config.ChatFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix, text), + tsplr.Group.R, tsplr.Group.G, tsplr.Group.B); + e.Handled = true; + } + else if (tsplr.mute) + { + tsplr.SendMessage("You are muted!"); + e.Handled = true; + } + } - /// - /// When a server command is run. - /// - /// - /// - private void ServerHooks_OnCommand(string text, HandledEventArgs e) - { - if (e.Handled) - return; + /// + /// When a server command is run. + /// + /// + /// + private void ServerHooks_OnCommand(string text, HandledEventArgs e) + { + if (e.Handled) + return; - // Damn you ThreadStatic and Redigit - if (Main.rand == null) - { - Main.rand = new Random(); - } - if (WorldGen.genRand == null) - { - WorldGen.genRand = new Random(); - } + // Damn you ThreadStatic and Redigit + if (Main.rand == null) + { + Main.rand = new Random(); + } + if (WorldGen.genRand == null) + { + WorldGen.genRand = new Random(); + } - if (text.StartsWith("playing") || text.StartsWith("/playing")) - { - int count = 0; - foreach (TSPlayer player in Players) - { - if (player != null && player.Active) - { - count++; - TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}] <{3}>", player.Name, player.IP, - player.Group.Name, player.UserAccountName)); - } - } - TSPlayer.Server.SendMessage(string.Format("{0} players connected.", count)); - } - else if (text == "autosave") - { - Main.autoSave = Config.AutoSave = !Config.AutoSave; - Log.ConsoleInfo("AutoSave " + (Config.AutoSave ? "Enabled" : "Disabled")); - } - else if (text.StartsWith("/")) - { - Commands.HandleCommand(TSPlayer.Server, text); - } - else - { - Commands.HandleCommand(TSPlayer.Server, "/" + text); - } - e.Handled = true; - } + if (text.StartsWith("playing") || text.StartsWith("/playing")) + { + int count = 0; + foreach (TSPlayer player in Players) + { + if (player != null && player.Active) + { + count++; + TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}] <{3}>", player.Name, player.IP, + player.Group.Name, player.UserAccountName)); + } + } + TSPlayer.Server.SendMessage(string.Format("{0} players connected.", count)); + } + else if (text == "autosave") + { + Main.autoSave = Config.AutoSave = !Config.AutoSave; + Log.ConsoleInfo("AutoSave " + (Config.AutoSave ? "Enabled" : "Disabled")); + } + else if (text.StartsWith("/")) + { + Commands.HandleCommand(TSPlayer.Server, text); + } + else + { + Commands.HandleCommand(TSPlayer.Server, "/" + text); + } + e.Handled = true; + } - private void OnGetData(GetDataEventArgs e) - { - if (e.Handled) - return; + private void OnGetData(GetDataEventArgs e) + { + if (e.Handled) + return; - PacketTypes type = e.MsgID; + PacketTypes type = e.MsgID; - Debug.WriteLine("Recv: {0:X}: {2} ({1:XX})", e.Msg.whoAmI, (byte)type, type); + Debug.WriteLine("Recv: {0:X}: {2} ({1:XX})", e.Msg.whoAmI, (byte) type, type); - var player = Players[e.Msg.whoAmI]; - if (player == null) - { - e.Handled = true; - return; - } + var player = Players[e.Msg.whoAmI]; + if (player == null) + { + e.Handled = true; + return; + } - if (!player.ConnectionAlive) - { - e.Handled = true; - return; - } + if (!player.ConnectionAlive) + { + e.Handled = true; + return; + } - if (player.RequiresPassword && type != PacketTypes.PasswordSend) - { - e.Handled = true; - return; - } + if (player.RequiresPassword && type != PacketTypes.PasswordSend) + { + e.Handled = true; + return; + } - if ((player.State < 10 || player.Dead) && (int)type > 12 && (int)type != 16 && (int)type != 42 && (int)type != 50 && (int)type != 38) - { - e.Handled = true; - return; - } + if ((player.State < 10 || player.Dead) && (int) type > 12 && (int) type != 16 && (int) type != 42 && (int) type != 50 && + (int) type != 38) + { + e.Handled = true; + return; + } - using (var data = new MemoryStream(e.Msg.readBuffer, e.Index, e.Length)) - { - try - { - if (GetDataHandlers.HandlerGetData(type, player, data)) - e.Handled = true; - } - catch (Exception ex) - { - Log.Error(ex.ToString()); - } - } - } + using (var data = new MemoryStream(e.Msg.readBuffer, e.Index, e.Length)) + { + try + { + if (GetDataHandlers.HandlerGetData(type, player, data)) + e.Handled = true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } + } - private void OnGreetPlayer(int who, HandledEventArgs e) - { - var player = Players[who]; - if (player == null) - { - e.Handled = true; - return; - } + private void OnGreetPlayer(int who, HandledEventArgs e) + { + var player = Players[who]; + if (player == null) + { + e.Handled = true; + return; + } - Utils.ShowFileToUser(player, "motd.txt"); + Utils.ShowFileToUser(player, "motd.txt"); - if (Config.PvPMode == "always" && !player.TPlayer.hostile) - { - player.SendMessage("PvP is forced! Enable PvP else you can't move or do anything!", Color.Red); - } + if (Config.PvPMode == "always" && !player.TPlayer.hostile) + { + player.SendMessage("PvP is forced! Enable PvP else you can't move or do anything!", Color.Red); + } - if (!player.IsLoggedIn) - { - if (Config.ServerSideInventory) - { - player.SendMessage(player.IgnoreActionsForInventory = "Server Side Inventory is enabled! Please /register or /login to play!", Color.Red); - } - else if (Config.RequireLogin) - { - player.SendMessage("Please /register or /login to play!", Color.Red); - } - } + if (!player.IsLoggedIn) + { + if (Config.ServerSideInventory) + { + player.SendMessage( + player.IgnoreActionsForInventory = "Server Side Inventory is enabled! Please /register or /login to play!", + Color.Red); + } + else if (Config.RequireLogin) + { + player.SendMessage("Please /register or /login to play!", Color.Red); + } + } - if (player.Group.HasPermission(Permissions.causeevents) && Config.InfiniteInvasion) - { - StartInvasion(); - } + if (player.Group.HasPermission(Permissions.causeevents) && Config.InfiniteInvasion) + { + StartInvasion(); + } - player.LastNetPosition = new Vector2(Main.spawnTileX * 16f, Main.spawnTileY * 16f); + player.LastNetPosition = new Vector2(Main.spawnTileX*16f, Main.spawnTileY*16f); - if (Config.RememberLeavePos) - { - var pos = RememberedPos.GetLeavePos(player.Name, player.IP); - player.LastNetPosition = pos; - player.Teleport((int) pos.X, (int) pos.Y + 3); - } + if (Config.RememberLeavePos) + { + var pos = RememberedPos.GetLeavePos(player.Name, player.IP); + player.LastNetPosition = pos; + player.Teleport((int) pos.X, (int) pos.Y + 3); + } - e.Handled = true; - } + e.Handled = true; + } - private void NpcHooks_OnStrikeNpc(NpcStrikeEventArgs e) - { - if (Config.InfiniteInvasion) - { - IncrementKills(); - if (Main.invasionSize < 10) - { - Main.invasionSize = 20000000; - } - } - } + private void NpcHooks_OnStrikeNpc(NpcStrikeEventArgs e) + { + if (Config.InfiniteInvasion) + { + IncrementKills(); + if (Main.invasionSize < 10) + { + Main.invasionSize = 20000000; + } + } + } - void OnProjectileSetDefaults(SetDefaultsEventArgs e) - { - if (e.Info == 43) - if (Config.DisableTombstones) - e.Object.SetDefaults(0); - if (e.Info == 75) - if (Config.DisableClownBombs) - e.Object.SetDefaults(0); - if (e.Info == 109) - if (Config.DisableSnowBalls) - e.Object.SetDefaults(0); + private void OnProjectileSetDefaults(SetDefaultsEventArgs e) + { + if (e.Info == 43) + if (Config.DisableTombstones) + e.Object.SetDefaults(0); + if (e.Info == 75) + if (Config.DisableClownBombs) + e.Object.SetDefaults(0); + if (e.Info == 109) + if (Config.DisableSnowBalls) + e.Object.SetDefaults(0); + } - } + private void OnNpcSetDefaults(SetDefaultsEventArgs e) + { + if (Itembans.ItemIsBanned(e.Object.name, null)) + { + e.Object.SetDefaults(0); + } + } - void OnNpcSetDefaults(SetDefaultsEventArgs e) - { - if (Itembans.ItemIsBanned(e.Object.name, null) ) - { - e.Object.SetDefaults(0); - } - } + /// + /// Send bytes to client using packetbuffering if available + /// + /// socket to send to + /// bytes to send + /// False on exception + public static bool SendBytes(ServerSock client, byte[] bytes) + { + if (PacketBuffer != null) + { + PacketBuffer.BufferBytes(client, bytes); + return true; + } - /// - /// Send bytes to client using packetbuffering if available - /// - /// socket to send to - /// bytes to send - /// False on exception - public static bool SendBytes(ServerSock client, byte[] bytes) - { - if (PacketBuffer != null) - { - PacketBuffer.BufferBytes(client, bytes); - return true; - } + return SendBytesBufferless(client, bytes); + } - return SendBytesBufferless(client,bytes); - } - /// - /// Send bytes to a client ignoring the packet buffer - /// - /// socket to send to - /// bytes to send - /// False on exception - public static bool SendBytesBufferless(ServerSock client, byte[] bytes) - { - try - { - if (client.tcpClient.Connected) - client.networkStream.Write(bytes, 0, bytes.Length); - return true; - } - catch (Exception ex) - { - Log.Warn("This is a normal exception"); - Log.Warn(ex.ToString()); - } - return false; - } + /// + /// Send bytes to a client ignoring the packet buffer + /// + /// socket to send to + /// bytes to send + /// False on exception + public static bool SendBytesBufferless(ServerSock client, byte[] bytes) + { + try + { + if (client.tcpClient.Connected) + client.networkStream.Write(bytes, 0, bytes.Length); + return true; + } + catch (Exception ex) + { + Log.Warn("This is a normal exception"); + Log.Warn(ex.ToString()); + } + return false; + } - void NetHooks_SendData(SendDataEventArgs e) - { - if (e.MsgID == PacketTypes.Disconnect) - { - Action senddisconnect = (sock, str) => - { - if (sock == null || !sock.active) - return; - sock.kill = true; - using (var ms = new MemoryStream()) - { - new DisconnectMsg {Reason = str}.PackFull(ms); - SendBytesBufferless(sock, ms.ToArray()); - } - }; + private void NetHooks_SendData(SendDataEventArgs e) + { + if (e.MsgID == PacketTypes.Disconnect) + { + Action senddisconnect = (sock, str) => + { + if (sock == null || !sock.active) + return; + sock.kill = true; + using (var ms = new MemoryStream()) + { + new DisconnectMsg {Reason = str}.PackFull(ms); + SendBytesBufferless(sock, ms.ToArray()); + } + }; - if (e.remoteClient != -1) - { - senddisconnect(Netplay.serverSock[e.remoteClient], e.text); - } - else - { - for (int i = 0; i < Netplay.serverSock.Length; i++) - { - if (e.ignoreClient != -1 && e.ignoreClient == i) - continue; + if (e.remoteClient != -1) + { + senddisconnect(Netplay.serverSock[e.remoteClient], e.text); + } + else + { + for (int i = 0; i < Netplay.serverSock.Length; i++) + { + if (e.ignoreClient != -1 && e.ignoreClient == i) + continue; - senddisconnect(Netplay.serverSock[i], e.text); - } - } - e.Handled = true; - } - } + senddisconnect(Netplay.serverSock[i], e.text); + } + } + e.Handled = true; + } + } - private void OnSaveWorld(bool resettime, HandledEventArgs e) - { - Utils.Broadcast("Saving world. Momentary lag might result from this.", Color.Red); - Thread SaveWorld = new Thread(Utils.SaveWorld); - SaveWorld.Start(); - e.Handled = true; - } + private void OnSaveWorld(bool resettime, HandledEventArgs e) + { + Utils.Broadcast("Saving world. Momentary lag might result from this.", Color.Red); + Thread SaveWorld = new Thread(Utils.SaveWorld); + SaveWorld.Start(); + e.Handled = true; + } - void OnStartHardMode(HandledEventArgs e) - { - if (Config.DisableHardmode) - e.Handled = true; - } + private void OnStartHardMode(HandledEventArgs e) + { + if (Config.DisableHardmode) + e.Handled = true; + } - /* + /* * Useful stuff: * */ - public static void StartInvasion() - { - Main.invasionType = 1; - if (Config.InfiniteInvasion) - { - Main.invasionSize = 20000000; - } - else - { - Main.invasionSize = 100 + (Config.InvasionMultiplier * Utils.ActivePlayers()); - } + public static void StartInvasion() + { + Main.invasionType = 1; + if (Config.InfiniteInvasion) + { + Main.invasionSize = 20000000; + } + else + { + Main.invasionSize = 100 + (Config.InvasionMultiplier*Utils.ActivePlayers()); + } - Main.invasionWarn = 0; - if (new Random().Next(2) == 0) - { - Main.invasionX = 0.0; - } - else - { - Main.invasionX = Main.maxTilesX; - } - } + Main.invasionWarn = 0; + if (new Random().Next(2) == 0) + { + Main.invasionX = 0.0; + } + else + { + Main.invasionX = Main.maxTilesX; + } + } - private static int KillCount; + private static int KillCount; - public static void IncrementKills() - { - KillCount++; - Random r = new Random(); - int random = r.Next(5); - if (KillCount % 100 == 0) - { - switch (random) - { - case 0: - Utils.Broadcast(string.Format("You call that a lot? {0} goblins killed!", KillCount)); - break; - case 1: - Utils.Broadcast(string.Format("Fatality! {0} goblins killed!", KillCount)); - break; - case 2: - Utils.Broadcast(string.Format("Number of 'noobs' killed to date: {0}", KillCount)); - break; - case 3: - Utils.Broadcast(string.Format("Duke Nukem would be proud. {0} goblins killed.", KillCount)); - break; - case 4: - Utils.Broadcast(string.Format("You call that a lot? {0} goblins killed!", KillCount)); - break; - case 5: - Utils.Broadcast(string.Format("{0} copies of Call of Duty smashed.", KillCount)); - break; - } - } - } + public static void IncrementKills() + { + KillCount++; + Random r = new Random(); + int random = r.Next(5); + if (KillCount%100 == 0) + { + switch (random) + { + case 0: + Utils.Broadcast(string.Format("You call that a lot? {0} goblins killed!", KillCount)); + break; + case 1: + Utils.Broadcast(string.Format("Fatality! {0} goblins killed!", KillCount)); + break; + case 2: + Utils.Broadcast(string.Format("Number of 'noobs' killed to date: {0}", KillCount)); + break; + case 3: + Utils.Broadcast(string.Format("Duke Nukem would be proud. {0} goblins killed.", KillCount)); + break; + case 4: + Utils.Broadcast(string.Format("You call that a lot? {0} goblins killed!", KillCount)); + break; + case 5: + Utils.Broadcast(string.Format("{0} copies of Call of Duty smashed.", KillCount)); + break; + } + } + } - public static bool CheckProjectilePermission(TSPlayer player, int index, int type) - { - if (type == 43) - { - return true; - } + public static bool CheckProjectilePermission(TSPlayer player, int index, int type) + { + if (type == 43) + { + return true; + } - if (type == 17 && !player.Group.HasPermission(Permissions.usebanneditem) && Itembans.ItemIsBanned("Dirt Rod", player)) //Dirt Rod Projectile - { - return true; - } + if (type == 17 && !player.Group.HasPermission(Permissions.usebanneditem) && Itembans.ItemIsBanned("Dirt Rod", player)) + //Dirt Rod Projectile + { + return true; + } - if ((type == 42 || type == 65 || type == 68) && !player.Group.HasPermission(Permissions.usebanneditem) && Itembans.ItemIsBanned("Sandgun", player)) //Sandgun Projectiles - { - return true; - } + if ((type == 42 || type == 65 || type == 68) && !player.Group.HasPermission(Permissions.usebanneditem) && + Itembans.ItemIsBanned("Sandgun", player)) //Sandgun Projectiles + { + return true; + } - Projectile proj = new Projectile(); - proj.SetDefaults(type); + Projectile proj = new Projectile(); + proj.SetDefaults(type); - if (!player.Group.HasPermission(Permissions.usebanneditem) && Itembans.ItemIsBanned(proj.name, player)) - { - return true; - } + if (!player.Group.HasPermission(Permissions.usebanneditem) && Itembans.ItemIsBanned(proj.name, player)) + { + return true; + } - if (proj.hostile) - { - return true; - } + if (proj.hostile) + { + return true; + } - return false; - } + return false; + } - public static bool CheckRangePermission(TSPlayer player, int x, int y, int range = 32) - { - if (Config.RangeChecks && ((Math.Abs(player.TileX - x) > 32) || (Math.Abs(player.TileY - y) > 32))) - { - return true; - } - return false; - } + public static bool CheckRangePermission(TSPlayer player, int x, int y, int range = 32) + { + if (Config.RangeChecks && ((Math.Abs(player.TileX - x) > 32) || (Math.Abs(player.TileY - y) > 32))) + { + return true; + } + return false; + } - public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY) - { - if (!player.Group.HasPermission(Permissions.canbuild)) - { - player.SendMessage("You do not have permission to build!", Color.Red); - return true; - } - if (!player.Group.HasPermission(Permissions.editspawn) && !Regions.CanBuild(tileX, tileY, player) && Regions.InArea(tileX, tileY)) - { - player.SendMessage("Region protected from changes.", Color.Red); - return true; - } - if (Config.DisableBuild) - { - if (!player.Group.HasPermission(Permissions.editspawn)) - { - player.SendMessage("World protected from changes.", Color.Red); - return true; - } - } - if (Config.SpawnProtection) - { - if (!player.Group.HasPermission(Permissions.editspawn)) - { - var flag = CheckSpawn(tileX, tileY); - if (flag) - { - player.SendMessage("Spawn protected from changes.", Color.Red); - return true; - } - } - } - return false; - } + public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY) + { + if (!player.Group.HasPermission(Permissions.canbuild)) + { + player.SendMessage("You do not have permission to build!", Color.Red); + return true; + } + if (!player.Group.HasPermission(Permissions.editspawn) && !Regions.CanBuild(tileX, tileY, player) && + Regions.InArea(tileX, tileY)) + { + player.SendMessage("Region protected from changes.", Color.Red); + return true; + } + if (Config.DisableBuild) + { + if (!player.Group.HasPermission(Permissions.editspawn)) + { + player.SendMessage("World protected from changes.", Color.Red); + return true; + } + } + if (Config.SpawnProtection) + { + if (!player.Group.HasPermission(Permissions.editspawn)) + { + var flag = CheckSpawn(tileX, tileY); + if (flag) + { + player.SendMessage("Spawn protected from changes.", Color.Red); + return true; + } + } + } + return false; + } - public static bool CheckSpawn(int x, int y) - { - Vector2 tile = new Vector2(x, y); - Vector2 spawn = new Vector2(Main.spawnTileX, Main.spawnTileY); - return Distance(spawn, tile) <= Config.SpawnProtectionRadius; - } - public static float Distance(Vector2 value1, Vector2 value2) - { - float num2 = value1.X - value2.X; - float num = value1.Y - value2.Y; - float num3 = (num2 * num2) + (num * num); - return (float)Math.Sqrt(num3); - } + public static bool CheckSpawn(int x, int y) + { + Vector2 tile = new Vector2(x, y); + Vector2 spawn = new Vector2(Main.spawnTileX, Main.spawnTileY); + return Distance(spawn, tile) <= Config.SpawnProtectionRadius; + } - public static bool HackedHealth(TSPlayer player) - { - return (player.TPlayer.statManaMax > 400) || - (player.TPlayer.statMana > 400) || - (player.TPlayer.statLifeMax > 400) || - (player.TPlayer.statLife > 400); - } + public static float Distance(Vector2 value1, Vector2 value2) + { + float num2 = value1.X - value2.X; + float num = value1.Y - value2.Y; + float num3 = (num2*num2) + (num*num); + return (float) Math.Sqrt(num3); + } - public static bool HackedInventory(TSPlayer player) - { - bool check = false; + public static bool HackedHealth(TSPlayer player) + { + return (player.TPlayer.statManaMax > 400) || + (player.TPlayer.statMana > 400) || + (player.TPlayer.statLifeMax > 400) || + (player.TPlayer.statLife > 400); + } - Item[] inventory = player.TPlayer.inventory; - Item[] armor = player.TPlayer.armor; - for (int i = 0; i < NetItem.maxNetInventory; i++) - { - if (i < 49) - { - Item item = new Item(); - if (inventory[i] != null && inventory[i].netID != 0) - { - item.netDefaults(inventory[i].netID); - item.Prefix(inventory[i].prefix); - item.AffixName(); - if (inventory[i].stack > item.maxStack) - { - check = true; - player.SendMessage(String.Format("Stack cheat detected. Remove item {0} ({1}) and then rejoin", item.name, inventory[i].stack), Color.Cyan); - } - } - } - else - { - Item item = new Item(); - if (armor[i - 48] != null && armor[i - 48].netID != 0) - { - item.netDefaults(armor[i - 48].netID); - item.Prefix(armor[i - 48].prefix); - item.AffixName(); - if (armor[i - 48].stack > item.maxStack) - { - check = true; - player.SendMessage(String.Format("Stack cheat detected. Remove armor {0} ({1}) and then rejoin", item.name, armor[i - 48].stack), Color.Cyan); - } - } - } - } + public static bool HackedInventory(TSPlayer player) + { + bool check = false; - return check; - } + Item[] inventory = player.TPlayer.inventory; + Item[] armor = player.TPlayer.armor; + for (int i = 0; i < NetItem.maxNetInventory; i++) + { + if (i < 49) + { + Item item = new Item(); + if (inventory[i] != null && inventory[i].netID != 0) + { + item.netDefaults(inventory[i].netID); + item.Prefix(inventory[i].prefix); + item.AffixName(); + if (inventory[i].stack > item.maxStack) + { + check = true; + player.SendMessage( + String.Format("Stack cheat detected. Remove item {0} ({1}) and then rejoin", item.name, inventory[i].stack), + Color.Cyan); + } + } + } + else + { + Item item = new Item(); + if (armor[i - 48] != null && armor[i - 48].netID != 0) + { + item.netDefaults(armor[i - 48].netID); + item.Prefix(armor[i - 48].prefix); + item.AffixName(); + if (armor[i - 48].stack > item.maxStack) + { + check = true; + player.SendMessage( + String.Format("Stack cheat detected. Remove armor {0} ({1}) and then rejoin", item.name, armor[i - 48].stack), + Color.Cyan); + } + } + } + } - public static bool CheckInventory(TSPlayer player) - { - PlayerData playerData = player.PlayerData; - bool check = true; + return check; + } - if (player.TPlayer.statLifeMax > playerData.maxHealth) - { - player.SendMessage("Error: Your max health exceeded (" + playerData.maxHealth + ") which is stored on server", Color.Cyan); - check = false; - } + public static bool CheckInventory(TSPlayer player) + { + PlayerData playerData = player.PlayerData; + bool check = true; - Item[] inventory = player.TPlayer.inventory; - Item[] armor = player.TPlayer.armor; - for (int i = 0; i < NetItem.maxNetInventory; i++) - { - if (i < 49) - { - Item item = new Item(); - Item serverItem = new Item(); - if (inventory[i] != null && inventory[i].netID != 0) - { - if (playerData.inventory[i].netID != inventory[i].netID) - { - item.netDefaults(inventory[i].netID); - item.Prefix(inventory[i].prefix); - item.AffixName(); - player.SendMessage(player.IgnoreActionsForInventory = "Your item (" + item.name + ") needs to be deleted.", Color.Cyan); - check = false; - } - else if (playerData.inventory[i].prefix != inventory[i].prefix) - { - item.netDefaults(inventory[i].netID); - item.Prefix(inventory[i].prefix); - item.AffixName(); - player.SendMessage(player.IgnoreActionsForInventory = "Your item (" + item.name + ") needs to be deleted.", Color.Cyan); - check = false; - } - else if (inventory[i].stack > playerData.inventory[i].stack) - { - item.netDefaults(inventory[i].netID); - item.Prefix(inventory[i].prefix); - item.AffixName(); - player.SendMessage(player.IgnoreActionsForInventory = "Your item (" + item.name + ") (" + inventory[i].stack + ") needs to have it's stack decreased to (" + playerData.inventory[i].stack + ").", Color.Cyan); - check = false; - } - } - } - else - { - Item item = new Item(); - Item serverItem = new Item(); - if (armor[i - 48] != null && armor[i - 48].netID != 0) - { - if (playerData.inventory[i].netID != armor[i - 48].netID) - { - item.netDefaults(armor[i - 48].netID); - item.Prefix(armor[i - 48].prefix); - item.AffixName(); - player.SendMessage(player.IgnoreActionsForInventory = "Your armor (" + item.name + ") needs to be deleted.", Color.Cyan); - check = false; - } - else if (playerData.inventory[i].prefix != armor[i - 48].prefix) - { - item.netDefaults(armor[i - 48].netID); - item.Prefix(armor[i - 48].prefix); - item.AffixName(); - player.SendMessage(player.IgnoreActionsForInventory = "Your armor (" + item.name + ") needs to be deleted.", Color.Cyan); - check = false; - } - else if (armor[i - 48].stack > playerData.inventory[i].stack) - { - item.netDefaults(armor[i - 48].netID); - item.Prefix(armor[i - 48].prefix); - item.AffixName(); - player.SendMessage(player.IgnoreActionsForInventory = "Your armor (" + item.name + ") (" + inventory[i].stack + ") needs to have it's stack decreased to (" + playerData.inventory[i].stack + ").", Color.Cyan); - check = false; - } - } - } - } + if (player.TPlayer.statLifeMax > playerData.maxHealth) + { + player.SendMessage("Error: Your max health exceeded (" + playerData.maxHealth + ") which is stored on server", + Color.Cyan); + check = false; + } - return check; - } + Item[] inventory = player.TPlayer.inventory; + Item[] armor = player.TPlayer.armor; + for (int i = 0; i < NetItem.maxNetInventory; i++) + { + if (i < 49) + { + Item item = new Item(); + Item serverItem = new Item(); + if (inventory[i] != null && inventory[i].netID != 0) + { + if (playerData.inventory[i].netID != inventory[i].netID) + { + item.netDefaults(inventory[i].netID); + item.Prefix(inventory[i].prefix); + item.AffixName(); + player.SendMessage(player.IgnoreActionsForInventory = "Your item (" + item.name + ") needs to be deleted.", + Color.Cyan); + check = false; + } + else if (playerData.inventory[i].prefix != inventory[i].prefix) + { + item.netDefaults(inventory[i].netID); + item.Prefix(inventory[i].prefix); + item.AffixName(); + player.SendMessage(player.IgnoreActionsForInventory = "Your item (" + item.name + ") needs to be deleted.", + Color.Cyan); + check = false; + } + else if (inventory[i].stack > playerData.inventory[i].stack) + { + item.netDefaults(inventory[i].netID); + item.Prefix(inventory[i].prefix); + item.AffixName(); + player.SendMessage( + player.IgnoreActionsForInventory = + "Your item (" + item.name + ") (" + inventory[i].stack + ") needs to have it's stack decreased to (" + + playerData.inventory[i].stack + ").", Color.Cyan); + check = false; + } + } + } + else + { + Item item = new Item(); + Item serverItem = new Item(); + if (armor[i - 48] != null && armor[i - 48].netID != 0) + { + if (playerData.inventory[i].netID != armor[i - 48].netID) + { + item.netDefaults(armor[i - 48].netID); + item.Prefix(armor[i - 48].prefix); + item.AffixName(); + player.SendMessage(player.IgnoreActionsForInventory = "Your armor (" + item.name + ") needs to be deleted.", + Color.Cyan); + check = false; + } + else if (playerData.inventory[i].prefix != armor[i - 48].prefix) + { + item.netDefaults(armor[i - 48].netID); + item.Prefix(armor[i - 48].prefix); + item.AffixName(); + player.SendMessage(player.IgnoreActionsForInventory = "Your armor (" + item.name + ") needs to be deleted.", + Color.Cyan); + check = false; + } + else if (armor[i - 48].stack > playerData.inventory[i].stack) + { + item.netDefaults(armor[i - 48].netID); + item.Prefix(armor[i - 48].prefix); + item.AffixName(); + player.SendMessage( + player.IgnoreActionsForInventory = + "Your armor (" + item.name + ") (" + inventory[i].stack + ") needs to have it's stack decreased to (" + + playerData.inventory[i].stack + ").", Color.Cyan); + check = false; + } + } + } + } - public static bool CheckIgnores(TSPlayer player) - { - bool check = false; - if (Config.PvPMode == "always" && !player.TPlayer.hostile) - check = true; - if (player.IgnoreActionsForInventory != "none") - check = true; - if (player.IgnoreActionsForCheating != "none") - check = true; - if (player.IgnoreActionsForDisabledArmor != "none") - check = true; - if (player.IgnoreActionsForClearingTrashCan) - check = true; - if (!player.IsLoggedIn && Config.RequireLogin) - check = true; - return check; - } + return check; + } - public void OnConfigRead(ConfigFile file) - { - NPC.defaultMaxSpawns = file.DefaultMaximumSpawns; - NPC.defaultSpawnRate = file.DefaultSpawnRate; + public static bool CheckIgnores(TSPlayer player) + { + bool check = false; + if (Config.PvPMode == "always" && !player.TPlayer.hostile) + check = true; + if (player.IgnoreActionsForInventory != "none") + check = true; + if (player.IgnoreActionsForCheating != "none") + check = true; + if (player.IgnoreActionsForDisabledArmor != "none") + check = true; + if (player.IgnoreActionsForClearingTrashCan) + check = true; + if (!player.IsLoggedIn && Config.RequireLogin) + check = true; + return check; + } - Main.autoSave = file.AutoSave; - if (Backups != null) - { - Backups.KeepFor = file.BackupKeepFor; - Backups.Interval = file.BackupInterval; - } - if (!OverridePort) - { - Netplay.serverPort = file.ServerPort; - } + public void OnConfigRead(ConfigFile file) + { + NPC.defaultMaxSpawns = file.DefaultMaximumSpawns; + NPC.defaultSpawnRate = file.DefaultSpawnRate; - if (file.MaxSlots > 235) - file.MaxSlots = 235; - Main.maxNetPlayers = file.MaxSlots + 20; - Netplay.password = ""; - Netplay.spamCheck = false; + Main.autoSave = file.AutoSave; + if (Backups != null) + { + Backups.KeepFor = file.BackupKeepFor; + Backups.Interval = file.BackupInterval; + } + if (!OverridePort) + { + Netplay.serverPort = file.ServerPort; + } - RconHandler.Password = file.RconPassword; - RconHandler.ListenPort = file.RconPort; + if (file.MaxSlots > 235) + file.MaxSlots = 235; + Main.maxNetPlayers = file.MaxSlots + 20; + Netplay.password = ""; + Netplay.spamCheck = false; - Utils.HashAlgo = file.HashAlgorithm; - } - } + RconHandler.Password = file.RconPassword; + RconHandler.ListenPort = file.RconPort; + + Utils.HashAlgo = file.HashAlgorithm; + } + } } \ No newline at end of file diff --git a/TShockAPI/UpdateManager.cs b/TShockAPI/UpdateManager.cs index ca6f9d81..6f49eb32 100644 --- a/TShockAPI/UpdateManager.cs +++ b/TShockAPI/UpdateManager.cs @@ -24,79 +24,80 @@ using Newtonsoft.Json; namespace TShockAPI { - class UpdateManager - { - static string updateUrl = "http://shankshock.com/tshock-update.json"; - public static DateTime lastcheck = DateTime.MinValue; - /// - /// Check once every X minutes. - /// - static readonly int CheckXMinutes = 30; + internal class UpdateManager + { + private static string updateUrl = "http://shankshock.com/tshock-update.json"; + public static DateTime lastcheck = DateTime.MinValue; - public static void UpdateProcedureCheck() - { - if ((DateTime.Now - lastcheck).TotalMinutes >= CheckXMinutes) - { - ThreadPool.QueueUserWorkItem(CheckUpdate); - lastcheck = DateTime.Now; - } - } + /// + /// Check once every X minutes. + /// + private static readonly int CheckXMinutes = 30; - public static void CheckUpdate(object o) - { - var updates = ServerIsOutOfDate(); - if (updates != null) - { - NotifyAdministrators(updates); - } - } + public static void UpdateProcedureCheck() + { + if ((DateTime.Now - lastcheck).TotalMinutes >= CheckXMinutes) + { + ThreadPool.QueueUserWorkItem(CheckUpdate); + lastcheck = DateTime.Now; + } + } - /// - /// Checks to see if the server is out of date. - /// - /// - private static Dictionary ServerIsOutOfDate() - { - using (var client = new WebClient()) - { - client.Headers.Add("user-agent", - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705;)"); - try - { - string updatejson = client.DownloadString(updateUrl); - var update = JsonConvert.DeserializeObject>(updatejson); - var version = new Version(update["version"]); - if (TShock.VersionNum.CompareTo(version) < 0) - return update; - } - catch (Exception e) - { - Log.Error(e.ToString()); - } - return null; - } - } + public static void CheckUpdate(object o) + { + var updates = ServerIsOutOfDate(); + if (updates != null) + { + NotifyAdministrators(updates); + } + } - private static void NotifyAdministrators(Dictionary update) - { - var changes = update["changes"].Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); - NotifyAdministrator(TSPlayer.Server, changes); - foreach (TSPlayer player in TShock.Players) - { - if (player != null && player.Active && player.Group.HasPermission(Permissions.maintenance)) - { - NotifyAdministrator(player, changes); - } - } - } + /// + /// Checks to see if the server is out of date. + /// + /// + private static Dictionary ServerIsOutOfDate() + { + using (var client = new WebClient()) + { + client.Headers.Add("user-agent", + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705;)"); + try + { + string updatejson = client.DownloadString(updateUrl); + var update = JsonConvert.DeserializeObject>(updatejson); + var version = new Version(update["version"]); + if (TShock.VersionNum.CompareTo(version) < 0) + return update; + } + catch (Exception e) + { + Log.Error(e.ToString()); + } + return null; + } + } - private static void NotifyAdministrator(TSPlayer player, string[] changes) - { - player.SendMessage("The server is out of date.", Color.Red); - for (int j = 0; j < changes.Length; j++) - { - player.SendMessage(changes[j], Color.Red); - } - } - } -} + private static void NotifyAdministrators(Dictionary update) + { + var changes = update["changes"].Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries); + NotifyAdministrator(TSPlayer.Server, changes); + foreach (TSPlayer player in TShock.Players) + { + if (player != null && player.Active && player.Group.HasPermission(Permissions.maintenance)) + { + NotifyAdministrator(player, changes); + } + } + } + + private static void NotifyAdministrator(TSPlayer player, string[] changes) + { + player.SendMessage("The server is out of date.", Color.Red); + for (int j = 0; j < changes.Length; j++) + { + player.SendMessage(changes[j], Color.Red); + } + } + } +} \ No newline at end of file diff --git a/TShockAPI/Utils.cs b/TShockAPI/Utils.cs index 7e924c7c..11586dff 100644 --- a/TShockAPI/Utils.cs +++ b/TShockAPI/Utils.cs @@ -28,599 +28,605 @@ using Terraria; namespace TShockAPI { - public class Utils - { - public Random Random = new Random(); - //private static List groups = new List(); + public class Utils + { + public Random Random = new Random(); + //private static List groups = new List(); - /// - /// Provides the real IP address from a RemoteEndPoint string that contains a port and an IP - /// - /// A string IPv4 address in IP:PORT form. - /// A string IPv4 address. - public string GetRealIP(string mess) - { - return mess.Split(':')[0]; - } + /// + /// Provides the real IP address from a RemoteEndPoint string that contains a port and an IP + /// + /// A string IPv4 address in IP:PORT form. + /// A string IPv4 address. + public string GetRealIP(string mess) + { + return mess.Split(':')[0]; + } - /// - /// Used for some places where a list of players might be used. - /// - /// String of players seperated by commas. - public string GetPlayers() - { - var sb = new StringBuilder(); - foreach (TSPlayer player in TShock.Players) - { - if (player != null && player.Active) - { - if (sb.Length != 0) - { - sb.Append(", "); - } - sb.Append(player.Name); - } - } - return sb.ToString(); - } + /// + /// Used for some places where a list of players might be used. + /// + /// String of players seperated by commas. + public string GetPlayers() + { + var sb = new StringBuilder(); + foreach (TSPlayer player in TShock.Players) + { + if (player != null && player.Active) + { + if (sb.Length != 0) + { + sb.Append(", "); + } + sb.Append(player.Name); + } + } + return sb.ToString(); + } - /// - /// Finds a player and gets IP as string - /// - /// Player name - public string GetPlayerIP(string playername) - { - foreach (TSPlayer player in TShock.Players) - { - if (player != null && player.Active) - { - if (playername.ToLower() == player.Name.ToLower()) - { - return player.IP; - } - } - } - return null; - } + /// + /// Finds a player and gets IP as string + /// + /// Player name + public string GetPlayerIP(string playername) + { + foreach (TSPlayer player in TShock.Players) + { + if (player != null && player.Active) + { + if (playername.ToLower() == player.Name.ToLower()) + { + return player.IP; + } + } + } + return null; + } - /// - /// It's a clamp function - /// - /// - /// Value to clamp - /// Maximum bounds of the clamp - /// Minimum bounds of the clamp - /// - public T Clamp(T value, T max, T min) - where T : IComparable - { - T result = value; - if (value.CompareTo(max) > 0) - result = max; - if (value.CompareTo(min) < 0) - result = min; - return result; - } + /// + /// It's a clamp function + /// + /// + /// Value to clamp + /// Maximum bounds of the clamp + /// Minimum bounds of the clamp + /// + public T Clamp(T value, T max, T min) + where T : IComparable + { + T result = value; + if (value.CompareTo(max) > 0) + result = max; + if (value.CompareTo(min) < 0) + result = min; + return result; + } - /// - /// Saves the map data - /// - public void SaveWorld() - { - WorldGen.saveWorld(); - Broadcast("World saved.", Color.Yellow); - Log.Info(string.Format("World saved at ({0})", Main.worldPathName)); - } + /// + /// Saves the map data + /// + public void SaveWorld() + { + WorldGen.saveWorld(); + Broadcast("World saved.", Color.Yellow); + Log.Info(string.Format("World saved at ({0})", Main.worldPathName)); + } - /// - /// Broadcasts a message to all players - /// - /// string message - public void Broadcast(string msg) - { - Broadcast(msg, Color.Green); - } + /// + /// Broadcasts a message to all players + /// + /// string message + public void Broadcast(string msg) + { + Broadcast(msg, Color.Green); + } - public void Broadcast(string msg, byte red, byte green, byte blue) - { - TSPlayer.All.SendMessage(msg, red, green, blue); - TSPlayer.Server.SendMessage(msg, red, green, blue); - Log.Info(string.Format("Broadcast: {0}", msg)); - } + public void Broadcast(string msg, byte red, byte green, byte blue) + { + TSPlayer.All.SendMessage(msg, red, green, blue); + TSPlayer.Server.SendMessage(msg, red, green, blue); + Log.Info(string.Format("Broadcast: {0}", msg)); + } - public void Broadcast(string msg, Color color) - { - Broadcast(msg, color.R, color.G, color.B); - } + public void Broadcast(string msg, Color color) + { + Broadcast(msg, color.R, color.G, color.B); + } - /// - /// Sends message to all users with 'logs' permission. - /// - /// - /// - public void SendLogs(string log, Color color) - { - Log.Info(log); - TSPlayer.Server.SendMessage(log, color); - foreach (TSPlayer player in TShock.Players) - { - if (player != null && player.Active && player.Group.HasPermission(Permissions.logs) && player.DisplayLogs && TShock.Config.DisableSpewLogs == false) - player.SendMessage(log, color); - } - } + /// + /// Sends message to all users with 'logs' permission. + /// + /// + /// + public void SendLogs(string log, Color color) + { + Log.Info(log); + TSPlayer.Server.SendMessage(log, color); + foreach (TSPlayer player in TShock.Players) + { + if (player != null && player.Active && player.Group.HasPermission(Permissions.logs) && player.DisplayLogs && + TShock.Config.DisableSpewLogs == false) + player.SendMessage(log, color); + } + } - /// - /// The number of active players on the server. - /// - /// int playerCount - public int ActivePlayers() - { - int num = 0; - foreach (TSPlayer player in TShock.Players) - { - if (player != null && player.Active) - { - num++; - } - } - return num; - } + /// + /// The number of active players on the server. + /// + /// int playerCount + public int ActivePlayers() + { + int num = 0; + foreach (TSPlayer player in TShock.Players) + { + if (player != null && player.Active) + { + num++; + } + } + return num; + } - /// - /// - /// - /// - /// - public List FindPlayer(string ply) - { - var found = new List(); - ply = ply.ToLower(); - foreach (TSPlayer player in TShock.Players) - { - if (player == null) - continue; + /// + /// + /// + /// + /// + public List FindPlayer(string ply) + { + var found = new List(); + ply = ply.ToLower(); + foreach (TSPlayer player in TShock.Players) + { + if (player == null) + continue; - string name = player.Name.ToLower(); - if (name.Equals(ply)) - return new List { player }; - if (name.Contains(ply)) - found.Add(player); - } - return found; - } + string name = player.Name.ToLower(); + if (name.Equals(ply)) + return new List {player}; + if (name.Contains(ply)) + found.Add(player); + } + return found; + } - public void GetRandomClearTileWithInRange(int startTileX, int startTileY, int tileXRange, int tileYRange, out int tileX, out int tileY) - { - int j = 0; - do - { - if (j == 100) - { - tileX = startTileX; - tileY = startTileY; - break; - } + public void GetRandomClearTileWithInRange(int startTileX, int startTileY, int tileXRange, int tileYRange, + out int tileX, out int tileY) + { + int j = 0; + do + { + if (j == 100) + { + tileX = startTileX; + tileY = startTileY; + break; + } - tileX = startTileX + Random.Next(tileXRange * -1, tileXRange); - tileY = startTileY + Random.Next(tileYRange * -1, tileYRange); - j++; - } - while (TileValid(tileX, tileY) && !TileClear(tileX, tileY)); - } + tileX = startTileX + Random.Next(tileXRange*-1, tileXRange); + tileY = startTileY + Random.Next(tileYRange*-1, tileYRange); + j++; + } while (TileValid(tileX, tileY) && !TileClear(tileX, tileY)); + } - private bool TileValid(int tileX, int tileY) - { - return tileX >= 0 && tileX <= Main.maxTilesX && tileY >= 0 && tileY <= Main.maxTilesY; - } + private bool TileValid(int tileX, int tileY) + { + return tileX >= 0 && tileX <= Main.maxTilesX && tileY >= 0 && tileY <= Main.maxTilesY; + } - private bool TileClear(int tileX, int tileY) - { - return !Main.tile[tileX, tileY].active; - } + private bool TileClear(int tileX, int tileY) + { + return !Main.tile[tileX, tileY].active; + } - public List GetItemByIdOrName(string idOrName) - { - int type = -1; - if (int.TryParse(idOrName, out type)) - { - return new List { GetItemById(type) }; - } - return GetItemByName(idOrName); - } + public List GetItemByIdOrName(string idOrName) + { + int type = -1; + if (int.TryParse(idOrName, out type)) + { + return new List {GetItemById(type)}; + } + return GetItemByName(idOrName); + } - public Item GetItemById(int id) - { - Item item = new Item(); - item.netDefaults(id); - return item; - } + public Item GetItemById(int id) + { + Item item = new Item(); + item.netDefaults(id); + return item; + } - public List GetItemByName(string name) - { - //Method #1 - must be exact match, allows support for different pickaxes/hammers/swords etc - for (int i = 1; i < Main.maxItemTypes; i++) - { - Item item = new Item(); - item.SetDefaults(name); - if (item.name == name) - return new List { item }; - } - //Method #2 - allows impartial matching - var found = new List(); - for (int i = -24; i < Main.maxItemTypes; i++) - { - try - { - Item item = new Item(); - item.netDefaults(i); - if (item.name.ToLower() == name.ToLower()) - return new List { item }; - if (item.name.ToLower().StartsWith(name.ToLower())) - found.Add(item); - } - catch { } - } - return found; - } + public List GetItemByName(string name) + { + //Method #1 - must be exact match, allows support for different pickaxes/hammers/swords etc + for (int i = 1; i < Main.maxItemTypes; i++) + { + Item item = new Item(); + item.SetDefaults(name); + if (item.name == name) + return new List {item}; + } + //Method #2 - allows impartial matching + var found = new List(); + for (int i = -24; i < Main.maxItemTypes; i++) + { + try + { + Item item = new Item(); + item.netDefaults(i); + if (item.name.ToLower() == name.ToLower()) + return new List {item}; + if (item.name.ToLower().StartsWith(name.ToLower())) + found.Add(item); + } + catch + { + } + } + return found; + } - public List GetNPCByIdOrName(string idOrName) - { - int type = -1; - if (int.TryParse(idOrName, out type)) - { - return new List { GetNPCById(type) }; - } - return GetNPCByName(idOrName); - } + public List GetNPCByIdOrName(string idOrName) + { + int type = -1; + if (int.TryParse(idOrName, out type)) + { + return new List {GetNPCById(type)}; + } + return GetNPCByName(idOrName); + } - public NPC GetNPCById(int id) - { - NPC npc = new NPC(); - npc.netDefaults(id); - return npc; - } + public NPC GetNPCById(int id) + { + NPC npc = new NPC(); + npc.netDefaults(id); + return npc; + } - public List GetNPCByName(string name) - { - //Method #1 - must be exact match, allows support for different coloured slimes - for (int i = -17; i < Main.maxNPCTypes; i++) - { - NPC npc = new NPC(); - npc.SetDefaults(name); - if (npc.name == name) - return new List { npc }; - } - //Method #2 - allows impartial matching - var found = new List(); - for (int i = 1; i < Main.maxNPCTypes; i++) - { - NPC npc = new NPC(); - npc.netDefaults(i); - if (npc.name.ToLower() == name.ToLower()) - return new List { npc }; - if (npc.name.ToLower().StartsWith(name.ToLower())) - found.Add(npc); - } - return found; - } + public List GetNPCByName(string name) + { + //Method #1 - must be exact match, allows support for different coloured slimes + for (int i = -17; i < Main.maxNPCTypes; i++) + { + NPC npc = new NPC(); + npc.SetDefaults(name); + if (npc.name == name) + return new List {npc}; + } + //Method #2 - allows impartial matching + var found = new List(); + for (int i = 1; i < Main.maxNPCTypes; i++) + { + NPC npc = new NPC(); + npc.netDefaults(i); + if (npc.name.ToLower() == name.ToLower()) + return new List {npc}; + if (npc.name.ToLower().StartsWith(name.ToLower())) + found.Add(npc); + } + return found; + } - public string GetBuffName(int id) - { - return (id > 0 && id < Main.maxBuffs) ? Main.buffName[id] : "null"; - } + public string GetBuffName(int id) + { + return (id > 0 && id < Main.maxBuffs) ? Main.buffName[id] : "null"; + } - public string GetBuffDescription(int id) - { - return (id > 0 && id < Main.maxBuffs) ? Main.buffTip[id] : "null"; - } + public string GetBuffDescription(int id) + { + return (id > 0 && id < Main.maxBuffs) ? Main.buffTip[id] : "null"; + } - public List GetBuffByName(string name) - { - for (int i = 1; i < Main.maxBuffs; i++) - { - if (Main.buffName[i].ToLower() == name) - return new List { i }; - } - var found = new List(); - for (int i = 1; i < Main.maxBuffs; i++) - { - if (Main.buffName[i].ToLower().StartsWith(name.ToLower())) - found.Add(i); - } - return found; - } + public List GetBuffByName(string name) + { + for (int i = 1; i < Main.maxBuffs; i++) + { + if (Main.buffName[i].ToLower() == name) + return new List {i}; + } + var found = new List(); + for (int i = 1; i < Main.maxBuffs; i++) + { + if (Main.buffName[i].ToLower().StartsWith(name.ToLower())) + found.Add(i); + } + return found; + } - public string GetPrefixById(int id) - { - var item = new Item(); - item.SetDefaults(0); - item.prefix = (byte)id; - item.AffixName(); - return item.name.Trim(); - } + public string GetPrefixById(int id) + { + var item = new Item(); + item.SetDefaults(0); + item.prefix = (byte) id; + item.AffixName(); + return item.name.Trim(); + } - public List GetPrefixByName(string name) - { - Item item = new Item(); - item.SetDefaults(0); - for (int i = 1; i < 83; i++) - { - item.prefix = (byte) i; - if (item.AffixName().Trim() == name) - return new List { i }; - } - var found = new List(); - for (int i = 1; i < 83; i++) - { - try - { - item.prefix = (byte) i; - if (item.AffixName().Trim().ToLower() == name.ToLower()) - return new List { i }; - if (item.AffixName().Trim().ToLower().StartsWith(name.ToLower())) - found.Add(i); - } - catch { } - } - return found; - } + public List GetPrefixByName(string name) + { + Item item = new Item(); + item.SetDefaults(0); + for (int i = 1; i < 83; i++) + { + item.prefix = (byte) i; + if (item.AffixName().Trim() == name) + return new List {i}; + } + var found = new List(); + for (int i = 1; i < 83; i++) + { + try + { + item.prefix = (byte) i; + if (item.AffixName().Trim().ToLower() == name.ToLower()) + return new List {i}; + if (item.AffixName().Trim().ToLower().StartsWith(name.ToLower())) + found.Add(i); + } + catch + { + } + } + return found; + } - public List GetPrefixByIdOrName(string idOrName) - { - int type = -1; - if (int.TryParse(idOrName, out type) && type > 0 && type < 84) - { - return new List {type}; - } - return GetPrefixByName(idOrName); - } + public List GetPrefixByIdOrName(string idOrName) + { + int type = -1; + if (int.TryParse(idOrName, out type) && type > 0 && type < 84) + { + return new List {type}; + } + return GetPrefixByName(idOrName); + } - /// - /// Kicks all player from the server without checking for immunetokick permission. - /// - /// int player - /// string reason - public void ForceKickAll(string reason) - { - foreach (TSPlayer player in TShock.Players) - { - if (player != null && player.Active) - { - ForceKick(player, reason); - } - } - } + /// + /// Kicks all player from the server without checking for immunetokick permission. + /// + /// int player + /// string reason + public void ForceKickAll(string reason) + { + foreach (TSPlayer player in TShock.Players) + { + if (player != null && player.Active) + { + ForceKick(player, reason); + } + } + } - /// - /// Kicks a player from the server without checking for immunetokick permission. - /// - /// int player - /// string reason - public void ForceKick(TSPlayer player, string reason) - { - if (!player.ConnectionAlive) - return; - player.Disconnect(reason); - Log.ConsoleInfo(string.Format("{0} was force kicked for : {1}", player.IP, reason)); - } + /// + /// Kicks a player from the server without checking for immunetokick permission. + /// + /// int player + /// string reason + public void ForceKick(TSPlayer player, string reason) + { + if (!player.ConnectionAlive) + return; + player.Disconnect(reason); + Log.ConsoleInfo(string.Format("{0} was force kicked for : {1}", player.IP, reason)); + } - /// - /// Kicks a player from the server. - /// - /// int player - /// string reason - public bool Kick(TSPlayer player, string reason, string adminUserName = "") - { - if (!player.ConnectionAlive) - return true; - if (!player.Group.HasPermission(Permissions.immunetokick)) - { - string playerName = player.Name; - player.Disconnect(string.Format("Kicked: {0}", reason)); - Log.ConsoleInfo(string.Format("Kicked {0} for : {1}", playerName, reason)); - if (adminUserName.Length == 0) - Broadcast(string.Format("{0} was kicked for {1}", playerName, reason.ToLower())); - else - Broadcast(string.Format("{0} kicked {1} for {2}", adminUserName, playerName, reason.ToLower())); - return true; - } - return false; - } + /// + /// Kicks a player from the server. + /// + /// int player + /// string reason + public bool Kick(TSPlayer player, string reason, string adminUserName = "") + { + if (!player.ConnectionAlive) + return true; + if (!player.Group.HasPermission(Permissions.immunetokick)) + { + string playerName = player.Name; + player.Disconnect(string.Format("Kicked: {0}", reason)); + Log.ConsoleInfo(string.Format("Kicked {0} for : {1}", playerName, reason)); + if (adminUserName.Length == 0) + Broadcast(string.Format("{0} was kicked for {1}", playerName, reason.ToLower())); + else + Broadcast(string.Format("{0} kicked {1} for {2}", adminUserName, playerName, reason.ToLower())); + return true; + } + return false; + } - /// - /// Bans and kicks a player from the server. - /// - /// int player - /// string reason - public bool Ban(TSPlayer player, string reason, string adminUserName = "") - { - if (!player.ConnectionAlive) - return true; - if (!player.Group.HasPermission(Permissions.immunetoban)) - { - string ip = player.IP; - string playerName = player.Name; - TShock.Bans.AddBan(ip, playerName, reason); - player.Disconnect(string.Format("Banned: {0}", reason)); - Log.ConsoleInfo(string.Format("Banned {0} for : {1}", playerName, reason)); - if (adminUserName.Length == 0) - Broadcast(string.Format("{0} was banned for {1}", playerName, reason.ToLower())); - else - Broadcast(string.Format("{0} banned {1} for {2}", adminUserName, playerName, reason.ToLower())); - return true; - } - return false; - } + /// + /// Bans and kicks a player from the server. + /// + /// int player + /// string reason + public bool Ban(TSPlayer player, string reason, string adminUserName = "") + { + if (!player.ConnectionAlive) + return true; + if (!player.Group.HasPermission(Permissions.immunetoban)) + { + string ip = player.IP; + string playerName = player.Name; + TShock.Bans.AddBan(ip, playerName, reason); + player.Disconnect(string.Format("Banned: {0}", reason)); + Log.ConsoleInfo(string.Format("Banned {0} for : {1}", playerName, reason)); + if (adminUserName.Length == 0) + Broadcast(string.Format("{0} was banned for {1}", playerName, reason.ToLower())); + else + Broadcast(string.Format("{0} banned {1} for {2}", adminUserName, playerName, reason.ToLower())); + return true; + } + return false; + } - /// - /// Shows a file to the user. - /// - /// int player - /// string filename reletave to savedir - //Todo: Fix this - public void ShowFileToUser(TSPlayer player, string file) - { - string foo = ""; - using (var tr = new StreamReader(Path.Combine(TShock.SavePath, file))) - { - while ((foo = tr.ReadLine()) != null) - { - foo = foo.Replace("%map%", Main.worldName); - foo = foo.Replace("%players%", GetPlayers()); - foo = SanitizeString(foo); - if (foo.Substring(0, 1) == "%" && foo.Substring(12, 1) == "%") //Look for a beginning color code. - { - string possibleColor = foo.Substring(0, 13); - foo = foo.Remove(0, 13); - float[] pC = { 0, 0, 0 }; - possibleColor = possibleColor.Replace("%", ""); - string[] pCc = possibleColor.Split(','); - if (pCc.Length == 3) - { - try - { - player.SendMessage(foo, (byte)Convert.ToInt32(pCc[0]), (byte)Convert.ToInt32(pCc[1]), - (byte)Convert.ToInt32(pCc[2])); - continue; - } - catch (Exception e) - { - Log.Error(e.ToString()); - } - } - } - player.SendMessage(foo); - } - } - } + /// + /// Shows a file to the user. + /// + /// int player + /// string filename reletave to savedir + //Todo: Fix this + public void ShowFileToUser(TSPlayer player, string file) + { + string foo = ""; + using (var tr = new StreamReader(Path.Combine(TShock.SavePath, file))) + { + while ((foo = tr.ReadLine()) != null) + { + foo = foo.Replace("%map%", Main.worldName); + foo = foo.Replace("%players%", GetPlayers()); + foo = SanitizeString(foo); + if (foo.Substring(0, 1) == "%" && foo.Substring(12, 1) == "%") //Look for a beginning color code. + { + string possibleColor = foo.Substring(0, 13); + foo = foo.Remove(0, 13); + float[] pC = {0, 0, 0}; + possibleColor = possibleColor.Replace("%", ""); + string[] pCc = possibleColor.Split(','); + if (pCc.Length == 3) + { + try + { + player.SendMessage(foo, (byte) Convert.ToInt32(pCc[0]), (byte) Convert.ToInt32(pCc[1]), + (byte) Convert.ToInt32(pCc[2])); + continue; + } + catch (Exception e) + { + Log.Error(e.ToString()); + } + } + } + player.SendMessage(foo); + } + } + } - /// - /// Returns a Group from the name of the group - /// - /// string groupName - public Group GetGroup(string groupName) - { - //first attempt on cached groups - for (int i = 0; i < TShock.Groups.groups.Count; i++) - { - if (TShock.Groups.groups[i].Name.Equals(groupName)) - { - return TShock.Groups.groups[i]; - } - } - return new Group(TShock.Config.DefaultGuestGroupName); - } + /// + /// Returns a Group from the name of the group + /// + /// string groupName + public Group GetGroup(string groupName) + { + //first attempt on cached groups + for (int i = 0; i < TShock.Groups.groups.Count; i++) + { + if (TShock.Groups.groups[i].Name.Equals(groupName)) + { + return TShock.Groups.groups[i]; + } + } + return new Group(TShock.Config.DefaultGuestGroupName); + } - /// - /// Returns an IPv4 address from a DNS query - /// - /// string ip - public string GetIPv4Address(string hostname) - { - try - { - //Get the ipv4 address from GetHostAddresses, if an ip is passed it will return that ip - var ip = Dns.GetHostAddresses(hostname).FirstOrDefault(i => i.AddressFamily == AddressFamily.InterNetwork); - //if the dns query was successful then return it, otherwise return an empty string - return ip != null ? ip.ToString() : ""; - } - catch (SocketException) - { - } - return ""; - } + /// + /// Returns an IPv4 address from a DNS query + /// + /// string ip + public string GetIPv4Address(string hostname) + { + try + { + //Get the ipv4 address from GetHostAddresses, if an ip is passed it will return that ip + var ip = Dns.GetHostAddresses(hostname).FirstOrDefault(i => i.AddressFamily == AddressFamily.InterNetwork); + //if the dns query was successful then return it, otherwise return an empty string + return ip != null ? ip.ToString() : ""; + } + catch (SocketException) + { + } + return ""; + } - public string HashAlgo = "md5"; + public string HashAlgo = "md5"; - public readonly Dictionary> HashTypes = new Dictionary> - { - {"sha512", () => new SHA512Managed()}, - {"sha256", () => new SHA256Managed()}, - {"md5", () => new MD5Cng()}, - {"sha512-xp", () => SHA512.Create()}, - {"sha256-xp", () => SHA256.Create()}, - {"md5-xp", () => MD5.Create()}, - }; + public readonly Dictionary> HashTypes = new Dictionary> + { + {"sha512", () => new SHA512Managed()}, + {"sha256", () => new SHA256Managed()}, + {"md5", () => new MD5Cng()}, + {"sha512-xp", () => SHA512.Create()}, + {"sha256-xp", () => SHA256.Create()}, + {"md5-xp", () => MD5.Create()}, + }; - /// - /// Returns a Sha256 string for a given string - /// - /// bytes to hash - /// string sha256 - public string HashPassword(byte[] bytes) - { - if (bytes == null) - throw new NullReferenceException("bytes"); - Func func; - if (!HashTypes.TryGetValue(HashAlgo.ToLower(), out func)) - throw new NotSupportedException("Hashing algorithm {0} is not supported".SFormat(HashAlgo.ToLower())); + /// + /// Returns a Sha256 string for a given string + /// + /// bytes to hash + /// string sha256 + public string HashPassword(byte[] bytes) + { + if (bytes == null) + throw new NullReferenceException("bytes"); + Func func; + if (!HashTypes.TryGetValue(HashAlgo.ToLower(), out func)) + throw new NotSupportedException("Hashing algorithm {0} is not supported".SFormat(HashAlgo.ToLower())); - using (var hash = func()) - { - var ret = hash.ComputeHash(bytes); - return ret.Aggregate("", (s, b) => s + b.ToString("X2")); - } - } - /// - /// Returns a Sha256 string for a given string - /// - /// bytes to hash - /// string sha256 - public string HashPassword(string password) - { - if (string.IsNullOrEmpty(password) || password == "non-existant password") - return "non-existant password"; - return HashPassword(Encoding.UTF8.GetBytes(password)); - } + using (var hash = func()) + { + var ret = hash.ComputeHash(bytes); + return ret.Aggregate("", (s, b) => s + b.ToString("X2")); + } + } - /// - /// Checks if the string contains any unprintable characters - /// - /// String to check - /// True if the string only contains printable characters - public bool ValidString(string str) - { - foreach (var c in str) - { - if (c < 0x20 || c > 0xA9) - return false; - } - return true; - } + /// + /// Returns a Sha256 string for a given string + /// + /// bytes to hash + /// string sha256 + public string HashPassword(string password) + { + if (string.IsNullOrEmpty(password) || password == "non-existant password") + return "non-existant password"; + return HashPassword(Encoding.UTF8.GetBytes(password)); + } - /// - /// Checks if world has hit the max number of chests - /// - /// True if the entire chest array is used - public bool MaxChests() - { - for (int i = 0; i < Main.chest.Length; i++) - { - if (Main.chest[i] == null) - return false; - } - return true; - } + /// + /// Checks if the string contains any unprintable characters + /// + /// String to check + /// True if the string only contains printable characters + public bool ValidString(string str) + { + foreach (var c in str) + { + if (c < 0x20 || c > 0xA9) + return false; + } + return true; + } - public int SearchProjectile(short identity) - { - for (int i = 0; i < Main.maxProjectiles; i++) - { - if (Main.projectile[i].identity == identity) - return i; - } - return 1000; - } + /// + /// Checks if world has hit the max number of chests + /// + /// True if the entire chest array is used + public bool MaxChests() + { + for (int i = 0; i < Main.chest.Length; i++) + { + if (Main.chest[i] == null) + return false; + } + return true; + } - public string SanitizeString(string str) - { - var returnstr = str.ToCharArray(); - for (int i = 0; i < str.Length; i++) - { - if (!ValidString(str[i].ToString())) - returnstr[i] = ' '; - } - return new string(returnstr); - } - } -} + public int SearchProjectile(short identity) + { + for (int i = 0; i < Main.maxProjectiles; i++) + { + if (Main.projectile[i].identity == identity) + return i; + } + return 1000; + } + + public string SanitizeString(string str) + { + var returnstr = str.ToCharArray(); + for (int i = 0; i < str.Length; i++) + { + if (!ValidString(str[i].ToString())) + returnstr[i] = ' '; + } + return new string(returnstr); + } + } +} \ No newline at end of file