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 @@
-
+