From d82851faf3c4b22c924adbfc2571961004acfb3e Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Sun, 22 Feb 2015 12:03:05 -0700 Subject: [PATCH 01/60] EnsureExists now calls EnsureTableStructure directly It occurs to me that copypasting code is bad --- TShockAPI/DB/SqlTable.cs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/TShockAPI/DB/SqlTable.cs b/TShockAPI/DB/SqlTable.cs index 96c9e1d2..5245e04c 100755 --- a/TShockAPI/DB/SqlTable.cs +++ b/TShockAPI/DB/SqlTable.cs @@ -79,19 +79,7 @@ namespace TShockAPI.DB [Obsolete("This method will be replaced by EnsureTableExists.")] 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)); - } + EnsureTableStructure(table); } public List GetColumns(SqlTable table) From 68afd6fcc68bce8c4b67e6245efe9dbe61a5f96d Mon Sep 17 00:00:00 2001 From: Zack Date: Sun, 22 Feb 2015 16:07:59 -0500 Subject: [PATCH 02/60] Make sure to write the correct number of bytes, as UTF8 can and most likely will be more than one byte per char. Fixes #863 --- TShockAPI/Rest/Rest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TShockAPI/Rest/Rest.cs b/TShockAPI/Rest/Rest.cs index 4fbf94e4..17c032cd 100644 --- a/TShockAPI/Rest/Rest.cs +++ b/TShockAPI/Rest/Rest.cs @@ -157,7 +157,8 @@ namespace Rests e.Response.Connection.Type = ConnectionType.Close; e.Response.ContentType = new ContentTypeHeader("application/json; charset=utf-8"); e.Response.Add(serverHeader); - e.Response.Body.Write(Encoding.UTF8.GetBytes(str), 0, str.Length); + var bytes = Encoding.UTF8.GetBytes(str); + e.Response.Body.Write(bytes, 0, bytes.Length); e.Response.Status = HttpStatusCode.OK; } From 63231c73f2fa021c2c6400628a2e705af999840f Mon Sep 17 00:00:00 2001 From: Zack Date: Sun, 22 Feb 2015 16:17:05 -0500 Subject: [PATCH 03/60] Utilize new account hooks to insert and delete from the SSC table, since this is what the feature was intended for. --- TShockAPI/Commands.cs | 2 -- TShockAPI/TShock.cs | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index ec378ae0..b2162eab 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -878,7 +878,6 @@ namespace TShockAPI args.Player.SendSuccessMessage("Account \"{0}\" has been registered.", user.Name); args.Player.SendSuccessMessage("Your password is {0}.", user.Password); TShock.Users.AddUser(user); - TShock.CharacterDB.SeedInitialData(TShock.Users.GetUser(user)); Log.ConsoleInfo("{0} registered an account: \"{1}\".", args.Player.Name, user.Name); } else @@ -919,7 +918,6 @@ namespace TShockAPI try { TShock.Users.AddUser(user); - TShock.CharacterDB.SeedInitialData(TShock.Users.GetUser(user)); args.Player.SendSuccessMessage("Account " + user.Name + " has been added to group " + user.Group + "!"); Log.ConsoleInfo(args.Player.Name + " added Account " + user.Name + " to group " + user.Group); } diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 04a4551f..1346113a 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -265,8 +265,10 @@ namespace TShockAPI ServerApi.Hooks.WorldChristmasCheck.Register(this, OnXmasCheck); ServerApi.Hooks.WorldHalloweenCheck.Register(this, OnHalloweenCheck); ServerApi.Hooks.NetNameCollision.Register(this, NetHooks_NameCollision); - TShockAPI.Hooks.PlayerHooks.PlayerPreLogin += OnPlayerPreLogin; - TShockAPI.Hooks.PlayerHooks.PlayerPostLogin += OnPlayerLogin; + Hooks.PlayerHooks.PlayerPreLogin += OnPlayerPreLogin; + Hooks.PlayerHooks.PlayerPostLogin += OnPlayerLogin; + Hooks.AccountHooks.AccountDelete += OnAccountDelete; + Hooks.AccountHooks.AccountCreate += OnAccountCreate; GetDataHandlers.InitGetDataHandler(); Commands.InitCommands(); @@ -379,6 +381,16 @@ namespace TShockAPI Users.UpdateLogin(u); } + private void OnAccountDelete(Hooks.AccountDeleteEventArgs args) + { + CharacterDB.RemovePlayer(args.User.ID); + } + + private void OnAccountCreate(Hooks.AccountCreateEventArgs args) + { + CharacterDB.SeedInitialData(Users.GetUser(args.User)); + } + private void OnPlayerPreLogin(Hooks.PlayerPreLoginEventArgs args) { if (args.Player.IsLoggedIn) From 8c91856113d2350d8ab5288848bd9eedea67d01a Mon Sep 17 00:00:00 2001 From: Zack Date: Sun, 22 Feb 2015 16:38:38 -0500 Subject: [PATCH 04/60] Update deploy_release to allow the user to specify the body of the release post, as well as using the tag to construct the filename that is uploaded. --- deploy_release.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/deploy_release.py b/deploy_release.py index 7d1b7785..7fbd1461 100644 --- a/deploy_release.py +++ b/deploy_release.py @@ -2,31 +2,48 @@ import requests import json import sys import os +import subprocess create_release_url = 'https://api.github.com/repos/NyxStudios/TShock/releases' -release_name = 'tshock_release.zip' +#Load variables from ENV, which are put there by the bamboo build. branch = os.environ["GIT_BRANCH"] tag_name = os.environ["bamboo_tag_name"] name = os.environ["bamboo_release_name"] +body = os.environ["bamboo_release_body"] + +#build release file name using the tag, stripping the 'v' off the front ie 'v.1.2.3' => '.1.2.3' resulting in a file called 'tshock.1.2.3.zip' +release_name = 'tshock_' + tag_name[1:] + '.zip' #because we can't find any other secure way to get a token into this script run from bamboo :'( with open('/home/bamboo/scripts/token.py') as f: token = f.read().rsplit('=', 1)[1].strip() -body = 'This is the newest release for TShock. Please see the release thread for more information @ http://tshock.co/xf' +#invoke the mv command on the artifact from bamboo to the new name above +subprocess.call('mv tshock_release.zip ' + release_name, shell=True) +#construct the payload for the post request to github to create the release. data = {'tag_name':tag_name, 'target_commitish':branch, 'name':name, 'body':body, 'draft':False, 'prerelease':False} +#headers for the post request with our oauth token, allowing us write access create_headers = {'Content-Type': 'application/json', 'Authorization': 'token ' + token} +#payload is a json string, not a strong typed json object json_data = json.dumps(data) +#make the post request, creating a release r = requests.post(create_release_url, data=json_data, headers=create_headers) +#parse the response into an object json_response = json.loads(r.text) +#extract the relevant information from the object needed to attach a binary to the release created previously release_id = json_response['id'] upload_url = json_response['upload_url'].rsplit('{')[0] + +#construct the post url using the release name, as that is required by the api upload_url = upload_url + '?name=' + release_name +#headers for the post request, need to specify that our file is a zip, and how large it is upload_headers = {'Authorization': 'token ' + token, 'Content-Type':'application/zip', 'Content-Length':str(os.path.getsize(release_name))} + +#upload the binary, resulting in a complete binary r = requests.post(upload_url, data=open(release_name, 'rb'), headers = upload_headers, verify=False) From 17ea9e0875ff5db64e6885224d6d651dffb94324 Mon Sep 17 00:00:00 2001 From: Zack Date: Sun, 22 Feb 2015 17:14:57 -0500 Subject: [PATCH 05/60] Use the NetItem max inventory when seeding the database. --- TShockAPI/DB/CharacterManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/DB/CharacterManager.cs b/TShockAPI/DB/CharacterManager.cs index 861baeeb..df9f75a1 100755 --- a/TShockAPI/DB/CharacterManager.cs +++ b/TShockAPI/DB/CharacterManager.cs @@ -104,7 +104,7 @@ namespace TShockAPI.DB public bool SeedInitialData(User user) { var inventory = new StringBuilder(); - for (int i = 0; i < Terraria.Main.maxInventory; i++) + for (int i = 0; i < NetItem.maxNetInventory; i++) { if (i > 0) { From 6bb3a2f2abb4b11f836f692b3e629185fcef0a46 Mon Sep 17 00:00:00 2001 From: PhoenixICE Date: Mon, 23 Feb 2015 09:26:51 +1100 Subject: [PATCH 06/60] Godmode Other Permission --- TShockAPI/Commands.cs | 5 +++++ TShockAPI/Permissions.cs | 3 +++ 2 files changed, 8 insertions(+) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index b2162eab..4ef1e42c 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -5194,6 +5194,11 @@ namespace TShockAPI TSPlayer playerToGod; if (args.Parameters.Count > 0) { + if (!args.Player.Group.HasPermission(Permissions.godmodeother)) + { + args.Player.SendErrorMessage("You do not have permission to god mode another player!"); + return; + } string plStr = String.Join(" ", args.Parameters); var players = TShock.Utils.FindPlayer(plStr); if (players.Count == 0) diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs index d970182a..687f474d 100644 --- a/TShockAPI/Permissions.cs +++ b/TShockAPI/Permissions.cs @@ -349,6 +349,9 @@ namespace TShockAPI [Description("Player recovers health as damage is taken. Can be one shotted.")] public static readonly string godmode = "tshock.godmode"; + [Description("User can godmode other players")] + public static readonly string godmodeother = "tshock.godmode.other"; + [Description("Player can chat")] public static readonly string canchat = "tshock.canchat"; From 10de490c86bbbb39057774e9ec8b232efe4b4b08 Mon Sep 17 00:00:00 2001 From: PhoenixICE Date: Mon, 23 Feb 2015 09:30:05 +1100 Subject: [PATCH 07/60] Tab formatting issue --- TShockAPI/Commands.cs | 10 +++++----- TShockAPI/Permissions.cs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 4ef1e42c..a2443e91 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -5194,11 +5194,11 @@ namespace TShockAPI TSPlayer playerToGod; if (args.Parameters.Count > 0) { - if (!args.Player.Group.HasPermission(Permissions.godmodeother)) - { - args.Player.SendErrorMessage("You do not have permission to god mode another player!"); - return; - } + if (!args.Player.Group.HasPermission(Permissions.godmodeother)) + { + args.Player.SendErrorMessage("You do not have permission to god mode another player!"); + return; + } string plStr = String.Join(" ", args.Parameters); var players = TShock.Utils.FindPlayer(plStr); if (players.Count == 0) diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs index 687f474d..e9d943f3 100644 --- a/TShockAPI/Permissions.cs +++ b/TShockAPI/Permissions.cs @@ -349,8 +349,8 @@ namespace TShockAPI [Description("Player recovers health as damage is taken. Can be one shotted.")] public static readonly string godmode = "tshock.godmode"; - [Description("User can godmode other players")] - public static readonly string godmodeother = "tshock.godmode.other"; + [Description("User can godmode other players")] + public static readonly string godmodeother = "tshock.godmode.other"; [Description("Player can chat")] public static readonly string canchat = "tshock.canchat"; From 9e2ff2e2a2b48b1953a95389f54633dafcd1b440 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Sun, 22 Feb 2015 20:16:03 -0700 Subject: [PATCH 08/60] Make logfile a public getter --- TShockAPI/Log.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/Log.cs b/TShockAPI/Log.cs index b2bb540f..27d4f512 100644 --- a/TShockAPI/Log.cs +++ b/TShockAPI/Log.cs @@ -37,7 +37,7 @@ namespace TShockAPI public static class Log { - private static string _filename; + public static string _filename { get; private set; } private static LogLevel _logLevel; private static StreamWriter _logWriter; From 75e12f8163e2b5cecc37ad70cff6a2c8aeb6f8af Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 23 Feb 2015 00:02:14 -0700 Subject: [PATCH 09/60] Remove irc from readme; add plugin downloads --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13d50d62..4dd27507 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,11 @@ TShock is a server modification for Terraria, written in C#, and based upon the Feeling like helping out? Want to find an awesome server? Some awesome plugins? -* [Website & Forums](http://tshock.co/xf/) +* [Website & Forums](https://tshock.co/xf/) * [Wiki](https://tshock.atlassian.net/wiki/display/TSHOCKPLUGINS/Home) -* [IRC: #tshock @ irc.rizon.net](http://tshock.co/xf/index.php?ezirc/) ## Download * [Github Releases](https://github.com/TShock/TShock/releases) +* [Plugins](https://tshock.co/xf/index.php?resources/) * [Download Archive](https://github.com/TShock/TShock/downloads) From 2f24484012ff620c0dc49d0c26b96c779d695f10 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 23 Feb 2015 00:04:01 -0700 Subject: [PATCH 10/60] Stop clicking this link please --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4dd27507..607c318c 100644 --- a/README.md +++ b/README.md @@ -28,4 +28,4 @@ Feeling like helping out? Want to find an awesome server? Some awesome plugins? * [Github Releases](https://github.com/TShock/TShock/releases) * [Plugins](https://tshock.co/xf/index.php?resources/) -* [Download Archive](https://github.com/TShock/TShock/downloads) +* [Very, very old versions of TShock](https://github.com/TShock/TShock/downloads) From 183084d60fde697b9ce0238fd6b81b7968c68b3b Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Tue, 24 Feb 2015 19:08:30 -0700 Subject: [PATCH 11/60] Minor changes pertaining to spacing & some unclear messages --- TShockAPI/Commands.cs | 2 +- TShockAPI/TShock.cs | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index a2443e91..58d7f132 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -4367,7 +4367,7 @@ namespace TShockAPI } else { - string reason = "misbehavior"; + string reason = "Banned by Administrator"; if (args.Parameters.Count > 1) reason = String.Join(" ", args.Parameters.ToArray(), 1, args.Parameters.Count - 1); var plr = players[0]; diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 1346113a..2df3078d 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -46,7 +46,7 @@ namespace TShockAPI public class TShock : TerrariaPlugin { public static readonly Version VersionNum = Assembly.GetExecutingAssembly().GetName().Version; - public static readonly string VersionCodename = "And the great beast rose from its slumber, ready to take on the world again."; + public static readonly string VersionCodename = "2015!!"; public static string SavePath = "tshock"; private const string LogFormatDefault = "yyyy-MM-dd_HH-mm-ss"; @@ -244,7 +244,7 @@ namespace TShockAPI if (Config.EnableGeoIP && File.Exists(geoippath)) Geo = new GeoIPCountry(geoippath); - Log.ConsoleInfo(string.Format("|> Version {0} ({1}) now running.", Version, VersionCodename)); + Log.ConsoleInfo(string.Format("TShock {0} ({1}) now running.", Version, VersionCodename)); ServerApi.Hooks.GamePostInitialize.Register(this, OnPostInit); ServerApi.Hooks.GameUpdate.Register(this, OnUpdate); @@ -262,7 +262,7 @@ namespace TShockAPI ServerApi.Hooks.ProjectileSetDefaults.Register(this, OnProjectileSetDefaults); ServerApi.Hooks.WorldStartHardMode.Register(this, OnStartHardMode); ServerApi.Hooks.WorldSave.Register(this, SaveManager.Instance.OnSaveWorld); - ServerApi.Hooks.WorldChristmasCheck.Register(this, OnXmasCheck); + ServerApi.Hooks.WorldChristmasCheck.Register(this, OnXmasCheck); ServerApi.Hooks.WorldHalloweenCheck.Register(this, OnHalloweenCheck); ServerApi.Hooks.NetNameCollision.Register(this, NetHooks_NameCollision); Hooks.PlayerHooks.PlayerPreLogin += OnPlayerPreLogin; @@ -344,7 +344,7 @@ namespace TShockAPI ServerApi.Hooks.WorldChristmasCheck.Deregister(this, OnXmasCheck); ServerApi.Hooks.WorldHalloweenCheck.Deregister(this, OnHalloweenCheck); ServerApi.Hooks.NetNameCollision.Deregister(this, NetHooks_NameCollision); - TShockAPI.Hooks.PlayerHooks.PlayerPostLogin -= OnPlayerLogin; + TShockAPI.Hooks.PlayerHooks.PlayerPostLogin -= OnPlayerLogin; if (File.Exists(Path.Combine(SavePath, "tshock.pid"))) { @@ -430,17 +430,17 @@ namespace TShockAPI } } - private void OnXmasCheck(ChristmasCheckEventArgs args) - { - if (args.Handled) - return; + private void OnXmasCheck(ChristmasCheckEventArgs args) + { + if (args.Handled) + return; - if(Config.ForceXmas) - { - args.Xmas = true; - args.Handled = true; - } + if(Config.ForceXmas) + { + args.Xmas = true; + args.Handled = true; } + } private void OnHalloweenCheck(HalloweenCheckEventArgs args) { @@ -1057,7 +1057,7 @@ namespace TShockAPI } catch (Exception ex) { - Log.ConsoleError("Command exception"); + Log.ConsoleError("An exeption occurred executing a command."); Log.Error(ex.ToString()); } } From 764971853059459e31c7a8c0e09811dba6fba50b Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Tue, 24 Feb 2015 19:12:22 -0700 Subject: [PATCH 12/60] Some people really like uneven spacing --- TShockAPI/Commands.cs | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 58d7f132..dae18214 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -608,25 +608,25 @@ namespace TShockAPI player.SendErrorMessage("Invalid command entered. Type {0}help for a list of valid commands.", TShock.Config.CommandSpecifier); return true; } - foreach (Command cmd in cmds) - { - if (!cmd.CanRun(player)) - { - TShock.Utils.SendLogs(string.Format("{0} tried to execute {1}{2}.", player.Name, TShock.Config.CommandSpecifier, cmdText), Color.PaleVioletRed, player); - player.SendErrorMessage("You do not have access to this command."); - } - else if (!cmd.AllowServer && !player.RealPlayer) - { - player.SendErrorMessage("You must use this command in-game."); - } - else - { - if (cmd.DoLog) - TShock.Utils.SendLogs(string.Format("{0} executed: {1}{2}.", player.Name, TShock.Config.CommandSpecifier, cmdText), Color.PaleVioletRed, player); - cmd.Run(cmdText, player, args); - } - } - return true; + foreach (Command cmd in cmds) + { + if (!cmd.CanRun(player)) + { + TShock.Utils.SendLogs(string.Format("{0} tried to execute {1}{2}.", player.Name, TShock.Config.CommandSpecifier, cmdText), Color.PaleVioletRed, player); + player.SendErrorMessage("You do not have access to this command."); + } + else if (!cmd.AllowServer && !player.RealPlayer) + { + player.SendErrorMessage("You must use this command in-game."); + } + else + { + if (cmd.DoLog) + TShock.Utils.SendLogs(string.Format("{0} executed: {1}{2}.", player.Name, TShock.Config.CommandSpecifier, cmdText), Color.PaleVioletRed, player); + cmd.Run(cmdText, player, args); + } + } + return true; } /// From f2b2da90d73071572c38bdac9be005f95dd6861f Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Tue, 24 Feb 2015 20:55:59 -0700 Subject: [PATCH 13/60] Added silent commands & other stuff (see below) 1. Removed old code. 2. Added silent command prefix & supporting code 3. Region ban & spawnmob support silence --- TShockAPI/Commands.cs | 80 ++++++++++++++++++++++++++++++++--------- TShockAPI/ConfigFile.cs | 5 ++- TShockAPI/TShock.cs | 3 +- 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index dae18214..3609bea2 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -37,6 +37,7 @@ namespace TShockAPI { public string Message { get; private set; } public TSPlayer Player { get; private set; } + public bool Silent { get; private set; } /// /// Parameters passed to the arguement. Does not include the command name. @@ -54,6 +55,15 @@ namespace TShockAPI Message = message; Player = ply; Parameters = args; + Silent = false; + } + + public CommandArgs(string message, bool silent, TSPlayer ply, List args) + { + Message = message; + Player = ply; + Parameters = args; + Silent = silent; } } @@ -124,19 +134,19 @@ namespace TShockAPI CommandDelegate = cmd; DoLog = true; HelpText = "No help available."; - HelpDesc = null; + HelpDesc = null; Names = new List(names); Permissions = new List(); } - public bool Run(string msg, TSPlayer ply, List parms) + public bool Run(string msg, bool silent, TSPlayer ply, List parms) { if (!CanRun(ply)) return false; try { - CommandDelegate(new CommandArgs(msg, ply, parms)); + CommandDelegate(new CommandArgs(msg, silent, ply, parms)); } catch (Exception e) { @@ -147,6 +157,11 @@ namespace TShockAPI return true; } + public bool Run(string msg, TSPlayer ply, List parms) + { + return Run(msg, false, ply, parms); + } + public bool HasAlias(string name) { return Names.Contains(name); @@ -583,6 +598,11 @@ namespace TShockAPI public static bool HandleCommand(TSPlayer player, string text) { string cmdText = text.Remove(0, 1); + string cmdPrefix = text[0].ToString(); + bool silent = false; + + if (cmdPrefix == TShock.Config.CommandSilentSpecifier) + silent = true; var args = ParseParameters(cmdText); if (args.Count < 1) @@ -622,8 +642,8 @@ namespace TShockAPI else { if (cmd.DoLog) - TShock.Utils.SendLogs(string.Format("{0} executed: {1}{2}.", player.Name, TShock.Config.CommandSpecifier, cmdText), Color.PaleVioletRed, player); - cmd.Run(cmdText, player, args); + TShock.Utils.SendLogs(string.Format("{0} executed: {1}{2}.", player.Name, silent ? TShock.Config.CommandSilentSpecifier : TShock.Config.CommandSpecifier, cmdText), Color.PaleVioletRed, player); + cmd.Run(cmdText, silent, player, args); } } return true; @@ -1152,9 +1172,27 @@ namespace TShockAPI var knownIps = JsonConvert.DeserializeObject>(user.KnownIps); TShock.Bans.AddBan(knownIps.Last(), user.Name, user.UUID, reason, false, args.Player.UserAccountName); if (String.IsNullOrWhiteSpace(args.Player.UserAccountName)) - TSPlayer.All.SendInfoMessage("{0} was {1}banned for '{2}'.", user.Name, force ? "force " : "", reason); + { + if (args.Silent) + { + args.Player.SendInfoMessage("{0} was {1}banned for '{2}'.", user.Name, force ? "Force " : "", reason); + } + else + { + TSPlayer.All.SendInfoMessage("{0} was {1}banned for '{2}'.", user.Name, force ? "Force " : "", reason); + } + } else - TSPlayer.All.SendInfoMessage("{0} {1}banned {2} for '{3}'.", args.Player.Name, force ? "force " : "", user.Name, reason); + { + if (args.Silent) + { + args.Player.SendInfoMessage("{0}banned {1} for '{2}'.", force ? "Force " : "", user.Name, reason); + } + else + { + TSPlayer.All.SendInfoMessage("{0} {1}banned {2} for '{3}'.", args.Player.Name, force ? "Force " : "", user.Name, reason); + } + } } } else @@ -1229,7 +1267,9 @@ namespace TShockAPI } } else + { args.Player.SendErrorMessage("Invalid player or account!"); + } } else if (players.Count > 1) TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); @@ -1563,7 +1603,7 @@ namespace TShockAPI private static void CheckUpdates(CommandArgs args) { - args.Player.SendInfoMessage("An update check has been queued."); + args.Player.SendInfoMessage("An update check has been queued."); try { TShock.UpdateManager.UpdateCheck(null); @@ -1575,12 +1615,6 @@ namespace TShockAPI } } - private static void UpdatePlugins(CommandArgs args) - { - args.Player.SendInfoMessage("Starting plugin update process:"); - args.Player.SendInfoMessage("This may take a while, do not turn off the server!"); - } - private static void ManageRest(CommandArgs args) { string subCommand = "help"; @@ -1947,7 +1981,14 @@ namespace TShockAPI if (npc.type >= 1 && npc.type < Main.maxNPCTypes && npc.type != 113) { TSPlayer.Server.SpawnNPC(npc.type, npc.name, amount, args.Player.TileX, args.Player.TileY, 50, 20); - TSPlayer.All.SendSuccessMessage("{0} has spawned {1} {2} time(s).", args.Player.Name, npc.name, amount); + if (args.Silent) + { + args.Player.SendSuccessMessage("Spawned {0} {1} time(s).", npc.name, amount); + } + else + { + TSPlayer.All.SendSuccessMessage("{0} has spawned {1} {2} time(s).", args.Player.Name, npc.name, amount); + } } else if (npc.type == 113) { @@ -1957,7 +1998,14 @@ namespace TShockAPI return; } NPC.SpawnWOF(new Vector2(args.Player.X, args.Player.Y)); - TSPlayer.All.SendSuccessMessage("{0} has spawned Wall of Flesh!", args.Player.Name); + if (args.Silent) + { + args.Player.SendSuccessMessage("Spawned Wall of Flesh!"); + } + else + { + TSPlayer.All.SendSuccessMessage("{0} has spawned a Wall of Flesh!", args.Player.Name); + } } else { diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs index 2b4726d8..be24b8b8 100755 --- a/TShockAPI/ConfigFile.cs +++ b/TShockAPI/ConfigFile.cs @@ -367,8 +367,11 @@ namespace TShockAPI [Description("Allows anyone to break grass, pots, etc.")] public bool AllowCutTilesAndBreakables = false; - [Description("Specifies which string starts a command")] + [Description("Specifies which string starts a command.")] public string CommandSpecifier = "/"; + + [Description("Specifies which string starts a command silently.")] + public string CommandSilentSpecifier = "."; [Description("Kicks a hardcore player on death.")] public bool KickOnHardcoreDeath; diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 2df3078d..97826f51 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -1049,7 +1049,8 @@ namespace TShockAPI return; }*/ - if (args.Text.StartsWith(Config.CommandSpecifier) && !string.IsNullOrWhiteSpace(args.Text.Substring(1))) + if ((args.Text.StartsWith(Config.CommandSpecifier) || args.Text.StartsWith(Config.CommandSilentSpecifier)) + && !string.IsNullOrWhiteSpace(args.Text.Substring(1))) { try { From 192ee915aee042ce7ec863d9f6b9f13fb9a76156 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Tue, 24 Feb 2015 21:20:33 -0700 Subject: [PATCH 14/60] Another batch of commands support silence --- TShockAPI/Commands.cs | 54 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 3609bea2..98753adb 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -1261,9 +1261,27 @@ namespace TShockAPI var knownIps = JsonConvert.DeserializeObject>(user.KnownIps); TShock.Bans.AddBan(knownIps.Last(), user.Name, user.UUID, reason, false, args.Player.UserAccountName, DateTime.UtcNow.AddSeconds(time).ToString("s")); if (String.IsNullOrWhiteSpace(args.Player.UserAccountName)) - TSPlayer.All.SendInfoMessage("{0} was {1}banned for '{2}'.", user.Name, force ? "force " : "", reason); + { + if (args.Silent) + { + args.Player.SendInfoMessage("{0} was {1}banned for '{2}'.", user.Name, force ? "force " : "", reason); + } + else + { + TSPlayer.All.SendInfoMessage("{0} was {1}banned for '{2}'.", user.Name, force ? "force " : "", reason); + } + } else - TSPlayer.All.SendInfoMessage("{0} {1}banned {2} for '{3}'.", args.Player.Name, force ? "force " : "", user.Name, reason); + { + if (args.Silent) + { + args.Player.SendInfoMessage("[broken name] was {1}banned for '{2}'.", force ? "force " : "", reason); + } + else + { + TSPlayer.All.SendInfoMessage("{0} {1}banned [broken name] for '{3}'.", args.Player.Name, force ? "force " : "", reason); + } + } } } else @@ -1285,11 +1303,27 @@ namespace TShockAPI false, args.Player.Name, DateTime.UtcNow.AddSeconds(time).ToString("s"))) { players[0].Disconnect(String.Format("Banned: {0}", reason)); - string verb = args.Player.RealPlayer ? "force " : ""; + string verb = args.Player.RealPlayer ? "Force " : ""; if (args.Player.RealPlayer) - TSPlayer.All.SendSuccessMessage("{0} {1}banned {2} for '{3}'", args.Player.Name, verb, players[0].Name, reason); + if (args.Silent) + { + args.Player.SendSuccessMessage("{0}banned {1} for '{2}'", verb, players[0].Name, reason); + } + else + { + TSPlayer.All.SendSuccessMessage("{0} {1}banned {2} for '{3}'", args.Player.Name, verb, players[0].Name, reason); + } else - TSPlayer.All.SendSuccessMessage("{0} was {1}banned for '{2}'", players[0].Name, verb, reason); + { + if (args.Silent) + { + args.Player.SendSuccessMessage("{0}banned {1} for '{2}'", verb, players[0].Name, reason); + } + else + { + TSPlayer.All.SendSuccessMessage("{0} was {1}banned for '{2}'", players[0].Name, verb, reason); + } + } } else args.Player.SendErrorMessage("Failed to ban {0}, check logs.", players[0].Name); @@ -1505,14 +1539,20 @@ namespace TShockAPI { TShock.Config.ForceHalloween = !TShock.Config.ForceHalloween; Main.checkHalloween(); - TSPlayer.All.SendInfoMessage("{0} {1}abled halloween mode!", args.Player.Name, (TShock.Config.ForceHalloween ? "en" : "dis")); + if (args.Silent) + args.Player.SendInfoMessage("{0}abled halloween mode!", (TShock.Config.ForceHalloween ? "en" : "dis")); + else + TSPlayer.All.SendInfoMessage("{0} {1}abled halloween mode!", args.Player.Name, (TShock.Config.ForceHalloween ? "en" : "dis")); } private static void ForceXmas(CommandArgs args) { TShock.Config.ForceXmas = !TShock.Config.ForceXmas; Main.checkXMas(); - TSPlayer.All.SendInfoMessage("{0} {1}abled Christmas mode!", args.Player.Name, (TShock.Config.ForceXmas ? "en" : "dis")); + if (args.Silent) + args.Player.SendInfoMessage("{0}abled Christmas mode!", (TShock.Config.ForceXmas ? "en" : "dis")); + else + TSPlayer.All.SendInfoMessage("{0} {1}abled Christmas mode!", args.Player.Name, (TShock.Config.ForceXmas ? "en" : "dis")); } private static void TempGroup(CommandArgs args) From c9dcc3d227278c288802a329d9d206fad33223e6 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Tue, 24 Feb 2015 21:26:16 -0700 Subject: [PATCH 15/60] Full, blood, and eclipse moon phases support silence DropMeteor now supports broadcasting to all and silence --- TShockAPI/Commands.cs | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 98753adb..d9296683 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -1711,29 +1711,51 @@ namespace TShockAPI #region Cause Events and Spawn Monsters Commands - private static void DropMeteor(CommandArgs args) + private static void DropMeteor(CommandArgs args) { WorldGen.spawnMeteor = false; WorldGen.dropMeteor(); - args.Player.SendInfoMessage("A meteor has been triggered."); + if (args.Silent) + { + args.Player.SendInfoMessage("A meteor has been triggered."); + } + else { + TSPlayer.All.SendInfoMessage("{0} triggered a meteor.", args.Player.Name); + } } private static void Fullmoon(CommandArgs args) { TSPlayer.Server.SetFullMoon(); - TSPlayer.All.SendInfoMessage("{0} started a full moon.", args.Player.Name); + if (args.Silent) + { + args.Player.SendInfoMessage("Started a full moon."); + } else { + TSPlayer.All.SendInfoMessage("{0} started a full moon.", args.Player.Name); + } } private static void Bloodmoon(CommandArgs args) { TSPlayer.Server.SetBloodMoon(!Main.bloodMoon); - TSPlayer.All.SendInfoMessage("{0} {1}ed a blood moon.", args.Player.Name, Main.bloodMoon ? "start" : "stopp"); + if (args.Silent) + { + args.Player.SendInfoMessage("{0}ed a blood moon.", Main.bloodMoon ? "start" : "stopp"); + } else { + TSPlayer.All.SendInfoMessage("{0} {1}ed a blood moon.", args.Player.Name, Main.bloodMoon ? "start" : "stopp"); + } } private static void Eclipse(CommandArgs args) { TSPlayer.Server.SetEclipse(!Main.eclipse); - TSPlayer.All.SendInfoMessage("{0} {1}ed an eclipse.", args.Player.Name, Main.eclipse ? "start" : "stopp"); + if (args.Silent) + { + args.Player.SendInfoMessage("{0}ed an eclipse.", Main.eclipse ? "start" : "stopp"); + } + else { + TSPlayer.All.SendInfoMessage("{0} {1}ed an eclipse.", args.Player.Name, Main.eclipse ? "start" : "stopp"); + } } private static void Invade(CommandArgs args) From 13756360bb7b079d4ff16a926ee8831dc6cde0c9 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Tue, 24 Feb 2015 21:38:25 -0700 Subject: [PATCH 16/60] Slightly more commands support silence --- TShockAPI/Commands.cs | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index d9296683..ea1d521d 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -3497,7 +3497,13 @@ namespace TShockAPI if (String.Equals(args.Parameters[0], "default", StringComparison.CurrentCultureIgnoreCase)) { TShock.Config.DefaultMaximumSpawns = NPC.defaultMaxSpawns = 5; - TSPlayer.All.SendInfoMessage("{0} changed the maximum spawns to 5.", args.Player.Name); + if (args.Silent) + { + args.Player.SendInfoMessage("Changed the maximum spawns to 5."); + } + else { + TSPlayer.All.SendInfoMessage("{0} changed the maximum spawns to 5.", args.Player.Name); + } return; } @@ -3509,7 +3515,13 @@ namespace TShockAPI } TShock.Config.DefaultMaximumSpawns = NPC.defaultMaxSpawns = maxSpawns; - TSPlayer.All.SendInfoMessage("{0} changed the maximum spawns to {1}.", args.Player.Name, maxSpawns); + if (args.Silent) + { + args.Player.SendInfoMessage("Changed the maximum spawns to {0}.", maxSpawns); + } + else { + TSPlayer.All.SendInfoMessage("{0} changed the maximum spawns to {1}.", args.Player.Name, maxSpawns); + } } private static void SpawnRate(CommandArgs args) @@ -3523,7 +3535,13 @@ namespace TShockAPI if (String.Equals(args.Parameters[0], "default", StringComparison.CurrentCultureIgnoreCase)) { TShock.Config.DefaultSpawnRate = NPC.defaultSpawnRate = 600; - TSPlayer.All.SendInfoMessage("{0} changed the spawn rate to 600.", args.Player.Name); + if (args.Silent) + { + args.Player.SendInfoMessage("Changed the spawn rate to 600."); + } + else { + TSPlayer.All.SendInfoMessage("{0} changed the spawn rate to 600.", args.Player.Name); + } return; } @@ -3533,9 +3551,14 @@ namespace TShockAPI args.Player.SendWarningMessage("Invalid spawn rate!"); return; } - TShock.Config.DefaultSpawnRate = NPC.defaultSpawnRate = spawnRate; - TSPlayer.All.SendInfoMessage("{0} changed the spawn rate to {1}.", args.Player.Name, spawnRate); + if (args.Silent) + { + args.Player.SendInfoMessage("Changed the spawn rate to {0}."spawnRate); + } + else { + TSPlayer.All.SendInfoMessage("{0} changed the spawn rate to {1}.", args.Player.Name, spawnRate); + } } #endregion Server Config Commands @@ -4226,7 +4249,7 @@ namespace TShockAPI #region World Protection Commands - private static void ToggleAntiBuild(CommandArgs args) + private static void ToggleAntiBuild(CommandArgs args) { TShock.Config.DisableBuild = (TShock.Config.DisableBuild == false); TSPlayer.All.SendSuccessMessage(string.Format("Anti-build is now {0}.", (TShock.Config.DisableBuild ? "on" : "off"))); From e18ab504530c0d11bcdafb8a2f1ec12009776cc0 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Tue, 24 Feb 2015 21:42:06 -0700 Subject: [PATCH 17/60] Literally add a comma between two different things --- TShockAPI/Commands.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index ea1d521d..b7829574 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -3554,7 +3554,7 @@ namespace TShockAPI TShock.Config.DefaultSpawnRate = NPC.defaultSpawnRate = spawnRate; if (args.Silent) { - args.Player.SendInfoMessage("Changed the spawn rate to {0}."spawnRate); + args.Player.SendInfoMessage("Changed the spawn rate to {0}.", spawnRate); } else { TSPlayer.All.SendInfoMessage("{0} changed the spawn rate to {1}.", args.Player.Name, spawnRate); From 21cd90fa23e21f1bbf6017d24ae35916e8d44dfd Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Wed, 25 Feb 2015 00:09:54 -0700 Subject: [PATCH 18/60] Save world on last player exit; fixes #707 --- TShockAPI/TShock.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 97826f51..fdae3db9 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -1022,6 +1022,12 @@ namespace TShockAPI RememberedPos.InsertLeavePos(tsplr.Name, tsplr.IP, (int) (tsplr.X/16), (int) (tsplr.Y/16)); } } + + // The last player will leave after this hook is executed. + if (Utils.ActivePlayers() == 1) + { + SaveManager.Instance.SaveWorld(); + } } private void OnChat(ServerChatEventArgs args) From c215ff8e102ae0f42558ae3f6ce69eddee06e279 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Wed, 25 Feb 2015 00:26:47 -0700 Subject: [PATCH 19/60] Console title now says "zero" with "zero" players "online" --- TShockAPI/TShock.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index fdae3db9..436acbea 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -584,7 +584,7 @@ namespace TShockAPI private void OnPostInit(EventArgs args) { - SetConsoleTitle(); + SetConsoleTitle(false); if (!File.Exists(Path.Combine(SavePath, "auth.lck")) && !File.Exists(Path.Combine(SavePath, "authcode.txt"))) { var r = new Random((int) DateTime.Now.ToBinary()); @@ -838,14 +838,14 @@ namespace TShockAPI } } } - SetConsoleTitle(); + SetConsoleTitle(false); } - private void SetConsoleTitle() + private void SetConsoleTitle(bool empty) { Console.Title = string.Format("{0}{1}/{2} @ {3}:{4} (TerrariaShock v{5})", !string.IsNullOrWhiteSpace(Config.ServerName) ? Config.ServerName + " - " : "", - Utils.ActivePlayers(), + empty ? 0 : Utils.ActivePlayers(), Config.MaxSlots, Netplay.serverListenIP, Netplay.serverPort, Version); } @@ -1027,6 +1027,7 @@ namespace TShockAPI if (Utils.ActivePlayers() == 1) { SaveManager.Instance.SaveWorld(); + SetConsoleTitle(true); } } From 0459dfca11e3c0adc190f650b4fe7e4b2656e6c3 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Wed, 25 Feb 2015 14:52:28 -0700 Subject: [PATCH 20/60] Adds SQL logging from WhiteX's fork; closes #869 --- TShockAPI/BackupManager.cs | 6 +- TShockAPI/Commands.cs | 46 +++---- TShockAPI/ConfigFile.cs | 6 + TShockAPI/ILog.cs | 140 ++++++++++++++++++++ TShockAPI/Log.cs | 88 +++---------- TShockAPI/PacketBufferer.cs | 10 +- TShockAPI/SqlLog.cs | 248 +++++++++++++++++++++++++++++++++++ TShockAPI/TShock.cs | 86 +++++++------ TShockAPI/TShockAPI.csproj | 7 +- TShockAPI/TextLog.cs | 250 ++++++++++++++++++++++++++++++++++++ 10 files changed, 743 insertions(+), 144 deletions(-) create mode 100644 TShockAPI/ILog.cs create mode 100644 TShockAPI/SqlLog.cs create mode 100644 TShockAPI/TextLog.cs diff --git a/TShockAPI/BackupManager.cs b/TShockAPI/BackupManager.cs index 1882d0bb..5422160e 100644 --- a/TShockAPI/BackupManager.cs +++ b/TShockAPI/BackupManager.cs @@ -67,7 +67,7 @@ namespace TShockAPI SaveManager.Instance.SaveWorld(); Console.WriteLine("World backed up."); Console.ForegroundColor = ConsoleColor.Gray; - Log.Info(string.Format("World backed up ({0}).", Main.worldPathName)); + TShock.Log.Info(string.Format("World backed up ({0}).", Main.worldPathName)); Main.worldPathName = worldname; } @@ -76,8 +76,8 @@ namespace TShockAPI Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Backup failed!"); Console.ForegroundColor = ConsoleColor.Gray; - Log.Error("Backup failed!"); - Log.Error(ex.ToString()); + TShock.Log.Error("Backup failed!"); + TShock.Log.Error(ex.ToString()); } } diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index b7829574..fe911e99 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -151,7 +151,7 @@ namespace TShockAPI catch (Exception e) { ply.SendErrorMessage("Command failed, check logs for more details."); - Log.Error(e.ToString()); + TShock.Log.Error(e.ToString()); } return true; @@ -711,7 +711,7 @@ namespace TShockAPI { if (args.Player.LoginAttempts > TShock.Config.MaximumLoginAttempts && (TShock.Config.MaximumLoginAttempts != -1)) { - Log.Warn(String.Format("{0} ({1}) had {2} or more invalid login attempts and was kicked automatically.", + TShock.Log.Warn(String.Format("{0} ({1}) had {2} or more invalid login attempts and was kicked automatically.", args.Player.IP, args.Player.Name, TShock.Config.MaximumLoginAttempts)); TShock.Utils.Kick(args.Player, "Too many invalid login attempts."); return; @@ -799,7 +799,7 @@ namespace TShockAPI } args.Player.SendSuccessMessage("Authenticated as " + user.Name + " successfully."); - Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + user.Name + "."); + TShock.Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + user.Name + "."); if ((args.Player.LoginHarassed) && (TShock.Config.RememberLeavePos)) { if (TShock.RememberedPos.GetLeavePos(args.Player.Name, args.Player.IP) != Vector2.Zero) @@ -824,14 +824,14 @@ namespace TShockAPI { args.Player.SendErrorMessage("Invalid password!"); } - Log.Warn(args.Player.IP + " failed to authenticate as user: " + user.Name + "."); + TShock.Log.Warn(args.Player.IP + " failed to authenticate as user: " + user.Name + "."); args.Player.LoginAttempts++; } } catch (Exception ex) { args.Player.SendErrorMessage("There was an error processing your request."); - Log.Error(ex.ToString()); + TShock.Log.Error(ex.ToString()); } } @@ -847,12 +847,12 @@ namespace TShockAPI { args.Player.SendSuccessMessage("You changed your password!"); 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 + "."); + TShock.Log.ConsoleInfo(args.Player.IP + " named " + args.Player.Name + " changed the password of account " + user.Name + "."); } else { args.Player.SendErrorMessage("You failed to change your password!"); - Log.ConsoleError(args.Player.IP + " named " + args.Player.Name + " failed to change password for account: " + + TShock.Log.ConsoleError(args.Player.IP + " named " + args.Player.Name + " failed to change password for account: " + user.Name + "."); } } @@ -864,7 +864,7 @@ namespace TShockAPI catch (UserManagerException ex) { args.Player.SendErrorMessage("Sorry, an error occured: " + ex.Message + "."); - Log.ConsoleError("PasswordUser returned an error: " + ex); + TShock.Log.ConsoleError("PasswordUser returned an error: " + ex); } } @@ -898,18 +898,18 @@ namespace TShockAPI args.Player.SendSuccessMessage("Account \"{0}\" has been registered.", user.Name); args.Player.SendSuccessMessage("Your password is {0}.", user.Password); TShock.Users.AddUser(user); - Log.ConsoleInfo("{0} registered an account: \"{1}\".", args.Player.Name, user.Name); + TShock.Log.ConsoleInfo("{0} registered an account: \"{1}\".", args.Player.Name, user.Name); } else { args.Player.SendErrorMessage("Account " + user.Name + " has already been registered."); - Log.ConsoleInfo(args.Player.Name + " failed to register an existing account: " + user.Name); + TShock.Log.ConsoleInfo(args.Player.Name + " failed to register an existing account: " + user.Name); } } catch (UserManagerException ex) { args.Player.SendErrorMessage("Sorry, an error occured: " + ex.Message + "."); - Log.ConsoleError("RegisterUser returned an error: " + ex); + TShock.Log.ConsoleError("RegisterUser returned an error: " + ex); } } @@ -939,7 +939,7 @@ namespace TShockAPI { TShock.Users.AddUser(user); args.Player.SendSuccessMessage("Account " + user.Name + " has been added to group " + user.Group + "!"); - Log.ConsoleInfo(args.Player.Name + " added Account " + user.Name + " to group " + user.Group); + TShock.Log.ConsoleInfo(args.Player.Name + " added Account " + user.Name + " to group " + user.Group); } catch (GroupNotExistsException e) { @@ -952,7 +952,7 @@ namespace TShockAPI catch (UserManagerException e) { args.Player.SendErrorMessage("User " + user.Name + " could not be added, check console for details."); - Log.ConsoleError(e.ToString()); + TShock.Log.ConsoleError(e.ToString()); } } else @@ -970,7 +970,7 @@ namespace TShockAPI { TShock.Users.RemoveUser(user); args.Player.SendSuccessMessage("Account removed successfully."); - Log.ConsoleInfo(args.Player.Name + " successfully deleted account: " + args.Parameters[1] + "."); + TShock.Log.ConsoleInfo(args.Player.Name + " successfully deleted account: " + args.Parameters[1] + "."); } catch (UserNotExistException e) { @@ -979,7 +979,7 @@ namespace TShockAPI catch (UserManagerException ex) { args.Player.SendMessage(ex.Message, Color.Red); - Log.ConsoleError(ex.ToString()); + TShock.Log.ConsoleError(ex.ToString()); } } @@ -994,7 +994,7 @@ namespace TShockAPI try { TShock.Users.SetUserPassword(user, args.Parameters[2]); - Log.ConsoleInfo(args.Player.Name + " changed the password of account " + user.Name); + TShock.Log.ConsoleInfo(args.Player.Name + " changed the password of account " + user.Name); args.Player.SendSuccessMessage("Password change succeeded for " + user.Name + "."); } catch (UserNotExistException e) @@ -1004,7 +1004,7 @@ namespace TShockAPI catch (UserManagerException e) { args.Player.SendErrorMessage("Password change for " + user.Name + " failed! Check console!"); - Log.ConsoleError(e.ToString()); + TShock.Log.ConsoleError(e.ToString()); } } else @@ -1023,7 +1023,7 @@ namespace TShockAPI try { TShock.Users.SetUserGroup(user, args.Parameters[2]); - Log.ConsoleInfo(args.Player.Name + " changed account " + user.Name + " to group " + args.Parameters[2] + "."); + TShock.Log.ConsoleInfo(args.Player.Name + " changed account " + user.Name + " to group " + args.Parameters[2] + "."); args.Player.SendSuccessMessage("Account " + user.Name + " has been changed to group " + args.Parameters[2] + "!"); } catch (GroupNotExistsException e) @@ -1626,7 +1626,7 @@ namespace TShockAPI { if (ServerApi.RunningMono) { - Log.ConsoleInfo("Sorry, this command has not yet been implemented in Mono."); + TShock.Log.ConsoleInfo("Sorry, this command has not yet been implemented in Mono."); } else { @@ -3688,7 +3688,7 @@ namespace TShockAPI } plr.DamagePlayer(damage); TSPlayer.All.SendInfoMessage("{0} slapped {1} for {2} damage.", args.Player.Name, plr.Name, damage); - Log.Info("{0} slapped {1} for {2} damage.", args.Player.Name, plr.Name, damage); + TShock.Log.Info("{0} slapped {1} for {2} damage.", args.Player.Name, plr.Name, damage); } } @@ -4381,7 +4381,7 @@ namespace TShockAPI if (TShock.AuthToken == 0) { args.Player.SendWarningMessage("Auth is disabled. This incident has been logged."); - Log.Warn(args.Player.IP + " attempted to use /auth even though it's disabled."); + TShock.Log.Warn(args.Player.IP + " attempted to use /auth even though it's disabled."); return; } int givenCode = Convert.ToInt32(args.Parameters[0]); @@ -4398,7 +4398,7 @@ namespace TShockAPI } catch (UserManagerException ex) { - Log.ConsoleError(ex.ToString()); + TShock.Log.ConsoleError(ex.ToString()); args.Player.SendErrorMessage(ex.Message); } return; @@ -4414,7 +4414,7 @@ namespace TShockAPI } args.Player.SendErrorMessage("Incorrect auth code. This incident has been logged."); - Log.Warn(args.Player.IP + " attempted to use an incorrect auth code."); + TShock.Log.Warn(args.Player.IP + " attempted to use an incorrect auth code."); } private static void AuthVerify(CommandArgs args) diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs index be24b8b8..f0068762 100755 --- a/TShockAPI/ConfigFile.cs +++ b/TShockAPI/ConfigFile.cs @@ -325,6 +325,12 @@ namespace TShockAPI [Description("The path of the directory where logs should be written into.")] public string LogPath = "tshock"; + [Description("Save logs to an SQL database instead of a text file. Default = false")] + public bool UseSqlLogs = false; + + [Description("Number of times the SQL log must fail to insert logs before falling back to the text log")] + public int RevertToTextLogsOnSqlFailures = 10; + [Description("Prevents players from placing tiles with an invalid style.")] public bool PreventInvalidPlaceStyle = true; diff --git a/TShockAPI/ILog.cs b/TShockAPI/ILog.cs new file mode 100644 index 00000000..906498ce --- /dev/null +++ b/TShockAPI/ILog.cs @@ -0,0 +1,140 @@ +/* +TShock, a server mod for Terraria +Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +using System; + +namespace TShockAPI +{ + [Flags] + public enum LogLevel + { + None = 0, + Debug = 1, + Info = 2, + Warning = 4, + Error = 8, + Data = 16, + All = 31 + } + + /// + /// Logging interface + /// + public interface ILog + { + /// + /// Log name + /// + string Name { get; } + + /// + /// Returns true if the ILog is using SQL or false if not + /// + bool Sql { get; } + + /// + /// Checks whether the log level contains the specified flag. + /// + /// The value to check. + bool MayWriteType(LogLevel type); + + /// + /// Writes an informative string to the log and to the console. + /// + /// The message to be written. + void ConsoleInfo(string message); + /// + /// Writes an informative string to the log and to the console. + /// + /// The format of the message to be written. + /// The format arguments. + void ConsoleInfo(string format, params object[] args); + + /// + /// Writes an error message to the log and to the console. + /// + /// The message to be written. + void ConsoleError(string message); + /// + /// Writes an error message to the log and to the console. + /// + /// The format of the message to be written. + /// The format arguments. + void ConsoleError(string format, params object[] args); + + /// + /// Writes a warning to the log. + /// + /// The message to be written. + void Warn(string message); + /// + /// Writes a warning to the log. + /// + /// The format of the message to be written. + /// The format arguments. + void Warn(string format, params object[] args); + + /// + /// Writes an error to the log. + /// + /// The message to be written. + void Error(string message); + /// + /// Writes an error to the log. + /// + /// The format of the message to be written. + /// The format arguments. + void Error(string format, params object[] args); + + /// + /// Writes an informative string to the log. + /// + /// The message to be written. + void Info(string message); + /// + /// Writes an informative string to the log. + /// + /// The format of the message to be written. + /// The format arguments. + void Info(string format, params object[] args); + + /// + /// Writes data to the log. + /// + /// The message to be written. + void Data(string message); + /// + /// Writes data to the log. + /// + /// The format of the message to be written. + /// The format arguments. + void Data(string format, params object[] args); + + /// + /// Writes a message to the log + /// + /// Message to write + /// LogLevel assosciated with the message + void Write(string message, LogLevel level); + + /// + /// Dispose the Log + /// + void Dispose(); + } +} diff --git a/TShockAPI/Log.cs b/TShockAPI/Log.cs index 27d4f512..782dbe36 100644 --- a/TShockAPI/Log.cs +++ b/TShockAPI/Log.cs @@ -17,57 +17,16 @@ along with this program. If not, see . */ using System; -using System.Diagnostics; -using System.Globalization; -using System.IO; namespace TShockAPI { - [Flags] - public enum LogLevel - { - None = 0, - Debug = 1, - Info = 2, - Warning = 4, - Error = 8, - Data = 16, - All = 31 - } - public static class Log { - public static string _filename { get; private set; } - 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; - - _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); - } - /// /// Writes data to the log file. /// /// The message to be written. + [Obsolete("Please use TShock.Log.Data")] public static void Data(String message) { Write(message, LogLevel.Data); @@ -78,6 +37,7 @@ namespace TShockAPI /// /// The format of the message to be written. /// The format arguments. + [Obsolete("Please use TShock.Log.Data")] public static void Data(string format, params object[] args) { Data(String.Format(format, args)); @@ -87,6 +47,7 @@ namespace TShockAPI /// Writes an error to the log file. /// /// The message to be written. + [Obsolete("Please use TShock.Log.Error")] public static void Error(String message) { Write(message, LogLevel.Error); @@ -97,6 +58,7 @@ namespace TShockAPI /// /// The format of the message to be written. /// The format arguments. + [Obsolete("Please use TShock.Log.Error")] public static void Error(string format, params object[] args) { Error(String.Format(format, args)); @@ -106,6 +68,7 @@ namespace TShockAPI /// Writes an error to the log file. /// /// The message to be written. + [Obsolete("Please use TShock.Log.ConsoleError")] public static void ConsoleError(String message) { Console.ForegroundColor = ConsoleColor.Red; @@ -119,6 +82,7 @@ namespace TShockAPI /// /// The format of the message to be written. /// The format arguments. + [Obsolete("Please use TShock.Log.ConsoleError")] public static void ConsoleError(string format, params object[] args) { ConsoleError(String.Format(format, args)); @@ -128,6 +92,7 @@ namespace TShockAPI /// Writes a warning to the log file. /// /// The message to be written. + [Obsolete("Please use TShock.Log.Warn")] public static void Warn(String message) { Write(message, LogLevel.Warning); @@ -138,6 +103,7 @@ namespace TShockAPI /// /// The format of the message to be written. /// The format arguments. + [Obsolete("Please use TShock.Log.Warn")] public static void Warn(string format, params object[] args) { Warn(String.Format(format, args)); @@ -147,6 +113,7 @@ namespace TShockAPI /// Writes an informative string to the log file. /// /// The message to be written. + [Obsolete("Please use TShock.Log.Info")] public static void Info(String message) { Write(message, LogLevel.Info); @@ -157,6 +124,7 @@ namespace TShockAPI /// /// The format of the message to be written. /// The format arguments. + [Obsolete("Please use TShock.Log.Info")] public static void Info(string format, params object[] args) { Info(String.Format(format, args)); @@ -166,6 +134,7 @@ namespace TShockAPI /// Writes an informative string to the log file. Also outputs to the console. /// /// The message to be written. + [Obsolete("Please use TShock.Log.ConsoleInfo")] public static void ConsoleInfo(String message) { Console.ForegroundColor = ConsoleColor.Yellow; @@ -179,6 +148,7 @@ namespace TShockAPI /// /// The format of the message to be written. /// The format arguments. + [Obsolete("Please use TShock.Log.ConsoleInfo")] public static void ConsoleInfo(string format, params object[] args) { ConsoleInfo(String.Format(format, args)); @@ -188,6 +158,7 @@ namespace TShockAPI /// Writes a debug string to the log file. /// /// The message to be written. + [Obsolete("Please use TShock.Log.Debug")] public static void Debug(String message) { Write(message, LogLevel.Debug); @@ -198,6 +169,7 @@ namespace TShockAPI /// /// The format of the message to be written. /// The format arguments. + [Obsolete("Please use TShock.Log.Debug")] public static void Debug(string format, params object[] args) { Debug(String.Format(format, args)); @@ -208,7 +180,7 @@ namespace TShockAPI /// public static void Dispose() { - _logWriter.Dispose(); + TShock.Log.Dispose(); } /// @@ -216,35 +188,7 @@ namespace TShockAPI /// private static void Write(String message, LogLevel level) { - if (!MayWriteType(level)) - { - return; - } - - string caller = "TShock"; - - StackFrame frame = new StackTrace().GetFrame(2); - if (frame != null) - { - var meth = frame.GetMethod(); - if (meth != null) - caller = meth.DeclaringType.Name; - } - - try - { - _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(); - } - catch (ObjectDisposedException) - { - Console.WriteLine("Unable to write to log as log has been disposed."); - Console.WriteLine("{0} - {1}: {2}: {3}", - DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), - caller, level.ToString().ToUpper(), message); - } + TShock.Log.Write(message, level); } } } \ No newline at end of file diff --git a/TShockAPI/PacketBufferer.cs b/TShockAPI/PacketBufferer.cs index 051a9531..5d420618 100644 --- a/TShockAPI/PacketBufferer.cs +++ b/TShockAPI/PacketBufferer.cs @@ -145,7 +145,7 @@ namespace TShockAPI } catch (Exception e) { - Log.ConsoleError(e.ToString()); + TShock.Log.ConsoleError(e.ToString()); } return false; } @@ -206,7 +206,7 @@ namespace TShockAPI } catch (ObjectDisposedException e) { - Log.Warn(e.ToString()); + TShock.Log.Warn(e.ToString()); } catch (SocketException e) { @@ -216,7 +216,7 @@ namespace TShockAPI case 10053: break; default: - Log.Warn(e.ToString()); + TShock.Log.Warn(e.ToString()); break; } } @@ -230,12 +230,12 @@ namespace TShockAPI case SocketError.ConnectionReset: break; default: - Log.Warn(e.ToString()); + TShock.Log.Warn(e.ToString()); break; } } else - Log.Warn(e.ToString()); + TShock.Log.Warn(e.ToString()); } return false; } diff --git a/TShockAPI/SqlLog.cs b/TShockAPI/SqlLog.cs new file mode 100644 index 00000000..8aed014f --- /dev/null +++ b/TShockAPI/SqlLog.cs @@ -0,0 +1,248 @@ +/* +TShock, a server mod for Terraria +Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Data; +using System.Diagnostics; +using System.Globalization; +using TShockAPI.DB; + +namespace TShockAPI +{ + /// + /// Class inheriting ILog for writing logs to TShock's SQL database + /// + public class SqlLog : ILog, IDisposable + { + private readonly LogLevel _logLevel; + private readonly IDbConnection _database; + private readonly TextLog _backupLog; + private int _failures; + private bool _useTextLog; + + public string Name + { + get { return "SQL Log Writer"; } + } + + public bool Sql + { + get { return true; } + } + + public SqlLog(LogLevel logLevel, IDbConnection db, string textlogFilepath, bool clearTextLog) + { + _logLevel = logLevel; + _database = db; + _backupLog = new TextLog(textlogFilepath, logLevel, clearTextLog); + } + + public bool MayWriteType(LogLevel type) + { + return ((_logLevel & type) == type); + } + + /// + /// Writes data to the log file. + /// + /// The message to be written. + public void Data(String message) + { + Write(message, LogLevel.Data); + } + + /// + /// Writes data to the log file. + /// + /// The format of the message to be written. + /// The format arguments. + public void Data(string format, params object[] args) + { + Data(String.Format(format, args)); + } + + /// + /// Writes an error to the log file. + /// + /// The message to be written. + public void Error(String message) + { + Write(message, LogLevel.Error); + } + + /// + /// Writes an error to the log file. + /// + /// The format of the message to be written. + /// The format arguments. + public void Error(string format, params object[] args) + { + Error(String.Format(format, args)); + } + + /// + /// Writes an error to the log file. + /// + /// The message to be written. + public 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 format of the message to be written. + /// The format arguments. + public void ConsoleError(string format, params object[] args) + { + ConsoleError(String.Format(format, args)); + } + + /// + /// Writes a warning to the log file. + /// + /// The message to be written. + public void Warn(String message) + { + Write(message, LogLevel.Warning); + } + + /// + /// Writes a warning to the log file. + /// + /// The format of the message to be written. + /// The format arguments. + public void Warn(string format, params object[] args) + { + Warn(String.Format(format, args)); + } + + /// + /// Writes an informative string to the log file. + /// + /// The message to be written. + public void Info(String message) + { + Write(message, LogLevel.Info); + } + + /// + /// Writes an informative string to the log file. + /// + /// The format of the message to be written. + /// The format arguments. + public void Info(string format, params object[] args) + { + Info(String.Format(format, args)); + } + + /// + /// Writes an informative string to the log file. Also outputs to the console. + /// + /// The message to be written. + public 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. Also outputs to the console. + /// + /// The format of the message to be written. + /// The format arguments. + public void ConsoleInfo(string format, params object[] args) + { + ConsoleInfo(String.Format(format, args)); + } + + /// + /// Writes a debug string to the log file. + /// + /// The message to be written. + public void Debug(String message) + { + Write(message, LogLevel.Debug); + } + + /// + /// Writes a debug string to the log file. + /// + /// The format of the message to be written. + /// The format arguments. + public void Debug(string format, params object[] args) + { + Debug(String.Format(format, args)); + } + + public void Write(string message, LogLevel level) + { + if (!MayWriteType(level)) + return; + + var caller = "TShock"; + + var frame = new StackTrace().GetFrame(2); + if (frame != null) + { + var meth = frame.GetMethod(); + if (meth != null && meth.DeclaringType != null) + caller = meth.DeclaringType.Name; + } + + try + { + if (_useTextLog) + { + _backupLog.Write(message, level); + return; + } + _database.Query("INSERT INTO Logs (LogLevel, TimeStamp, Caller, Message) VALUES (@0, @1, @2, @3)", + level, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), + caller, message); + + if (_failures > 0) + _failures--; + } + catch (Exception ex) + { + _backupLog.ConsoleError("SQL Log insert query failed: {0}", ex); + _failures++; + _backupLog.Error("SQL logging will revert to text logging if {0} more failures occur.", + TShock.Config.RevertToTextLogsOnSqlFailures - _failures); + + if (_failures >= TShock.Config.RevertToTextLogsOnSqlFailures) + { + _useTextLog = true; + _backupLog.ConsoleError("SQL Logging disabled due to errors. Reverting to text logging."); + } + } + } + + public void Dispose() + { + _backupLog.Dispose(); + } + } +} \ No newline at end of file diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 436acbea..5c0df0b5 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -36,8 +36,6 @@ using Terraria; using TerrariaApi.Server; using TShockAPI.DB; using TShockAPI.Net; -using System.Threading; -using System.Threading.Tasks; using TShockAPI.ServerSideCharacters; namespace TShockAPI @@ -53,7 +51,7 @@ namespace TShockAPI private static string LogFormat = LogFormatDefault; private const string LogPathDefault = "tshock"; private static string LogPath = LogPathDefault; - private static bool LogClear = false; + private static bool LogClear; public static TSPlayer[] Players = new TSPlayer[Main.maxPlayers]; public static BanManager Bans; @@ -77,6 +75,7 @@ namespace TShockAPI public static RestManager RestManager; public static Utils Utils = Utils.Instance; public static UpdateManager UpdateManager; + public static ILog Log; /// /// Used for implementing REST Tokens prior to the REST system starting up. /// @@ -126,6 +125,9 @@ namespace TShockAPI [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] public override void Initialize() { + string logFilename; + string logPathSetupWarning; + try { HandleCommandLine(Environment.GetCommandLineArgs()); @@ -142,37 +144,29 @@ namespace TShockAPI Main.ServerSideCharacter = ServerSideCharacterConfig.Enabled; DateTime now = DateTime.Now; - string logFilename; - string logPathSetupWarning = null; // Log path was not already set by the command line parameter? if (LogPath == LogPathDefault) LogPath = Config.LogPath; try { - logFilename = Path.Combine(LogPath, now.ToString(LogFormat)+".log"); + logFilename = Path.Combine(LogPath, now.ToString(LogFormat) + ".log"); if (!Directory.Exists(LogPath)) Directory.CreateDirectory(LogPath); } - catch(Exception ex) + catch (Exception ex) { - logPathSetupWarning = "Could not apply the given log path / log format, defaults will be used. Exception details:\n" + ex; + logPathSetupWarning = + "Could not apply the given log path / log format, defaults will be used. Exception details:\n" + ex; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(logPathSetupWarning); Console.ForegroundColor = ConsoleColor.Gray; // Problem with the log path or format use the default logFilename = Path.Combine(LogPathDefault, now.ToString(LogFormatDefault) + ".log"); } -#if DEBUG - Log.Initialize(logFilename, LogLevel.All, false); -#else - Log.Initialize(logFilename, LogLevel.All & ~LogLevel.Debug, LogClear); -#endif - if (logPathSetupWarning != null) - Log.Warn(logPathSetupWarning); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; } - catch(Exception ex) + catch (Exception ex) { // Will be handled by the server api and written to its crashlog.txt. throw new Exception("Fatal TShock initialization exception. See inner exception for details.", ex); @@ -181,16 +175,6 @@ namespace TShockAPI // Further exceptions are written to TShock's log from now on. try { - if (File.Exists(Path.Combine(SavePath, "tshock.pid"))) - { - Log.ConsoleInfo( - "TShock was improperly shut down. Please use the exit command in the future to prevent this."); - File.Delete(Path.Combine(SavePath, "tshock.pid")); - } - File.WriteAllText(Path.Combine(SavePath, "tshock.pid"), Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture)); - - HandleCommandLinePostConfigLoad(Environment.GetCommandLineArgs()); - if (Config.StorageType.ToLower() == "sqlite") { string sql = Path.Combine(SavePath, "tshock.sqlite"); @@ -204,16 +188,18 @@ namespace TShockAPI 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 + hostport[0], + hostport.Length > 1 ? hostport[1] : "3306", + Config.MySqlDbName, + Config.MySqlUsername, + Config.MySqlPassword ); } catch (MySqlException ex) { - Log.Error(ex.ToString()); + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(ex); + Console.ResetColor(); throw new Exception("MySql not setup correctly"); } } @@ -222,12 +208,34 @@ namespace TShockAPI throw new Exception("Invalid storage type"); } +#if DEBUG + var level = LogLevel.All; +#else + var level = LogLevel.All & ~LogLevel.Debug; +#endif + if (Config.UseSqlLogs) + Log = new SqlLog(level, DB, logFilename, LogClear); + else + Log = new TextLog(logFilename, level, LogClear); + + if (File.Exists(Path.Combine(SavePath, "tshock.pid"))) + { + Log.ConsoleInfo( + "TShock was improperly shut down. Please use the exit command in the future to prevent this."); + File.Delete(Path.Combine(SavePath, "tshock.pid")); + } + File.WriteAllText(Path.Combine(SavePath, "tshock.pid"), + Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture)); + + HandleCommandLinePostConfigLoad(Environment.GetCommandLineArgs()); + + Backups = new BackupManager(Path.Combine(SavePath, "backups")); Backups.KeepFor = Config.BackupKeepFor; Backups.Interval = Config.BackupInterval; Bans = new BanManager(DB); Warps = new WarpManager(DB); - Regions = new RegionManager(DB); + Regions = new RegionManager(DB); Users = new UserManager(DB); Groups = new GroupManager(DB); Itembans = new ItemManager(DB); @@ -294,7 +302,7 @@ namespace TShockAPI } } - private static void getTShockAscii() + private static void getTShockAscii() { // ReSharper disable LocalizableElement Console.Write(" ___ ___ ___ ___ ___ \n" + @@ -1210,24 +1218,24 @@ namespace TShockAPI player.LoginMS = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; - if (TShock.Config.EnableGeoIP && TShock.Geo != null) + if (Config.EnableGeoIP && TShock.Geo != null) { Log.Info(string.Format("{0} ({1}) from '{2}' group from '{3}' joined. ({4}/{5})", player.Name, player.IP, player.Group.Name, player.Country, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots)); if (!player.SilentJoinInProgress) - TShock.Utils.Broadcast(string.Format("{0} ({1}) has joined.", player.Name, player.Country), Color.Yellow); + Utils.Broadcast(string.Format("{0} ({1}) has joined.", player.Name, player.Country), Color.Yellow); } else { Log.Info(string.Format("{0} ({1}) from '{2}' group joined. ({3}/{4})", player.Name, player.IP, player.Group.Name, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots)); if (!player.SilentJoinInProgress) - TShock.Utils.Broadcast(player.Name + " has joined.", Color.Yellow); + Utils.Broadcast(player.Name + " has joined.", Color.Yellow); } - if (TShock.Config.DisplayIPToAdmins) - TShock.Utils.SendLogs(string.Format("{0} has joined. IP: {1}", player.Name, player.IP), Color.Blue); + if (Config.DisplayIPToAdmins) + Utils.SendLogs(string.Format("{0} has joined. IP: {1}", player.Name, player.IP), Color.Blue); Utils.ShowFileToUser(player, "motd.txt"); diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj index 4072b8ed..e038bbaa 100644 --- a/TShockAPI/TShockAPI.csproj +++ b/TShockAPI/TShockAPI.csproj @@ -78,6 +78,10 @@ + + + + @@ -102,7 +106,6 @@ - @@ -182,7 +185,7 @@ - +