Merge branch 'general-devel'
This commit is contained in:
commit
0622350653
41 changed files with 2138 additions and 1735 deletions
|
|
@ -1,9 +1,5 @@
|
||||||
language: c
|
language: csharp
|
||||||
install:
|
solution: ./TShockAPI/TShockAPI.csproj
|
||||||
- sudo apt-get install mono-devel mono-gmcs nunit-console
|
|
||||||
script:
|
|
||||||
- xbuild ./TShockAPI/TShockAPI.csproj
|
|
||||||
notifications:
|
notifications:
|
||||||
irc: irc.rizon.net#tshock
|
|
||||||
hipchat:
|
hipchat:
|
||||||
secure: hpRLWiHF2j6O2qJOVs++aqAmryN6G5kY0SF26/rKCpQ7klhMlDZIgI1V1dbkKqlculFtW1neS0EBJyV9lmcV5b26H+KhlZYGN0j7q1VcOTM3rvtU6wW0Ap22uRLl2RrnA4kEsgDAsNouPOkyLZ19hlHAISlsId6G4+Rfqg6k+zQ=
|
secure: hpRLWiHF2j6O2qJOVs++aqAmryN6G5kY0SF26/rKCpQ7klhMlDZIgI1V1dbkKqlculFtW1neS0EBJyV9lmcV5b26H+KhlZYGN0j7q1VcOTM3rvtU6wW0Ap22uRLl2RrnA4kEsgDAsNouPOkyLZ19hlHAISlsId6G4+Rfqg6k+zQ=
|
||||||
|
|
@ -1,36 +1,40 @@
|
||||||
### Issue Guidelines
|
### Issue Guidelines
|
||||||
Please follow these simple requirements before posting an issue:
|
Please follow these simple requirements before posting an issue:
|
||||||
|
|
||||||
1. TShock version number
|
- TShock version number
|
||||||
2. Any stack traces that may have happened when the issue occurred
|
- Any stack traces that may have happened when the issue occurred
|
||||||
3. How to reproduce the issue
|
- How to reproduce the issue
|
||||||
|
- Screenshots of the issue (if applicable)
|
||||||
|
|
||||||
|
### TShock Additions
|
||||||
|
|
||||||
|
If something is better suited to be a plugin for TShock, rather than a TShock core feature, it should not be added!
|
||||||
|
|
||||||
### Pull Request Dev Guidelines
|
### Pull Request Dev Guidelines
|
||||||
|
|
||||||
These guidelines are for contributors. If you do not follow these guidelines your commits will be reverted.
|
These guidelines are for all contributors.
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
- Follow the code style. We generally use microsofts except for m_ infront of private variables.
|
- Push code to the general-devel branch. Do not push it anywhere else.
|
||||||
- Do not push unfinished features to the master branch, instead create a remote branch and push to that.
|
- Use tabs, not spaces.
|
||||||
- Do not push untested code to the master branch, instead push to the test branch.
|
- Use UpperCamelCase for public function names.
|
||||||
- Document all compatibility issues in the COMPATIBILITY file. (IE file formats changing)
|
- Prior to developing, make sure your clone is up to date with general-devel. This means that we don't get merge commits in your pull request.
|
||||||
- DO NOT MASS COMMIT. Commit changes as you go (without pushing). That way when you push we don't get a thousand changes with a 1-3 line commit message.
|
|
||||||
|
|
||||||
Optional:
|
|
||||||
- Build Version Increment (http://autobuildversion.codeplex.com/).
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
### Dev Team Guidelines
|
### Dev Team Guidelines
|
||||||
|
|
||||||
These guidelines are to be followed by all developers with commit level access to this repository:
|
These guidelines are to be followed by all developers with commit level access to this repository:
|
||||||
|
|
||||||
- Do not, for any reason, submit code to the master branch before it hits the development branch first. If the development branch is far ahead, and a new bug fix is going out, branch master, then merge with master and remove your branch.
|
|
||||||
- If you are found to do this, you will be the person merging and rebasing your code to fit general-devel.
|
|
||||||
- Prior to posting any version on the website, you must tick the version in AssemblyInfo.cs. This is the versioning formula:
|
- Prior to posting any version on the website, you must tick the version in AssemblyInfo.cs. This is the versioning formula:
|
||||||
- Major.Minor.Revision.BuildDate (tick Revision if you're fixing prior to an actual planned release)
|
- Major.Minor.Revision
|
||||||
- Do not release any development builds on the forums without consulting another developer first.
|
- Do not release any development builds on the forums without consulting another developer first.
|
||||||
- __Document code prior to marking it done in JIRA__
|
- This is not a professional software product. Your results may vary with code quality, buginess, etc. Do not complain about something -- just fix it and move on.
|
||||||
- Move any un-tested code to the "Needs Validation" section on JIRA prior to marking it as done.
|
- __Do not force push the repo__, or you will be removed.
|
||||||
- Do not push changes to any branch without a proper issue being assigned in JIRA. If a feature isn't planned for this release, __it shouldn't be in the repo about to be released__.
|
- __Do not revert commits__, unless you have sign-off from one other developer (the two-man rule), or you will be removed.
|
||||||
- Submit all pull requests to the general-devel branch prior to the master branch, or you will be ignored.
|
- __This is not a meritocracy.__
|
||||||
|
|
||||||
|
#### Pull Request Acceptance Guidelines
|
||||||
|
|
||||||
|
- Don't ruin someone's first time sending a pull request. They feel demotivated, and then they won't want to push any more code for us.
|
||||||
|
- Don't accept untested pull requests from the outside world. Bamboo and Travis will at least make sure that something compiles, but actual code and execution tests are required.
|
||||||
|
- Pull request acceptance from internal contributors (anyone with write access) requires only one other approval to merge.
|
||||||
|
- Pull request acceptance from external contributors (anyone without write access) requires the [two-man rule](https://en.wikipedia.org/wiki/Two-man_rule) to be followed. If another man/woman/child in the two-man rule cannot be found within seven days, then this requirement is exempted.
|
||||||
|
|
|
||||||
11
README.md
11
README.md
|
|
@ -1,8 +1,3 @@
|
||||||
# Current Status
|
|
||||||
This project is in maintenance mode. This means that the core team of developers' time is very limited, and only extremely game breaking bugs will be fixed. Improvements, new features, and minor issues will not be resolved by direct development until this time restriction has passed. Issues created reflecting these requests will not be worked on until this notice is removed.
|
|
||||||
|
|
||||||
Thanks for your continued support of TShock for Terraria.
|
|
||||||
|
|
||||||
# TShock [](https://travis-ci.org/NyxStudios/TShock)
|
# TShock [](https://travis-ci.org/NyxStudios/TShock)
|
||||||
|
|
||||||
TShock is a server modification for Terraria, written in C#, and based upon the [Terraria Server API](https://github.com/Deathmax/TerrariaAPI-Server). It uses JSON for configuration management, and offers several features not present in the Terraria Server normally.
|
TShock is a server modification for Terraria, written in C#, and based upon the [Terraria Server API](https://github.com/Deathmax/TerrariaAPI-Server). It uses JSON for configuration management, and offers several features not present in the Terraria Server normally.
|
||||||
|
|
@ -21,11 +16,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?
|
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)
|
* [Wiki](https://tshock.atlassian.net/wiki/display/TSHOCKPLUGINS/Home)
|
||||||
* [IRC: #tshock @ irc.rizon.net](http://tshock.co/xf/index.php?ezirc/)
|
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
|
|
||||||
* [Github Releases](https://github.com/TShock/TShock/releases)
|
* [Github Releases](https://github.com/TShock/TShock/releases)
|
||||||
* [Download Archive](https://github.com/TShock/TShock/downloads)
|
* [Plugins](https://tshock.co/xf/index.php?resources/)
|
||||||
|
* [Very, very old versions of TShock](https://github.com/TShock/TShock/downloads)
|
||||||
|
|
|
||||||
|
|
@ -61,13 +61,13 @@ namespace TShockAPI
|
||||||
if (worldpath != null && !Directory.Exists(worldpath))
|
if (worldpath != null && !Directory.Exists(worldpath))
|
||||||
Directory.CreateDirectory(worldpath);
|
Directory.CreateDirectory(worldpath);
|
||||||
|
|
||||||
TShock.Utils.Broadcast("Server map saving, potential lag spike.");
|
TSPlayer.All.SendInfoMessage("Server map saving, potential lag spike.");
|
||||||
Console.WriteLine("Backing up world...");
|
Console.WriteLine("Backing up world...");
|
||||||
|
|
||||||
SaveManager.Instance.SaveWorld();
|
SaveManager.Instance.SaveWorld();
|
||||||
Console.WriteLine("World backed up.");
|
Console.WriteLine("World backed up.");
|
||||||
Console.ForegroundColor = ConsoleColor.Gray;
|
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;
|
Main.worldPathName = worldname;
|
||||||
}
|
}
|
||||||
|
|
@ -76,8 +76,8 @@ namespace TShockAPI
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
Console.WriteLine("Backup failed!");
|
Console.WriteLine("Backup failed!");
|
||||||
Console.ForegroundColor = ConsoleColor.Gray;
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
Log.Error("Backup failed!");
|
TShock.Log.Error("Backup failed!");
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -106,11 +106,6 @@ namespace TShockAPI
|
||||||
[Description("Number of failed login attempts before kicking the player.")]
|
[Description("Number of failed login attempts before kicking the player.")]
|
||||||
public int MaximumLoginAttempts = 3;
|
public int MaximumLoginAttempts = 3;
|
||||||
|
|
||||||
[Description("Not implemented.")]
|
|
||||||
public string RconPassword = "";
|
|
||||||
[Description("Not implemented.")]
|
|
||||||
public int RconPort = 7777;
|
|
||||||
|
|
||||||
[Description("Used when replying to a rest /status request or sent to the client when UseServerName is true.")]
|
[Description("Used when replying to a rest /status request or sent to the client when UseServerName is true.")]
|
||||||
public string ServerName = "";
|
public string ServerName = "";
|
||||||
[Description("Sends ServerName in place of the world name to clients.")]
|
[Description("Sends ServerName in place of the world name to clients.")]
|
||||||
|
|
@ -325,6 +320,12 @@ namespace TShockAPI
|
||||||
[Description("The path of the directory where logs should be written into.")]
|
[Description("The path of the directory where logs should be written into.")]
|
||||||
public string LogPath = "tshock";
|
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.")]
|
[Description("Prevents players from placing tiles with an invalid style.")]
|
||||||
public bool PreventInvalidPlaceStyle = true;
|
public bool PreventInvalidPlaceStyle = true;
|
||||||
|
|
||||||
|
|
@ -367,9 +368,12 @@ namespace TShockAPI
|
||||||
[Description("Allows anyone to break grass, pots, etc.")]
|
[Description("Allows anyone to break grass, pots, etc.")]
|
||||||
public bool AllowCutTilesAndBreakables = false;
|
public bool AllowCutTilesAndBreakables = false;
|
||||||
|
|
||||||
[Description("Specifies which string starts a command")]
|
[Description("Specifies which string starts a command.")]
|
||||||
public string CommandSpecifier = "/";
|
public string CommandSpecifier = "/";
|
||||||
|
|
||||||
|
[Description("Specifies which string starts a command silently.")]
|
||||||
|
public string CommandSilentSpecifier = ".";
|
||||||
|
|
||||||
[Description("Kicks a hardcore player on death.")]
|
[Description("Kicks a hardcore player on death.")]
|
||||||
public bool KickOnHardcoreDeath;
|
public bool KickOnHardcoreDeath;
|
||||||
|
|
||||||
|
|
@ -391,6 +395,9 @@ namespace TShockAPI
|
||||||
[Description("The maximum allowable MP, before equipment buffs.")]
|
[Description("The maximum allowable MP, before equipment buffs.")]
|
||||||
public int MaxMP = 200;
|
public int MaxMP = 200;
|
||||||
|
|
||||||
|
[Description("Determines if the server should save the world if the last player exits.")]
|
||||||
|
public bool SaveWorldOnLastPlayerExit = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a configuration file from a given path
|
/// Reads a configuration file from a given path
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +96,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
Console.WriteLine(ex.StackTrace);
|
Console.WriteLine(ex.StackTrace);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -123,7 +123,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -145,18 +145,11 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if COMPAT_SIGS
|
|
||||||
[Obsolete("This method is for signature compatibility for external code only")]
|
|
||||||
public bool AddBan(string ip, string name, string reason)
|
|
||||||
{
|
|
||||||
return AddBan(ip, name, "", reason, false, "", "");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
public bool AddBan(string ip, string name = "", string uuid = "", string reason = "", bool exceptions = false, string banner = "", string expiration = "")
|
public bool AddBan(string ip, string name = "", string uuid = "", string reason = "", bool exceptions = false, string banner = "", string expiration = "")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -167,18 +160,11 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
if (exceptions)
|
if (exceptions)
|
||||||
throw ex;
|
throw ex;
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if COMPAT_SIGS
|
|
||||||
[Obsolete("This method is for signature compatibility for external code only")]
|
|
||||||
public bool RemoveBan(string ip)
|
|
||||||
{
|
|
||||||
return RemoveBan(ip, false, true, false);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
public bool RemoveBan(string match, bool byName = false, bool casesensitive = true, bool exceptions = false)
|
public bool RemoveBan(string match, bool byName = false, bool casesensitive = true, bool exceptions = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -193,7 +179,7 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
if (exceptions)
|
if (exceptions)
|
||||||
throw ex;
|
throw ex;
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -206,7 +192,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return playerData;
|
return playerData;
|
||||||
|
|
@ -104,7 +104,7 @@ namespace TShockAPI.DB
|
||||||
public bool SeedInitialData(User user)
|
public bool SeedInitialData(User user)
|
||||||
{
|
{
|
||||||
var inventory = new StringBuilder();
|
var inventory = new StringBuilder();
|
||||||
for (int i = 0; i < Terraria.Main.maxInventory; i++)
|
for (int i = 0; i < NetItem.maxNetInventory; i++)
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -137,7 +137,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -162,7 +162,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -176,7 +176,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -191,7 +191,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ namespace TShockAPI.DB
|
||||||
var error = "Invalid parent {0} for group {1}".SFormat(parentname, group.Name);
|
var error = "Invalid parent {0} for group {1}".SFormat(parentname, group.Name);
|
||||||
if (exceptions)
|
if (exceptions)
|
||||||
throw new GroupManagerException(error);
|
throw new GroupManagerException(error);
|
||||||
Log.ConsoleError(error);
|
TShock.Log.ConsoleError(error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
group.Parent = parent;
|
group.Parent = parent;
|
||||||
|
|
@ -162,19 +162,6 @@ namespace TShockAPI.DB
|
||||||
return AddGroup(name, null, permissions, Group.defaultChatColor, false);
|
return AddGroup(name, null, permissions, Group.defaultChatColor, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if COMPAT_SIGS
|
|
||||||
[Obsolete("This method is for signature compatibility for external code only")]
|
|
||||||
public String AddGroup(String name, string parentname, String permissions)
|
|
||||||
{
|
|
||||||
return AddGroup(name, parentname, permissions, Group.defaultChatColor, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Obsolete("This method is for signature compatibility for external code only")]
|
|
||||||
public String AddGroup(String name, string parentname, String permissions, String chatcolor)
|
|
||||||
{
|
|
||||||
return AddGroup(name, parentname, permissions, chatcolor, false);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates a group including permissions
|
/// Updates a group including permissions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -224,13 +211,6 @@ namespace TShockAPI.DB
|
||||||
group.Suffix = suffix;
|
group.Suffix = suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if COMPAT_SIGS
|
|
||||||
[Obsolete("This method is for signature compatibility for external code only")]
|
|
||||||
public String DeleteGroup(String name)
|
|
||||||
{
|
|
||||||
return DeleteGroup(name, false);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
public String DeleteGroup(String name, bool exceptions = false)
|
public String DeleteGroup(String name, bool exceptions = false)
|
||||||
{
|
{
|
||||||
if (!GroupExists(name))
|
if (!GroupExists(name))
|
||||||
|
|
@ -298,7 +278,7 @@ namespace TShockAPI.DB
|
||||||
string groupName = reader.Get<string>("GroupName");
|
string groupName = reader.Get<string>("GroupName");
|
||||||
if (groupName == "superadmin")
|
if (groupName == "superadmin")
|
||||||
{
|
{
|
||||||
Log.ConsoleInfo("WARNING: Group \"superadmin\" is defined in the database even though it's a reserved group name.");
|
TShock.Log.ConsoleInfo("WARNING: Group \"superadmin\" is defined in the database even though it's a reserved group name.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -314,7 +294,7 @@ namespace TShockAPI.DB
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
{
|
{
|
||||||
// Just in case somebody messed with the unique primary key.
|
// Just in case somebody messed with the unique primary key.
|
||||||
Log.ConsoleError("ERROR: Group name \"{0}\" occurs more than once. Keeping current group settings.");
|
TShock.Log.ConsoleError("ERROR: Group name \"{0}\" occurs more than once. Keeping current group settings.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -349,14 +329,14 @@ namespace TShockAPI.DB
|
||||||
group.Parent = groups.FirstOrDefault(g => g.Name == parentGroupName);
|
group.Parent = groups.FirstOrDefault(g => g.Name == parentGroupName);
|
||||||
if (group.Parent == null)
|
if (group.Parent == null)
|
||||||
{
|
{
|
||||||
Log.ConsoleError(
|
TShock.Log.ConsoleError(
|
||||||
"ERROR: Group \"{0}\" is referencing non existent parent group \"{1}\", parent reference was removed.",
|
"ERROR: Group \"{0}\" is referencing non existent parent group \"{1}\", parent reference was removed.",
|
||||||
group.Name, parentGroupName);
|
group.Name, parentGroupName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (group.Parent == group)
|
if (group.Parent == group)
|
||||||
Log.ConsoleInfo(
|
TShock.Log.ConsoleInfo(
|
||||||
"WARNING: Group \"{0}\" is referencing itself as parent group, parent reference was removed.", group.Name);
|
"WARNING: Group \"{0}\" is referencing itself as parent group, parent reference was removed.", group.Name);
|
||||||
|
|
||||||
List<Group> groupChain = new List<Group> { group };
|
List<Group> groupChain = new List<Group> { group };
|
||||||
|
|
@ -365,7 +345,7 @@ namespace TShockAPI.DB
|
||||||
{
|
{
|
||||||
if (groupChain.Contains(checkingGroup.Parent))
|
if (groupChain.Contains(checkingGroup.Parent))
|
||||||
{
|
{
|
||||||
Log.ConsoleError(
|
TShock.Log.ConsoleError(
|
||||||
"ERROR: Group \"{0}\" is referencing parent group \"{1}\" which is already part of the parent chain. Parent reference removed.",
|
"ERROR: Group \"{0}\" is referencing parent group \"{1}\" which is already part of the parent chain. Parent reference removed.",
|
||||||
checkingGroup.Name, checkingGroup.Parent.Name);
|
checkingGroup.Name, checkingGroup.Parent.Name);
|
||||||
|
|
||||||
|
|
@ -386,7 +366,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.ConsoleError("Error on reloading groups: " + ex);
|
TShock.Log.ConsoleError("Error on reloading groups: " + ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,7 +126,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -150,7 +150,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,7 +131,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,7 +155,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -94,15 +94,15 @@ namespace TShockAPI.DB
|
||||||
if (Int32.TryParse(splitids[i], out id)) // if unparsable, it's not an int, so silently skip
|
if (Int32.TryParse(splitids[i], out id)) // if unparsable, it's not an int, so silently skip
|
||||||
r.AllowedIDs.Add(id);
|
r.AllowedIDs.Add(id);
|
||||||
else
|
else
|
||||||
Log.Warn("One of your UserIDs is not a usable integer: " + splitids[i]);
|
TShock.Log.Warn("One of your UserIDs is not a usable integer: " + splitids[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.Error("Your database contains invalid UserIDs (they should be ints).");
|
TShock.Log.Error("Your database contains invalid UserIDs (they should be ints).");
|
||||||
Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field.");
|
TShock.Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field.");
|
||||||
Log.Error(e.ToString());
|
TShock.Log.Error(e.ToString());
|
||||||
Log.Error(e.StackTrace);
|
TShock.Log.Error(e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
Regions.Add(r);
|
Regions.Add(r);
|
||||||
|
|
@ -111,10 +111,22 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a region to the database.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tx">TileX of the top left corner.</param>
|
||||||
|
/// <param name="ty">TileY of the top left corner.</param>
|
||||||
|
/// <param name="width">Width of the region in tiles.</param>
|
||||||
|
/// <param name="height">Height of the region in tiles.</param>
|
||||||
|
/// <param name="regionname">The name of the region.</param>
|
||||||
|
/// <param name="owner">The User Account Name of the person who created this region.</param>
|
||||||
|
/// <param name="worldid">The world id that this region is in.</param>
|
||||||
|
/// <param name="z">The Z index of the region.</param>
|
||||||
|
/// <returns>Whether the region was created and added successfully.</returns>
|
||||||
public bool AddRegion(int tx, int ty, int width, int height, string regionname, string owner, string worldid, int z = 0)
|
public bool AddRegion(int tx, int ty, int width, int height, string regionname, string owner, string worldid, int z = 0)
|
||||||
{
|
{
|
||||||
if (GetRegionByName(regionname) != null)
|
if (GetRegionByName(regionname) != null)
|
||||||
|
|
@ -126,28 +138,37 @@ namespace TShockAPI.DB
|
||||||
database.Query(
|
database.Query(
|
||||||
"INSERT INTO Regions (X1, Y1, width, height, RegionName, WorldID, UserIds, Protected, Groups, Owner, Z) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10);",
|
"INSERT INTO Regions (X1, Y1, width, height, RegionName, WorldID, UserIds, Protected, Groups, Owner, Z) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10);",
|
||||||
tx, ty, width, height, regionname, worldid, "", 1, "", owner, z);
|
tx, ty, width, height, regionname, worldid, "", 1, "", owner, z);
|
||||||
Regions.Add(new Region(new Rectangle(tx, ty, width, height), regionname, owner, true, worldid, z));
|
var region = new Region(new Rectangle(tx, ty, width, height), regionname, owner, true, worldid, z);
|
||||||
|
Regions.Add(region);
|
||||||
|
Hooks.RegionHooks.OnRegionCreated(region);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes the region from this world with a given name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The name of the region to delete.</param>
|
||||||
|
/// <returns>Whether the region was successfully deleted.</returns>
|
||||||
public bool DeleteRegion(string name)
|
public bool DeleteRegion(string name)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
database.Query("DELETE FROM Regions WHERE RegionName=@0 AND WorldID=@1", name, Main.worldID.ToString());
|
database.Query("DELETE FROM Regions WHERE RegionName=@0 AND WorldID=@1", name, Main.worldID.ToString());
|
||||||
var worldid = Main.worldID.ToString();
|
var worldid = Main.worldID.ToString();
|
||||||
|
var region = Regions.FirstOrDefault(r => r.Name == name && r.WorldID == worldid);
|
||||||
Regions.RemoveAll(r => r.Name == name && r.WorldID == worldid);
|
Regions.RemoveAll(r => r.Name == name && r.WorldID == worldid);
|
||||||
|
Hooks.RegionHooks.OnRegionDeleted(region);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -165,7 +186,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -182,7 +203,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -308,7 +329,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -363,7 +384,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -390,7 +411,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -413,7 +434,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return regions;
|
return regions;
|
||||||
}
|
}
|
||||||
|
|
@ -518,7 +539,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Vector2();
|
return new Vector2();
|
||||||
|
|
@ -88,7 +88,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Vector2();
|
return new Vector2();
|
||||||
|
|
@ -105,7 +105,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -117,7 +117,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,19 +79,7 @@ namespace TShockAPI.DB
|
||||||
[Obsolete("This method will be replaced by EnsureTableExists.")]
|
[Obsolete("This method will be replaced by EnsureTableExists.")]
|
||||||
public void EnsureExists(SqlTable table)
|
public void EnsureExists(SqlTable table)
|
||||||
{
|
{
|
||||||
var columns = GetColumns(table);
|
EnsureTableStructure(table);
|
||||||
if (columns.Count > 0)
|
|
||||||
{
|
|
||||||
if (!table.Columns.All(c => columns.Contains(c.Name)) || !columns.All(c => table.Columns.Any(c2 => c2.Name == c)))
|
|
||||||
{
|
|
||||||
var from = new SqlTable(table.Name, columns.Select(s => new SqlColumn(s, MySqlDbType.String)).ToList());
|
|
||||||
database.Query(creator.AlterTable(from, table));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
database.Query(creator.CreateTable(table));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<string> GetColumns(SqlTable table)
|
public List<string> GetColumns(SqlTable table)
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,7 +131,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,7 +155,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex);
|
TShock.Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -285,7 +285,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +117,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +162,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -186,7 +186,7 @@ namespace TShockAPI.DB
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1261,7 +1261,7 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1469,7 +1469,7 @@ namespace TShockAPI
|
||||||
TShock.CharacterDB.InsertPlayerData(args.Player);
|
TShock.CharacterDB.InsertPlayerData(args.Player);
|
||||||
}
|
}
|
||||||
args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen);
|
args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen);
|
||||||
Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + ".");
|
TShock.Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + ".");
|
||||||
Hooks.PlayerHooks.OnPlayerPostLogin(args.Player);
|
Hooks.PlayerHooks.OnPlayerPostLogin(args.Player);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1547,7 +1547,7 @@ namespace TShockAPI
|
||||||
TShock.CharacterDB.InsertPlayerData(args.Player);
|
TShock.CharacterDB.InsertPlayerData(args.Player);
|
||||||
}
|
}
|
||||||
args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen);
|
args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen);
|
||||||
Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + ".");
|
TShock.Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + ".");
|
||||||
TShock.Users.SetUserUUID(user, args.Player.UUID);
|
TShock.Users.SetUserUUID(user, args.Player.UUID);
|
||||||
Hooks.PlayerHooks.OnPlayerPostLogin(args.Player);
|
Hooks.PlayerHooks.OnPlayerPostLogin(args.Player);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -2239,27 +2239,23 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (args.Player.IgnoreActionsForCheating != "none")
|
if (args.Player.IgnoreActionsForCheating != "none")
|
||||||
{
|
{
|
||||||
args.Player.SendMessage("Disabled for cheating: " + args.Player.IgnoreActionsForCheating,
|
args.Player.SendErrorMessage("Disabled for cheating: " + args.Player.IgnoreActionsForCheating);
|
||||||
Color.Red);
|
|
||||||
}
|
}
|
||||||
else if (args.Player.IgnoreActionsForDisabledArmor != "none")
|
else if (args.Player.IgnoreActionsForDisabledArmor != "none")
|
||||||
{
|
{
|
||||||
args.Player.SendMessage(
|
args.Player.SendErrorMessage("Disabled for banned armor: " + args.Player.IgnoreActionsForDisabledArmor);
|
||||||
"Disabled for banned armor: " + args.Player.IgnoreActionsForDisabledArmor, Color.Red);
|
|
||||||
}
|
}
|
||||||
else if (args.Player.IgnoreActionsForInventory != "none")
|
else if (args.Player.IgnoreActionsForInventory != "none")
|
||||||
{
|
{
|
||||||
args.Player.SendMessage(
|
args.Player.SendErrorMessage("Disabled for Server Side Inventory: " + args.Player.IgnoreActionsForInventory);
|
||||||
"Disabled for Server Side Inventory: " + args.Player.IgnoreActionsForInventory,
|
|
||||||
Color.Red);
|
|
||||||
}
|
}
|
||||||
else if (TShock.Config.RequireLogin && !args.Player.IsLoggedIn)
|
else if (TShock.Config.RequireLogin && !args.Player.IsLoggedIn)
|
||||||
{
|
{
|
||||||
args.Player.SendMessage("Please /register or /login to play!", Color.Red);
|
args.Player.SendErrorMessage("Please /register or /login to play!");
|
||||||
}
|
}
|
||||||
else if (args.Player.IgnoreActionsForClearingTrashCan)
|
else if (args.Player.IgnoreActionsForClearingTrashCan)
|
||||||
{
|
{
|
||||||
args.Player.SendMessage("You need to rejoin to ensure your trash can is cleared!", Color.Red);
|
args.Player.SendErrorMessage("You need to rejoin to ensure your trash can is cleared!");
|
||||||
}
|
}
|
||||||
var lastTileX = args.Player.LastNetPosition.X;
|
var lastTileX = args.Player.LastNetPosition.X;
|
||||||
var lastTileY = args.Player.LastNetPosition.Y - 48;
|
var lastTileY = args.Player.LastNetPosition.Y - 48;
|
||||||
|
|
@ -2299,9 +2295,8 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
control[5] = false;
|
control[5] = false;
|
||||||
args.Player.Disable("Using banned item");
|
args.Player.Disable("Using banned item");
|
||||||
args.Player.SendMessage(
|
args.Player.SendErrorMessage("You cannot use {0} on this server. Your actions are being ignored.",
|
||||||
string.Format("You cannot use {0} on this server. Your actions are being ignored.",
|
args.TPlayer.inventory[item].name);
|
||||||
args.TPlayer.inventory[item].name), Color.Red);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.TPlayer.inventory[item].name == "Mana Crystal" && args.Player.TPlayer.statManaMax <= 180)
|
if (args.TPlayer.inventory[item].name == "Mana Crystal" && args.Player.TPlayer.statManaMax <= 180)
|
||||||
|
|
@ -2449,13 +2444,6 @@ namespace TShockAPI
|
||||||
args.Player.RemoveProjectile(ident, owner);
|
args.Player.RemoveProjectile(ident, owner);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Server now checks owner + ident, if owner is different, server will create new projectile.
|
|
||||||
/*if (args.Player.Index != owner)
|
|
||||||
{
|
|
||||||
args.Player.Disable(String.Format("Owner ({0}) and player ID ({1}) does not match to update projectile", owner, args.Player.Index));
|
|
||||||
args.Player.RemoveProjectile(ident, owner);
|
|
||||||
return true;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (dmg > TShock.Config.MaxProjDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap))
|
if (dmg > TShock.Config.MaxProjDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap))
|
||||||
{
|
{
|
||||||
|
|
@ -2475,7 +2463,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (type == 100 || type == 164 || type == 180 || type == 261 || (type > 289 && type < 298) || (type >= 325 && type <= 328) || (type >= 345 && type <= 352))
|
if (type == 100 || type == 164 || type == 180 || type == 261 || (type > 289 && type < 298) || (type >= 325 && type <= 328) || (type >= 345 && type <= 352))
|
||||||
{
|
{
|
||||||
Log.Debug("Certain projectiles have been ignored for cheat detection.");
|
TShock.Log.Debug("Certain projectiles have been ignored for cheat detection.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -2502,7 +2490,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (type == 90 && TShock.Config.ProjIgnoreShrapnel) // Ignore crystal shards
|
if (type == 90 && TShock.Config.ProjIgnoreShrapnel) // Ignore crystal shards
|
||||||
{
|
{
|
||||||
Log.Debug("Ignoring shrapnel per config..");
|
TShock.Log.Debug("Ignoring shrapnel per config..");
|
||||||
}
|
}
|
||||||
else if (!Main.projectile[index].active)
|
else if (!Main.projectile[index].active)
|
||||||
{
|
{
|
||||||
|
|
@ -2579,7 +2567,7 @@ namespace TShockAPI
|
||||||
if (dmg > 20000) //Abnormal values have the potential to cause infinite loops in the server.
|
if (dmg > 20000) //Abnormal values have the potential to cause infinite loops in the server.
|
||||||
{
|
{
|
||||||
TShock.Utils.ForceKick(args.Player, "Crash Exploit Attempt", true);
|
TShock.Utils.ForceKick(args.Player, "Crash Exploit Attempt", true);
|
||||||
Log.ConsoleError("Death Exploit Attempt: Damage {0}", dmg);
|
TShock.Log.ConsoleError("Death Exploit Attempt: Damage {0}", dmg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2970,7 +2958,7 @@ namespace TShockAPI
|
||||||
|
|
||||||
if (!args.Player.Group.HasPermission(Permissions.movenpc))
|
if (!args.Player.Group.HasPermission(Permissions.movenpc))
|
||||||
{
|
{
|
||||||
args.Player.SendMessage("You do not have permission to relocate NPCs.", Color.Red);
|
args.Player.SendErrorMessage("You do not have permission to relocate NPCs.");
|
||||||
args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY,
|
args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY,
|
||||||
Convert.ToByte(Main.npc[id].homeless));
|
Convert.ToByte(Main.npc[id].homeless));
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -2978,7 +2966,7 @@ namespace TShockAPI
|
||||||
|
|
||||||
if (TShock.CheckTilePermission(args.Player, x, y))
|
if (TShock.CheckTilePermission(args.Player, x, y))
|
||||||
{
|
{
|
||||||
args.Player.SendMessage( "You do not have access to modify this area.", Color.Red);
|
args.Player.SendErrorMessage( "You do not have access to modify this area.");
|
||||||
args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY,
|
args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY,
|
||||||
Convert.ToByte(Main.npc[id].homeless));
|
Convert.ToByte(Main.npc[id].homeless));
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -3099,7 +3087,7 @@ namespace TShockAPI
|
||||||
if ((Main.ServerSideCharacter) && (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - args.Player.LoginMS < TShock.ServerSideCharacterConfig.LogonDiscardThreshold))
|
if ((Main.ServerSideCharacter) && (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - args.Player.LoginMS < TShock.ServerSideCharacterConfig.LogonDiscardThreshold))
|
||||||
{
|
{
|
||||||
//Player is probably trying to sneak items onto the server in their hands!!!
|
//Player is probably trying to sneak items onto the server in their hands!!!
|
||||||
Log.ConsoleInfo(string.Format("Player {0} tried to sneak {1} onto the server!", args.Player.Name, item.name));
|
TShock.Log.ConsoleInfo("Player {0} tried to sneak {1} onto the server!", args.Player.Name, item.name);
|
||||||
args.Player.SendData(PacketTypes.ItemDrop, "", id);
|
args.Player.SendData(PacketTypes.ItemDrop, "", id);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -3382,12 +3370,12 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
if (spawnboss && !args.Player.Group.HasPermission(Permissions.summonboss))
|
if (spawnboss && !args.Player.Group.HasPermission(Permissions.summonboss))
|
||||||
{
|
{
|
||||||
args.Player.SendMessage("You don't have permission to summon a boss.", Color.Red);
|
args.Player.SendErrorMessage("You don't have permission to summon a boss.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (invasion && !args.Player.Group.HasPermission(Permissions.startinvasion))
|
if (invasion && !args.Player.Group.HasPermission(Permissions.startinvasion))
|
||||||
{
|
{
|
||||||
args.Player.SendMessage("You don't have permission to start an invasion.", Color.Red);
|
args.Player.SendErrorMessage("You don't have permission to start an invasion.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!spawnboss && !invasion)
|
if (!spawnboss && !invasion)
|
||||||
|
|
|
||||||
|
|
@ -153,13 +153,6 @@ namespace TShockAPI
|
||||||
public byte B = 255;
|
public byte B = 255;
|
||||||
|
|
||||||
public static Group DefaultGroup = null;
|
public static Group DefaultGroup = null;
|
||||||
#if COMPAT_SIGS
|
|
||||||
[Obsolete("This constructor is for signature compatibility for external code only")]
|
|
||||||
public Group(string groupname, Group parentgroup, string chatcolor)
|
|
||||||
: this(groupname, parentgroup, chatcolor, null)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public Group(string groupname, Group parentgroup = null, string chatcolor = "255,255,255", string permissions = null)
|
public Group(string groupname, Group parentgroup = null, string chatcolor = "255,255,255", string permissions = null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace TShockAPI.Hooks
|
||||||
{
|
{
|
||||||
public class AccountDeleteEventArgs
|
public class AccountDeleteEventArgs
|
||||||
{
|
{
|
||||||
public User User { get; set; }
|
public User User { get; private set; }
|
||||||
|
|
||||||
public AccountDeleteEventArgs(User user)
|
public AccountDeleteEventArgs(User user)
|
||||||
{
|
{
|
||||||
|
|
@ -31,7 +31,7 @@ namespace TShockAPI.Hooks
|
||||||
|
|
||||||
public class AccountCreateEventArgs
|
public class AccountCreateEventArgs
|
||||||
{
|
{
|
||||||
public User User { get; set; }
|
public User User { get; private set; }
|
||||||
|
|
||||||
public AccountCreateEventArgs(User user)
|
public AccountCreateEventArgs(User user)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
111
TShockAPI/Hooks/RegionHooks.cs
Normal file
111
TShockAPI/Hooks/RegionHooks.cs
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using TShockAPI.DB;
|
||||||
|
|
||||||
|
namespace TShockAPI.Hooks
|
||||||
|
{
|
||||||
|
public class RegionHooks
|
||||||
|
{
|
||||||
|
public class RegionEnteredEventArgs
|
||||||
|
{
|
||||||
|
public TSPlayer Player { get; private set; }
|
||||||
|
|
||||||
|
public RegionEnteredEventArgs(TSPlayer ply)
|
||||||
|
{
|
||||||
|
Player = ply;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void RegionEnteredD(RegionEnteredEventArgs args);
|
||||||
|
public static event RegionEnteredD RegionEntered;
|
||||||
|
public static void OnRegionEntered(TSPlayer player)
|
||||||
|
{
|
||||||
|
if (RegionEntered == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionEntered(new RegionEnteredEventArgs(player));
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RegionLeftEventArgs
|
||||||
|
{
|
||||||
|
public TSPlayer Player { get; private set; }
|
||||||
|
public Region Region { get; private set; }
|
||||||
|
|
||||||
|
public RegionLeftEventArgs(TSPlayer ply, Region region)
|
||||||
|
{
|
||||||
|
Player = ply;
|
||||||
|
Region = region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void RegionLeftD(RegionLeftEventArgs args);
|
||||||
|
public static event RegionLeftD RegionLeft;
|
||||||
|
public static void OnRegionLeft(TSPlayer player, Region region)
|
||||||
|
{
|
||||||
|
if (RegionLeft == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionLeft(new RegionLeftEventArgs(player, region));
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RegionCreatedEventArgs
|
||||||
|
{
|
||||||
|
public Region Region { get; private set; }
|
||||||
|
|
||||||
|
public RegionCreatedEventArgs(Region region)
|
||||||
|
{
|
||||||
|
Region = region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void RegionCreatedD(RegionCreatedEventArgs args);
|
||||||
|
public static event RegionCreatedD RegionCreated;
|
||||||
|
public static void OnRegionCreated(Region region)
|
||||||
|
{
|
||||||
|
if (RegionCreated == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RegionCreated(new RegionCreatedEventArgs(region));
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RegionDeletedEventArgs
|
||||||
|
{
|
||||||
|
public Region Region { get; private set; }
|
||||||
|
|
||||||
|
public RegionDeletedEventArgs(Region region)
|
||||||
|
{
|
||||||
|
Region = region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void RegionDeletedD(RegionDeletedEventArgs args);
|
||||||
|
public static event RegionDeletedD RegionDeleted;
|
||||||
|
public static void OnRegionDeleted(Region region)
|
||||||
|
{
|
||||||
|
if (RegionDeleted == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RegionDeleted(new RegionDeletedEventArgs(region));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
153
TShockAPI/ILog.cs
Normal file
153
TShockAPI/ILog.cs
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace TShockAPI
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum LogLevel
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Debug = 1,
|
||||||
|
Info = 2,
|
||||||
|
Warning = 4,
|
||||||
|
Error = 8,
|
||||||
|
Data = 16,
|
||||||
|
All = 31
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logging interface
|
||||||
|
/// </summary>
|
||||||
|
public interface ILog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Log name
|
||||||
|
/// </summary>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether the log level contains the specified flag.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The <see cref="LogLevel" /> value to check.</param>
|
||||||
|
bool MayWriteType(LogLevel type);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log and to the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
void ConsoleInfo(string message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log and to the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
void ConsoleInfo(string format, params object[] args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error message to the log and to the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
void ConsoleError(string message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error message to the log and to the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
void ConsoleError(string format, params object[] args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a warning to the log.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
void Warn(string message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a warning to the log.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
void Warn(string format, params object[] args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error to the log.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
void Error(string message);
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error to the log.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
void Error(string format, params object[] args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
void Info(string message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
void Info(string format, params object[] args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes data to the log.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
void Data(string message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes data to the log.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
void Data(string format, params object[] args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a message to the log
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">Message to write</param>
|
||||||
|
/// <param name="level">LogLevel assosciated with the message</param>
|
||||||
|
void Write(string message, LogLevel level);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a debug string to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
void Debug(String message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a debug string to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
void Debug(string format, params object[] args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dispose the Log
|
||||||
|
/// </summary>
|
||||||
|
void Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,57 +17,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace TShockAPI
|
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 class Log
|
||||||
{
|
{
|
||||||
private static string _filename;
|
|
||||||
private static LogLevel _logLevel;
|
|
||||||
private static StreamWriter _logWriter;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates the log file stream and sets the initial log level.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filename">The output filename. This file will be overwritten if 'clear' is set.</param>
|
|
||||||
/// <param name="logLevel">The <see cref="LogLevel" /> value which sets the type of messages to output.</param>
|
|
||||||
/// <param name="clear">Whether or not to clear the log file on initialization.</param>
|
|
||||||
public static void Initialize(string filename, LogLevel logLevel, bool clear)
|
|
||||||
{
|
|
||||||
_filename = filename;
|
|
||||||
_logLevel = logLevel;
|
|
||||||
|
|
||||||
_logWriter = new StreamWriter(filename, !clear);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks whether the log level contains the specified flag.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The <see cref="LogLevel" /> value to check.</param>
|
|
||||||
private static bool MayWriteType(LogLevel type)
|
|
||||||
{
|
|
||||||
return ((_logLevel & type) == type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes data to the log file.
|
/// Writes data to the log file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The message to be written.</param>
|
/// <param name="message">The message to be written.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.Data")]
|
||||||
public static void Data(String message)
|
public static void Data(String message)
|
||||||
{
|
{
|
||||||
Write(message, LogLevel.Data);
|
Write(message, LogLevel.Data);
|
||||||
|
|
@ -78,6 +37,7 @@ namespace TShockAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="format">The format of the message to be written.</param>
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
/// <param name="args">The format arguments.</param>
|
/// <param name="args">The format arguments.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.Data")]
|
||||||
public static void Data(string format, params object[] args)
|
public static void Data(string format, params object[] args)
|
||||||
{
|
{
|
||||||
Data(String.Format(format, args));
|
Data(String.Format(format, args));
|
||||||
|
|
@ -87,6 +47,7 @@ namespace TShockAPI
|
||||||
/// Writes an error to the log file.
|
/// Writes an error to the log file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The message to be written.</param>
|
/// <param name="message">The message to be written.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.Error")]
|
||||||
public static void Error(String message)
|
public static void Error(String message)
|
||||||
{
|
{
|
||||||
Write(message, LogLevel.Error);
|
Write(message, LogLevel.Error);
|
||||||
|
|
@ -97,6 +58,7 @@ namespace TShockAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="format">The format of the message to be written.</param>
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
/// <param name="args">The format arguments.</param>
|
/// <param name="args">The format arguments.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.Error")]
|
||||||
public static void Error(string format, params object[] args)
|
public static void Error(string format, params object[] args)
|
||||||
{
|
{
|
||||||
Error(String.Format(format, args));
|
Error(String.Format(format, args));
|
||||||
|
|
@ -106,6 +68,7 @@ namespace TShockAPI
|
||||||
/// Writes an error to the log file.
|
/// Writes an error to the log file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The message to be written.</param>
|
/// <param name="message">The message to be written.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.ConsoleError")]
|
||||||
public static void ConsoleError(String message)
|
public static void ConsoleError(String message)
|
||||||
{
|
{
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
|
@ -119,6 +82,7 @@ namespace TShockAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="format">The format of the message to be written.</param>
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
/// <param name="args">The format arguments.</param>
|
/// <param name="args">The format arguments.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.ConsoleError")]
|
||||||
public static void ConsoleError(string format, params object[] args)
|
public static void ConsoleError(string format, params object[] args)
|
||||||
{
|
{
|
||||||
ConsoleError(String.Format(format, args));
|
ConsoleError(String.Format(format, args));
|
||||||
|
|
@ -128,6 +92,7 @@ namespace TShockAPI
|
||||||
/// Writes a warning to the log file.
|
/// Writes a warning to the log file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The message to be written.</param>
|
/// <param name="message">The message to be written.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.Warn")]
|
||||||
public static void Warn(String message)
|
public static void Warn(String message)
|
||||||
{
|
{
|
||||||
Write(message, LogLevel.Warning);
|
Write(message, LogLevel.Warning);
|
||||||
|
|
@ -138,6 +103,7 @@ namespace TShockAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="format">The format of the message to be written.</param>
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
/// <param name="args">The format arguments.</param>
|
/// <param name="args">The format arguments.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.Warn")]
|
||||||
public static void Warn(string format, params object[] args)
|
public static void Warn(string format, params object[] args)
|
||||||
{
|
{
|
||||||
Warn(String.Format(format, args));
|
Warn(String.Format(format, args));
|
||||||
|
|
@ -147,6 +113,7 @@ namespace TShockAPI
|
||||||
/// Writes an informative string to the log file.
|
/// Writes an informative string to the log file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The message to be written.</param>
|
/// <param name="message">The message to be written.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.Info")]
|
||||||
public static void Info(String message)
|
public static void Info(String message)
|
||||||
{
|
{
|
||||||
Write(message, LogLevel.Info);
|
Write(message, LogLevel.Info);
|
||||||
|
|
@ -157,6 +124,7 @@ namespace TShockAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="format">The format of the message to be written.</param>
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
/// <param name="args">The format arguments.</param>
|
/// <param name="args">The format arguments.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.Info")]
|
||||||
public static void Info(string format, params object[] args)
|
public static void Info(string format, params object[] args)
|
||||||
{
|
{
|
||||||
Info(String.Format(format, 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.
|
/// Writes an informative string to the log file. Also outputs to the console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The message to be written.</param>
|
/// <param name="message">The message to be written.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.ConsoleInfo")]
|
||||||
public static void ConsoleInfo(String message)
|
public static void ConsoleInfo(String message)
|
||||||
{
|
{
|
||||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
|
@ -179,6 +148,7 @@ namespace TShockAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="format">The format of the message to be written.</param>
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
/// <param name="args">The format arguments.</param>
|
/// <param name="args">The format arguments.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.ConsoleInfo")]
|
||||||
public static void ConsoleInfo(string format, params object[] args)
|
public static void ConsoleInfo(string format, params object[] args)
|
||||||
{
|
{
|
||||||
ConsoleInfo(String.Format(format, args));
|
ConsoleInfo(String.Format(format, args));
|
||||||
|
|
@ -188,6 +158,7 @@ namespace TShockAPI
|
||||||
/// Writes a debug string to the log file.
|
/// Writes a debug string to the log file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The message to be written.</param>
|
/// <param name="message">The message to be written.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.Debug")]
|
||||||
public static void Debug(String message)
|
public static void Debug(String message)
|
||||||
{
|
{
|
||||||
Write(message, LogLevel.Debug);
|
Write(message, LogLevel.Debug);
|
||||||
|
|
@ -198,53 +169,18 @@ namespace TShockAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="format">The format of the message to be written.</param>
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
/// <param name="args">The format arguments.</param>
|
/// <param name="args">The format arguments.</param>
|
||||||
|
[Obsolete("Please use TShock.Log.Debug")]
|
||||||
public static void Debug(string format, params object[] args)
|
public static void Debug(string format, params object[] args)
|
||||||
{
|
{
|
||||||
Debug(String.Format(format, args));
|
Debug(String.Format(format, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disposes objects that are being used.
|
|
||||||
/// </summary>
|
|
||||||
public static void Dispose()
|
|
||||||
{
|
|
||||||
_logWriter.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Internal method which writes a message directly to the log file.
|
/// Internal method which writes a message directly to the log file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void Write(String message, LogLevel level)
|
private static void Write(String message, LogLevel level)
|
||||||
{
|
{
|
||||||
if (!MayWriteType(level))
|
TShock.Log.Write(message, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +145,7 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.ConsoleError(e.ToString());
|
TShock.Log.ConsoleError(e.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -206,7 +206,7 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
catch (ObjectDisposedException e)
|
catch (ObjectDisposedException e)
|
||||||
{
|
{
|
||||||
Log.Warn(e.ToString());
|
TShock.Log.Warn(e.ToString());
|
||||||
}
|
}
|
||||||
catch (SocketException e)
|
catch (SocketException e)
|
||||||
{
|
{
|
||||||
|
|
@ -216,7 +216,7 @@ namespace TShockAPI
|
||||||
case 10053:
|
case 10053:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.Warn(e.ToString());
|
TShock.Log.Warn(e.ToString());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -230,12 +230,12 @@ namespace TShockAPI
|
||||||
case SocketError.ConnectionReset:
|
case SocketError.ConnectionReset:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.Warn(e.ToString());
|
TShock.Log.Warn(e.ToString());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Log.Warn(e.ToString());
|
TShock.Log.Warn(e.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -349,6 +349,9 @@ namespace TShockAPI
|
||||||
[Description("Player recovers health as damage is taken. Can be one shotted.")]
|
[Description("Player recovers health as damage is taken. Can be one shotted.")]
|
||||||
public static readonly string godmode = "tshock.godmode";
|
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")]
|
[Description("Player can chat")]
|
||||||
public static readonly string canchat = "tshock.canchat";
|
public static readonly string canchat = "tshock.canchat";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,5 +53,5 @@ using System.Runtime.InteropServices;
|
||||||
// Also, be sure to release on github with the exact assembly version tag as below
|
// Also, be sure to release on github with the exact assembly version tag as below
|
||||||
// so that the update manager works correctly (via the Github releases api and mimic)
|
// so that the update manager works correctly (via the Github releases api and mimic)
|
||||||
|
|
||||||
[assembly: AssemblyVersion("4.2.6")]
|
[assembly: AssemblyVersion("4.2.7")]
|
||||||
[assembly: AssemblyFileVersion("4.2.6")]
|
[assembly: AssemblyFileVersion("4.2.7")]
|
||||||
|
|
|
||||||
|
|
@ -1,454 +0,0 @@
|
||||||
/*
|
|
||||||
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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Streams;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
using Terraria;
|
|
||||||
|
|
||||||
namespace TShockAPI
|
|
||||||
{
|
|
||||||
internal class RconHandler
|
|
||||||
{
|
|
||||||
public static string Password = "";
|
|
||||||
private static DateTime LastRequest;
|
|
||||||
private static DateTime LastHeartbeat;
|
|
||||||
public static int ListenPort;
|
|
||||||
public static bool ContinueServer = true;
|
|
||||||
public static string Response = "";
|
|
||||||
private static bool Started;
|
|
||||||
private static UdpClient listener;
|
|
||||||
private static Thread startThread;
|
|
||||||
private static Thread heartbeat;
|
|
||||||
private static Thread listen;
|
|
||||||
|
|
||||||
public static void ShutdownAllThreads()
|
|
||||||
{
|
|
||||||
if (Started)
|
|
||||||
{
|
|
||||||
startThread.Abort();
|
|
||||||
heartbeat.Abort();
|
|
||||||
listen.Abort();
|
|
||||||
Started = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void StartThread()
|
|
||||||
{
|
|
||||||
if (!Started)
|
|
||||||
{
|
|
||||||
startThread = new Thread(Start);
|
|
||||||
startThread.Start();
|
|
||||||
|
|
||||||
heartbeat = new Thread(SendHeartbeat);
|
|
||||||
heartbeat.Start();
|
|
||||||
}
|
|
||||||
Started = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Start()
|
|
||||||
{
|
|
||||||
Log.Info("Starting RconHandler.");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Console.WriteLine(string.Format("RconHandler is running at UDP port {0} and password is {1}",
|
|
||||||
ListenPort,
|
|
||||||
Password));
|
|
||||||
listen = new Thread(Listener);
|
|
||||||
listen.Start();
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (listen.ThreadState != ThreadState.Running)
|
|
||||||
{
|
|
||||||
listen.Abort();
|
|
||||||
while (listen.ThreadState != ThreadState.Stopped)
|
|
||||||
continue;
|
|
||||||
listen.Start();
|
|
||||||
}
|
|
||||||
Thread.Sleep(3000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.Error(e.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Listener()
|
|
||||||
{
|
|
||||||
if (listener == null)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
listener = new UdpClient(ListenPort);
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
if (e.SocketErrorCode == SocketError.AddressAlreadyInUse)
|
|
||||||
Log.ConsoleError("Could not bind to " + ListenPort + ". Are you sure you don't have another instance running?");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.Error(e.ToString());
|
|
||||||
}
|
|
||||||
while (ContinueServer)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var listenEP = new IPEndPoint(IPAddress.Any, ListenPort);
|
|
||||||
LastRequest = DateTime.Now;
|
|
||||||
byte[] bytes = listener.Receive(ref listenEP);
|
|
||||||
var packet = ParsePacket(bytes, listenEP);
|
|
||||||
listener.Send(packet, packet.Length, listenEP);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.Error(e.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string SendPacket(byte[] bytes, string hostname, int port)
|
|
||||||
{
|
|
||||||
var response = Encoding.UTF8.GetString(new byte[] {0xFF, 0xFF, 0xFF, 0xFF}) + "disconnect";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var EP = new IPEndPoint(IPAddress.Any, port);
|
|
||||||
using (var client = new UdpClient())
|
|
||||||
{
|
|
||||||
client.Connect(hostname, port);
|
|
||||||
client.Client.ReceiveTimeout = 500;
|
|
||||||
client.Send(bytes, bytes.Length);
|
|
||||||
response = Encoding.UTF8.GetString(client.Receive(ref EP));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.Error(e.ToString());
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] ParsePacket(byte[] bytes, IPEndPoint EP)
|
|
||||||
{
|
|
||||||
string response = "";
|
|
||||||
var packetstring = Encoding.UTF8.GetString(PadPacket(bytes));
|
|
||||||
var redirect = false;
|
|
||||||
var print = true;
|
|
||||||
if ((DateTime.Now - LastRequest).Milliseconds >= 100)
|
|
||||||
{
|
|
||||||
if (packetstring.StartsWith("rcon") || packetstring.Substring(4).StartsWith("rcon") ||
|
|
||||||
packetstring.Substring(5).StartsWith("rcon"))
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(Password))
|
|
||||||
{
|
|
||||||
var args = ParseParameters(packetstring);
|
|
||||||
if (args.Count >= 3)
|
|
||||||
{
|
|
||||||
if (args[1] == Password)
|
|
||||||
{
|
|
||||||
args[1] = args[0] = "";
|
|
||||||
string command = string.Join(" ", args.ToArray());
|
|
||||||
command = command.TrimEnd(' ').TrimEnd('\0').TrimStart(' ');
|
|
||||||
Log.ConsoleInfo("Rcon from " + EP + ":" + command);
|
|
||||||
Response = "";
|
|
||||||
response = ExecuteCommand(command);
|
|
||||||
response += "\n" + Response;
|
|
||||||
Response = "";
|
|
||||||
response = response.TrimStart('\n');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
response = "Bad rcon password.\n";
|
|
||||||
Log.ConsoleInfo("Bad rcon password from " + EP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
response = "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
response = "No rcon password set on the server.\n";
|
|
||||||
Log.Info("No password for rcon set");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
redirect = true;
|
|
||||||
}
|
|
||||||
if (packetstring.StartsWith("getinfo")
|
|
||||||
|| packetstring.Substring(4).StartsWith("getinfo")
|
|
||||||
|| packetstring.Substring(5).StartsWith("getinfo"))
|
|
||||||
{
|
|
||||||
var challenge = "";
|
|
||||||
if (packetstring.Split(' ').Length == 2)
|
|
||||||
challenge = packetstring.Split(' ')[1];
|
|
||||||
response = "infoResponse\n";
|
|
||||||
var infostring =
|
|
||||||
string.Format(
|
|
||||||
@"\_TShock_ver\{6}\mapname\{1}\sv_maxclients\{2}\clients\{3}\sv_privateClients\{4}\hconly\{5}\gamename\TERRARIA\protocol\100\sv_hostname\{0}\g_needPass\{7}",
|
|
||||||
TShock.Config.ServerName, Main.worldName, Main.maxNetPlayers,
|
|
||||||
TShock.Utils.ActivePlayers(), Main.maxNetPlayers - TShock.Config.MaxSlots,
|
|
||||||
TShock.Config.HardcoreOnly ? 1 : 0, TShock.VersionNum,
|
|
||||||
Netplay.password != "" ? 1 : 0);
|
|
||||||
if (challenge != "")
|
|
||||||
infostring += @"\challenge\" + challenge;
|
|
||||||
response += infostring;
|
|
||||||
print = false;
|
|
||||||
redirect = false;
|
|
||||||
}
|
|
||||||
else if (packetstring.StartsWith("getstatus")
|
|
||||||
|| packetstring.Substring(4).StartsWith("getstatus")
|
|
||||||
|| packetstring.Substring(5).StartsWith("getstatus"))
|
|
||||||
{
|
|
||||||
var challenge = "";
|
|
||||||
if (packetstring.Split(' ').Length == 2)
|
|
||||||
challenge = packetstring.Split(' ')[1];
|
|
||||||
response = "statusResponse\n";
|
|
||||||
var statusstring = string.Format(
|
|
||||||
@"\_TShock_ver\{6}\mapname\{1}\sv_maxclients\{2}\clients\{3}\sv_privateClients\{4}\hconly\{5}\gamename\TERRARIA\protocol\100\sv_hostname\{0}\g_needPass\{7}",
|
|
||||||
TShock.Config.ServerName, Main.worldName, Main.maxNetPlayers,
|
|
||||||
TShock.Utils.ActivePlayers(), Main.maxNetPlayers - TShock.Config.MaxSlots,
|
|
||||||
TShock.Config.HardcoreOnly ? 1 : 0, TShock.VersionNum,
|
|
||||||
Netplay.password != "" ? 1 : 0) + "\n";
|
|
||||||
if (challenge != "")
|
|
||||||
statusstring += @"\challenge\" + challenge;
|
|
||||||
foreach (TSPlayer player in TShock.Players)
|
|
||||||
{
|
|
||||||
if (player != null && player.Active)
|
|
||||||
statusstring += (string.Format("0 0 {0}\n", player.Name));
|
|
||||||
}
|
|
||||||
response += statusstring;
|
|
||||||
print = false;
|
|
||||||
redirect = false;
|
|
||||||
}
|
|
||||||
if (!redirect)
|
|
||||||
return (ConstructPacket(response, print));
|
|
||||||
else
|
|
||||||
return (ConstructPacket("disconnect", false));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string ExecuteCommand(string text)
|
|
||||||
{
|
|
||||||
if (Main.rand == null)
|
|
||||||
Main.rand = new Random();
|
|
||||||
if (WorldGen.genRand == null)
|
|
||||||
WorldGen.genRand = new Random();
|
|
||||||
if (text.StartsWith("exit"))
|
|
||||||
{
|
|
||||||
TShock.Utils.StopServer();
|
|
||||||
return "Server shutting down.";
|
|
||||||
}
|
|
||||||
else if (text.StartsWith("playing") || text.StartsWith("/playing"))
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
foreach (TSPlayer player in TShock.Players)
|
|
||||||
{
|
|
||||||
if (player != null && player.Active)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}] <{3}>", player.Name, player.IP, player.Group.Name,
|
|
||||||
player.UserAccountName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TSPlayer.Server.SendMessage(string.Format("{0} players connected.", count));
|
|
||||||
}
|
|
||||||
else if (text.StartsWith("status"))
|
|
||||||
{
|
|
||||||
Response += "map: " + Main.worldName + "\n";
|
|
||||||
Response += "num score ping name lastmsg address qport rate\n";
|
|
||||||
int count = 0;
|
|
||||||
foreach (TSPlayer player in TShock.Players)
|
|
||||||
{
|
|
||||||
if (player != null && player.Active)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
Response +=
|
|
||||||
(string.Format("{0} 0 0 {1}({2}) {3} {4} 0 0", count, player.Name, player.Group.Name,
|
|
||||||
Netplay.serverSock[player.Index].tcpClient.Client.RemoteEndPoint, "")) + "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (text.StartsWith("say "))
|
|
||||||
{
|
|
||||||
Log.Info(string.Format("Server said: {0}", text.Remove(0, 4)));
|
|
||||||
return string.Format("Server said: {0}", text.Remove(0, 4));
|
|
||||||
}
|
|
||||||
else if (text == "autosave")
|
|
||||||
{
|
|
||||||
Main.autoSave = TShock.Config.AutoSave = !TShock.Config.AutoSave;
|
|
||||||
Log.ConsoleInfo("AutoSave " + (TShock.Config.AutoSave ? "Enabled" : "Disabled"));
|
|
||||||
return "AutoSave " + (TShock.Config.AutoSave ? "Enabled" : "Disabled");
|
|
||||||
}
|
|
||||||
else if (text.StartsWith("/"))
|
|
||||||
{
|
|
||||||
if (!Commands.HandleCommand(TSPlayer.Server, text))
|
|
||||||
return "Invalid command.";
|
|
||||||
}
|
|
||||||
else if (!Commands.HandleCommand(TSPlayer.Server, "/" + text))
|
|
||||||
return "Invalid command.";
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] ConstructPacket(string response, bool print)
|
|
||||||
{
|
|
||||||
var oob = new byte[] {0xFF, 0xFF, 0xFF, 0xFF};
|
|
||||||
using (var stream = new MemoryStream())
|
|
||||||
{
|
|
||||||
stream.WriteBytes(oob);
|
|
||||||
if (print)
|
|
||||||
stream.WriteBytes(Encoding.UTF8.GetBytes(string.Format("print\n{0}", response)));
|
|
||||||
else
|
|
||||||
stream.WriteBytes(Encoding.UTF8.GetBytes(response));
|
|
||||||
var trimmedpacket = new byte[(int) stream.Length];
|
|
||||||
var packet = stream.GetBuffer();
|
|
||||||
Array.Copy(packet, trimmedpacket, (int) stream.Length);
|
|
||||||
return trimmedpacket;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] PadPacket(byte[] packet)
|
|
||||||
{
|
|
||||||
var returnpacket = new byte[(4 + packet.Length)];
|
|
||||||
int h = 0;
|
|
||||||
if (packet[0] != 0xFF)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
returnpacket[i] = 0xFF;
|
|
||||||
for (int i = 4; i < returnpacket.Length; i++)
|
|
||||||
returnpacket[i] = packet[h++];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
returnpacket = packet;
|
|
||||||
return returnpacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SendHeartbeat()
|
|
||||||
{
|
|
||||||
LastHeartbeat = DateTime.UtcNow.Subtract(new TimeSpan(0, 0, 30));
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if ((DateTime.UtcNow - LastHeartbeat).Seconds >= 30)
|
|
||||||
{
|
|
||||||
var packet = ConstructPacket("heartbeat TerrariaShock", false);
|
|
||||||
if (listener == null)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
listener = new UdpClient(ListenPort);
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
if (e.SocketErrorCode == SocketError.AddressAlreadyInUse)
|
|
||||||
Log.ConsoleError("Could not bind to " + ListenPort + ". Are you sure you don't have another instance running?");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.Error(e.ToString());
|
|
||||||
}
|
|
||||||
listener.Send(packet, packet.Length, TShock.Config.MasterServer, 27950);
|
|
||||||
LastHeartbeat = DateTime.UtcNow;
|
|
||||||
}
|
|
||||||
Thread.Sleep(10000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region ParseParams
|
|
||||||
|
|
||||||
private static List<String> ParseParameters(string str)
|
|
||||||
{
|
|
||||||
var ret = new List<string>();
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
bool instr = false;
|
|
||||||
for (int i = 0; i < str.Length; i++)
|
|
||||||
{
|
|
||||||
char c = str[i];
|
|
||||||
|
|
||||||
if (instr)
|
|
||||||
{
|
|
||||||
if (c == '\\')
|
|
||||||
{
|
|
||||||
if (i + 1 >= str.Length)
|
|
||||||
break;
|
|
||||||
c = GetEscape(str[++i]);
|
|
||||||
}
|
|
||||||
else if (c == '"')
|
|
||||||
{
|
|
||||||
ret.Add(sb.ToString());
|
|
||||||
sb.Clear();
|
|
||||||
instr = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
sb.Append(c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (IsWhiteSpace(c))
|
|
||||||
{
|
|
||||||
if (sb.Length > 0)
|
|
||||||
{
|
|
||||||
ret.Add(sb.ToString());
|
|
||||||
sb.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (c == '"')
|
|
||||||
{
|
|
||||||
if (sb.Length > 0)
|
|
||||||
{
|
|
||||||
ret.Add(sb.ToString());
|
|
||||||
sb.Clear();
|
|
||||||
}
|
|
||||||
instr = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.Append(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sb.Length > 0)
|
|
||||||
ret.Add(sb.ToString());
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static char GetEscape(char c)
|
|
||||||
{
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '\\':
|
|
||||||
return '\\';
|
|
||||||
case '"':
|
|
||||||
return '"';
|
|
||||||
case 't':
|
|
||||||
return '\t';
|
|
||||||
default:
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsWhiteSpace(char c)
|
|
||||||
{
|
|
||||||
return c == ' ' || c == '\t' || c == '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -157,7 +157,8 @@ namespace Rests
|
||||||
e.Response.Connection.Type = ConnectionType.Close;
|
e.Response.Connection.Type = ConnectionType.Close;
|
||||||
e.Response.ContentType = new ContentTypeHeader("application/json; charset=utf-8");
|
e.Response.ContentType = new ContentTypeHeader("application/json; charset=utf-8");
|
||||||
e.Response.Add(serverHeader);
|
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;
|
e.Response.Status = HttpStatusCode.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -212,7 +213,7 @@ namespace Rests
|
||||||
object result = cmd.Execute(verbs, parms, request);
|
object result = cmd.Execute(verbs, parms, request);
|
||||||
if (cmd.DoLog && TShock.Config.LogRest)
|
if (cmd.DoLog && TShock.Config.LogRest)
|
||||||
{
|
{
|
||||||
Log.ConsoleInfo("Anonymous requested REST endpoint: " + BuildRequestUri(cmd, verbs, parms, false));
|
TShock.Log.ConsoleInfo("Anonymous requested REST endpoint: " + BuildRequestUri(cmd, verbs, parms, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ namespace TShockAPI
|
||||||
var msg = args.Parameters["msg"];
|
var msg = args.Parameters["msg"];
|
||||||
if (string.IsNullOrWhiteSpace(msg))
|
if (string.IsNullOrWhiteSpace(msg))
|
||||||
return RestMissingParam("msg");
|
return RestMissingParam("msg");
|
||||||
TShock.Utils.Broadcast(msg);
|
TSPlayer.All.SendInfoMessage(msg);
|
||||||
return RestResponse("The message was broadcasted successfully");
|
return RestResponse("The message was broadcasted successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -660,7 +660,7 @@ namespace TShockAPI
|
||||||
TSPlayer player = (TSPlayer)ret;
|
TSPlayer player = (TSPlayer)ret;
|
||||||
player.DamagePlayer(999999);
|
player.DamagePlayer(999999);
|
||||||
var from = string.IsNullOrWhiteSpace(args.Parameters["from"]) ? "Server Admin" : args.Parameters["from"];
|
var from = string.IsNullOrWhiteSpace(args.Parameters["from"]) ? "Server Admin" : args.Parameters["from"];
|
||||||
player.SendMessage(string.Format("{0} just killed you!", from));
|
player.SendInfoMessage(string.Format("{0} just killed you!", from));
|
||||||
return RestResponse("Player " + player.Name + " was killed");
|
return RestResponse("Player " + player.Name + " was killed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -916,7 +916,7 @@ namespace TShockAPI
|
||||||
TSPlayer player = (TSPlayer)ret;
|
TSPlayer player = (TSPlayer)ret;
|
||||||
player.mute = mute;
|
player.mute = mute;
|
||||||
var verb = mute ? "muted" : "unmuted";
|
var verb = mute ? "muted" : "unmuted";
|
||||||
player.SendMessage("You have been remotely " + verb);
|
player.SendInfoMessage("You have been remotely " + verb);
|
||||||
return RestResponse("Player " + player.Name + " was " + verb);
|
return RestResponse("Player " + player.Name + " was " + verb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ namespace Rests
|
||||||
"The old model will be removed with the next maintenance release of TShock. In order to switch to the new model, ",
|
"The old model will be removed with the next maintenance release of TShock. In order to switch to the new model, ",
|
||||||
"change the config setting \"RestUseNewPermissionModel\" to true."
|
"change the config setting \"RestUseNewPermissionModel\" to true."
|
||||||
);
|
);
|
||||||
Log.Warn(warningMessage);
|
TShock.Log.Warn(warningMessage);
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
Console.WriteLine(warningMessage);
|
Console.WriteLine(warningMessage);
|
||||||
Console.ForegroundColor = ConsoleColor.Gray;
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
|
|
@ -80,7 +80,7 @@ namespace Rests
|
||||||
"with existing REST services. If compatibility problems occur, you can switch back to the unsecure permission ",
|
"with existing REST services. If compatibility problems occur, you can switch back to the unsecure permission ",
|
||||||
"model by changing the config setting \"RestUseNewPermissionModel\" to false, which is not recommended."
|
"model by changing the config setting \"RestUseNewPermissionModel\" to false, which is not recommended."
|
||||||
);
|
);
|
||||||
Log.ConsoleInfo(warningMessage);
|
TShock.Log.ConsoleInfo(warningMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,8 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error("World saved notification failed");
|
TShock.Log.Error("World saved notification failed");
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -130,12 +130,12 @@ namespace TShockAPI
|
||||||
else
|
else
|
||||||
WorldFile.saveWorld(task.resetTime);
|
WorldFile.saveWorld(task.resetTime);
|
||||||
TShock.Utils.Broadcast("World saved.", Color.Yellow);
|
TShock.Utils.Broadcast("World saved.", Color.Yellow);
|
||||||
Log.Info(string.Format("World saved at ({0})", Main.worldPathName));
|
TShock.Log.Info(string.Format("World saved at ({0})", Main.worldPathName));
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.Error("World saved failed");
|
TShock.Log.Error("World saved failed");
|
||||||
Log.Error(e.ToString());
|
TShock.Log.Error(e.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
295
TShockAPI/SqlLog.cs
Normal file
295
TShockAPI/SqlLog.cs
Normal file
|
|
@ -0,0 +1,295 @@
|
||||||
|
/*
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using TShockAPI.DB;
|
||||||
|
|
||||||
|
namespace TShockAPI
|
||||||
|
{
|
||||||
|
struct LogInfo
|
||||||
|
{
|
||||||
|
public string timestamp;
|
||||||
|
public string message;
|
||||||
|
public string caller;
|
||||||
|
public LogLevel logLevel;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return String.Format("Message: {0}: {1}: {2}",
|
||||||
|
caller, logLevel.ToString().ToUpper(), message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Class inheriting ILog for writing logs to TShock's SQL database
|
||||||
|
/// </summary>
|
||||||
|
public class SqlLog : ILog, IDisposable
|
||||||
|
{
|
||||||
|
private readonly LogLevel _logLevel;
|
||||||
|
private readonly IDbConnection _database;
|
||||||
|
private readonly TextLog _backupLog;
|
||||||
|
private readonly List<LogInfo> _failures = new List<LogInfo>(TShock.Config.RevertToTextLogsOnSqlFailures);
|
||||||
|
private bool _useTextLog;
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "SQL Log Writer"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes data to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void Data(String message)
|
||||||
|
{
|
||||||
|
Write(message, LogLevel.Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes data to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void Data(string format, params object[] args)
|
||||||
|
{
|
||||||
|
Data(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void Error(String message)
|
||||||
|
{
|
||||||
|
Write(message, LogLevel.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void Error(string format, params object[] args)
|
||||||
|
{
|
||||||
|
Error(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void ConsoleError(String message)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.WriteLine(message);
|
||||||
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
|
Write(message, LogLevel.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void ConsoleError(string format, params object[] args)
|
||||||
|
{
|
||||||
|
ConsoleError(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a warning to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void Warn(String message)
|
||||||
|
{
|
||||||
|
Write(message, LogLevel.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a warning to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void Warn(string format, params object[] args)
|
||||||
|
{
|
||||||
|
Warn(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void Info(String message)
|
||||||
|
{
|
||||||
|
Write(message, LogLevel.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void Info(string format, params object[] args)
|
||||||
|
{
|
||||||
|
Info(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log file. Also outputs to the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void ConsoleInfo(String message)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.WriteLine(message);
|
||||||
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
|
Write(message, LogLevel.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log file. Also outputs to the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void ConsoleInfo(string format, params object[] args)
|
||||||
|
{
|
||||||
|
ConsoleInfo(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a debug string to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void Debug(String message)
|
||||||
|
{
|
||||||
|
Write(message, LogLevel.Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a debug string to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
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);
|
||||||
|
|
||||||
|
var success = true;
|
||||||
|
while (_failures.Count > 0 && success)
|
||||||
|
{
|
||||||
|
var info = _failures.First();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_database.Query("INSERT INTO Logs (LogLevel, TimeStamp, Caller, Message) VALUES (@0, @1, @2, @3)",
|
||||||
|
info.logLevel, info.timestamp, info.caller, info.message);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
_failures.Add(new LogInfo
|
||||||
|
{
|
||||||
|
caller = "TShock",
|
||||||
|
logLevel = LogLevel.Error,
|
||||||
|
message = String.Format("SQL Log insert query failed: {0}", ex),
|
||||||
|
timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
_failures.RemoveAt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_backupLog.ConsoleError("SQL Log insert query failed: {0}", ex);
|
||||||
|
|
||||||
|
_failures.Add(new LogInfo
|
||||||
|
{
|
||||||
|
logLevel = level,
|
||||||
|
message = message,
|
||||||
|
caller = caller,
|
||||||
|
timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_failures.Count >= TShock.Config.RevertToTextLogsOnSqlFailures)
|
||||||
|
{
|
||||||
|
_useTextLog = true;
|
||||||
|
_backupLog.ConsoleError("SQL Logging disabled due to errors. Reverting to text logging.");
|
||||||
|
|
||||||
|
foreach(var logInfo in _failures)
|
||||||
|
{
|
||||||
|
_backupLog.Write(String.Format("SQL log failed at: {0}. {1}", logInfo.timestamp, logInfo),
|
||||||
|
LogLevel.Error);
|
||||||
|
}
|
||||||
|
_failures.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_backupLog.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4
TShockAPI/StatTracker.cs
Normal file → Executable file
4
TShockAPI/StatTracker.cs
Normal file → Executable file
|
|
@ -45,7 +45,7 @@ namespace TShockAPI
|
||||||
|
|
||||||
var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(data);
|
var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(data);
|
||||||
var encoded = HttpUtility.UrlEncode(serialized);
|
var encoded = HttpUtility.UrlEncode(serialized);
|
||||||
var uri = String.Format("http://96.47.231.227:8000?data={0}", encoded);
|
var uri = String.Format("http://stats.tshock.co/publish/{0}", encoded);
|
||||||
var client = (HttpWebRequest)WebRequest.Create(uri);
|
var client = (HttpWebRequest)WebRequest.Create(uri);
|
||||||
client.Timeout = 5000;
|
client.Timeout = 5000;
|
||||||
try
|
try
|
||||||
|
|
@ -64,7 +64,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (!failed)
|
if (!failed)
|
||||||
{
|
{
|
||||||
Log.ConsoleError("StatTracker Exception: {0}", e);
|
TShock.Log.ConsoleError("StatTracker Exception: {0}", e);
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,11 @@ namespace TShockAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int LastKilledProjectile = 0;
|
public int LastKilledProjectile = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current region this player is in, or null if none.
|
||||||
|
/// </summary>
|
||||||
|
public Region CurrentRegion = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the player is a real, human, player on the server.
|
/// Whether the player is a real, human, player on the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -387,12 +392,12 @@ namespace TShockAPI
|
||||||
PlayerData.CopyCharacter(this);
|
PlayerData.CopyCharacter(this);
|
||||||
TShock.CharacterDB.InsertPlayerData(this);
|
TShock.CharacterDB.InsertPlayerData(this);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e)
|
}
|
||||||
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.Error(e.Message);
|
TShock.Log.Error(e.Message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -412,7 +417,7 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.Error(e.Message);
|
TShock.Log.Error(e.Message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -622,7 +627,6 @@ namespace TShockAPI
|
||||||
|
|
||||||
public void Spawn()
|
public void Spawn()
|
||||||
{
|
{
|
||||||
// TPlayer.FindSpawn();
|
|
||||||
if (this.sX > 0 && this.sY > 0)
|
if (this.sX > 0 && this.sY > 0)
|
||||||
{
|
{
|
||||||
Spawn(this.sX, this.sY);
|
Spawn(this.sX, this.sY);
|
||||||
|
|
@ -707,7 +711,7 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
TShock.Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -780,12 +784,6 @@ namespace TShockAPI
|
||||||
SendErrorMessage(string.Format(format, args));
|
SendErrorMessage(string.Format(format, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use SendErrorMessage, SendInfoMessage, or SendWarningMessage, or a custom color instead.")]
|
|
||||||
public virtual void SendMessage(string msg)
|
|
||||||
{
|
|
||||||
SendMessage(msg, 0, 255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void SendMessage(string msg, Color color)
|
public virtual void SendMessage(string msg, Color color)
|
||||||
{
|
{
|
||||||
SendMessage(msg, color.R, color.G, color.B);
|
SendMessage(msg, color.R, color.G, color.B);
|
||||||
|
|
@ -836,11 +834,11 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (displayConsole)
|
if (displayConsole)
|
||||||
{
|
{
|
||||||
Log.ConsoleInfo(string.Format("Player {0} has been disabled for {1}.", Name, reason));
|
TShock.Log.ConsoleInfo("Player {0} has been disabled for {1}.", Name, reason);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Info("Player {0} has been disabled for {1}.", Name, reason);
|
TShock.Log.Info("Player {0} has been disabled for {1}.", Name, reason);
|
||||||
}
|
}
|
||||||
LastDisableNotification = DateTime.UtcNow;
|
LastDisableNotification = DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
|
|
@ -849,7 +847,7 @@ namespace TShockAPI
|
||||||
StackFrame frame = null;
|
StackFrame frame = null;
|
||||||
frame = trace.GetFrame(1);
|
frame = trace.GetFrame(1);
|
||||||
if (frame != null && frame.GetMethod().DeclaringType != null)
|
if (frame != null && frame.GetMethod().DeclaringType != null)
|
||||||
Log.Debug(frame.GetMethod().DeclaringType.Name + " called Disable().");
|
TShock.Log.Debug(frame.GetMethod().DeclaringType.Name + " called Disable().");
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Whoopie(object time)
|
public virtual void Whoopie(object time)
|
||||||
|
|
@ -857,7 +855,7 @@ namespace TShockAPI
|
||||||
var time2 = (int) time;
|
var time2 = (int) time;
|
||||||
var launch = DateTime.UtcNow;
|
var launch = DateTime.UtcNow;
|
||||||
var startname = Name;
|
var startname = Name;
|
||||||
SendMessage("You are now being annoyed.", Color.Red);
|
SendInfoMessage("You are now being annoyed.");
|
||||||
while ((DateTime.UtcNow - launch).TotalSeconds < time2 && startname == Name)
|
while ((DateTime.UtcNow - launch).TotalSeconds < time2 && startname == Name)
|
||||||
{
|
{
|
||||||
SendData(PacketTypes.NpcSpecial, number: Index, number2: 2f);
|
SendData(PacketTypes.NpcSpecial, number: Index, number2: 2f);
|
||||||
|
|
@ -924,11 +922,6 @@ namespace TShockAPI
|
||||||
AwaitingResponse = new Dictionary<string, Action<object>>();
|
AwaitingResponse = new Dictionary<string, Action<object>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SendMessage(string msg)
|
|
||||||
{
|
|
||||||
SendMessage(msg, 0, 255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SendMessage(string msg, Color color)
|
public override void SendMessage(string msg, Color color)
|
||||||
{
|
{
|
||||||
SendMessage(msg, color.R, color.G, color.B);
|
SendMessage(msg, color.R, color.G, color.B);
|
||||||
|
|
@ -1003,11 +996,6 @@ namespace TShockAPI
|
||||||
Console.ResetColor();
|
Console.ResetColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SendMessage(string msg)
|
|
||||||
{
|
|
||||||
SendMessage(msg, 0, 255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SendMessage(string msg, Color color)
|
public override void SendMessage(string msg, Color color)
|
||||||
{
|
{
|
||||||
SendMessage(msg, color.R, color.G, color.B);
|
SendMessage(msg, color.R, color.G, color.B);
|
||||||
|
|
@ -1016,7 +1004,6 @@ namespace TShockAPI
|
||||||
public override void SendMessage(string msg, byte red, byte green, byte blue)
|
public override void SendMessage(string msg, byte red, byte green, byte blue)
|
||||||
{
|
{
|
||||||
Console.WriteLine(msg);
|
Console.WriteLine(msg);
|
||||||
//RconHandler.Response += msg + "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFullMoon()
|
public void SetFullMoon()
|
||||||
|
|
@ -1428,6 +1415,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].inventory[k].name, player.Index, (float)k, (float)Main.player[player.Index].inventory[k].prefix, 0f, 0);
|
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].inventory[k].name, player.Index, (float)k, (float)Main.player[player.Index].inventory[k].prefix, 0f, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[0].name, player.Index, 59f, (float)Main.player[player.Index].armor[0].prefix, 0f, 0);
|
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[0].name, player.Index, 59f, (float)Main.player[player.Index].armor[0].prefix, 0f, 0);
|
||||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[1].name, player.Index, 60f, (float)Main.player[player.Index].armor[1].prefix, 0f, 0);
|
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[1].name, player.Index, 60f, (float)Main.player[player.Index].armor[1].prefix, 0f, 0);
|
||||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[2].name, player.Index, 61f, (float)Main.player[player.Index].armor[2].prefix, 0f, 0);
|
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[2].name, player.Index, 61f, (float)Main.player[player.Index].armor[2].prefix, 0f, 0);
|
||||||
|
|
|
||||||
|
|
@ -36,24 +36,22 @@ using Terraria;
|
||||||
using TerrariaApi.Server;
|
using TerrariaApi.Server;
|
||||||
using TShockAPI.DB;
|
using TShockAPI.DB;
|
||||||
using TShockAPI.Net;
|
using TShockAPI.Net;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using TShockAPI.ServerSideCharacters;
|
using TShockAPI.ServerSideCharacters;
|
||||||
|
|
||||||
namespace TShockAPI
|
namespace TShockAPI
|
||||||
{
|
{
|
||||||
[ApiVersion(1, 16)]
|
[ApiVersion(1, 17)]
|
||||||
public class TShock : TerrariaPlugin
|
public class TShock : TerrariaPlugin
|
||||||
{
|
{
|
||||||
public static readonly Version VersionNum = Assembly.GetExecutingAssembly().GetName().Version;
|
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";
|
public static string SavePath = "tshock";
|
||||||
private const string LogFormatDefault = "yyyy-MM-dd_HH-mm-ss";
|
private const string LogFormatDefault = "yyyy-MM-dd_HH-mm-ss";
|
||||||
private static string LogFormat = LogFormatDefault;
|
private static string LogFormat = LogFormatDefault;
|
||||||
private const string LogPathDefault = "tshock";
|
private const string LogPathDefault = "tshock";
|
||||||
private static string LogPath = LogPathDefault;
|
private static string LogPath = LogPathDefault;
|
||||||
private static bool LogClear = false;
|
private static bool LogClear;
|
||||||
|
|
||||||
public static TSPlayer[] Players = new TSPlayer[Main.maxPlayers];
|
public static TSPlayer[] Players = new TSPlayer[Main.maxPlayers];
|
||||||
public static BanManager Bans;
|
public static BanManager Bans;
|
||||||
|
|
@ -76,7 +74,9 @@ namespace TShockAPI
|
||||||
public static SecureRest RestApi;
|
public static SecureRest RestApi;
|
||||||
public static RestManager RestManager;
|
public static RestManager RestManager;
|
||||||
public static Utils Utils = Utils.Instance;
|
public static Utils Utils = Utils.Instance;
|
||||||
|
public static StatTracker StatTracker = new StatTracker();
|
||||||
public static UpdateManager UpdateManager;
|
public static UpdateManager UpdateManager;
|
||||||
|
public static ILog Log;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used for implementing REST Tokens prior to the REST system starting up.
|
/// Used for implementing REST Tokens prior to the REST system starting up.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -107,10 +107,6 @@ namespace TShockAPI
|
||||||
get { return "The administration modification of the future."; }
|
get { return "The administration modification of the future."; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string UpdateURL
|
|
||||||
{
|
|
||||||
get { return ""; }
|
|
||||||
}
|
|
||||||
public TShock(Main game)
|
public TShock(Main game)
|
||||||
: base(game)
|
: base(game)
|
||||||
{
|
{
|
||||||
|
|
@ -126,13 +122,13 @@ namespace TShockAPI
|
||||||
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
|
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
|
string logFilename;
|
||||||
|
string logPathSetupWarning;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HandleCommandLine(Environment.GetCommandLineArgs());
|
HandleCommandLine(Environment.GetCommandLineArgs());
|
||||||
|
|
||||||
if (Version.Major >= 4)
|
|
||||||
getTShockAscii();
|
|
||||||
|
|
||||||
if (!Directory.Exists(SavePath))
|
if (!Directory.Exists(SavePath))
|
||||||
Directory.CreateDirectory(SavePath);
|
Directory.CreateDirectory(SavePath);
|
||||||
|
|
||||||
|
|
@ -142,37 +138,29 @@ namespace TShockAPI
|
||||||
Main.ServerSideCharacter = ServerSideCharacterConfig.Enabled;
|
Main.ServerSideCharacter = ServerSideCharacterConfig.Enabled;
|
||||||
|
|
||||||
DateTime now = DateTime.Now;
|
DateTime now = DateTime.Now;
|
||||||
string logFilename;
|
|
||||||
string logPathSetupWarning = null;
|
|
||||||
// Log path was not already set by the command line parameter?
|
// Log path was not already set by the command line parameter?
|
||||||
if (LogPath == LogPathDefault)
|
if (LogPath == LogPathDefault)
|
||||||
LogPath = Config.LogPath;
|
LogPath = Config.LogPath;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
logFilename = Path.Combine(LogPath, now.ToString(LogFormat)+".log");
|
logFilename = Path.Combine(LogPath, now.ToString(LogFormat) + ".log");
|
||||||
if (!Directory.Exists(LogPath))
|
if (!Directory.Exists(LogPath))
|
||||||
Directory.CreateDirectory(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 =
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
"Could not apply the given log path / log format, defaults will be used. Exception details:\n" + ex;
|
||||||
Console.WriteLine(logPathSetupWarning);
|
|
||||||
Console.ForegroundColor = ConsoleColor.Gray;
|
ServerApi.LogWriter.PluginWriteLine(this, logPathSetupWarning, TraceLevel.Error);
|
||||||
|
|
||||||
// Problem with the log path or format use the default
|
// Problem with the log path or format use the default
|
||||||
logFilename = Path.Combine(LogPathDefault, now.ToString(LogFormatDefault) + ".log");
|
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;
|
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Will be handled by the server api and written to its crashlog.txt.
|
// 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);
|
throw new Exception("Fatal TShock initialization exception. See inner exception for details.", ex);
|
||||||
|
|
@ -181,16 +169,6 @@ namespace TShockAPI
|
||||||
// Further exceptions are written to TShock's log from now on.
|
// Further exceptions are written to TShock's log from now on.
|
||||||
try
|
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")
|
if (Config.StorageType.ToLower() == "sqlite")
|
||||||
{
|
{
|
||||||
string sql = Path.Combine(SavePath, "tshock.sqlite");
|
string sql = Path.Combine(SavePath, "tshock.sqlite");
|
||||||
|
|
@ -213,7 +191,7 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
catch (MySqlException ex)
|
catch (MySqlException ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex.ToString());
|
ServerApi.LogWriter.PluginWriteLine(this, ex.ToString(), TraceLevel.Error);
|
||||||
throw new Exception("MySql not setup correctly");
|
throw new Exception("MySql not setup correctly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -222,6 +200,27 @@ namespace TShockAPI
|
||||||
throw new Exception("Invalid storage type");
|
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 = new BackupManager(Path.Combine(SavePath, "backups"));
|
||||||
Backups.KeepFor = Config.BackupKeepFor;
|
Backups.KeepFor = Config.BackupKeepFor;
|
||||||
Backups.Interval = Config.BackupInterval;
|
Backups.Interval = Config.BackupInterval;
|
||||||
|
|
@ -244,7 +243,7 @@ namespace TShockAPI
|
||||||
if (Config.EnableGeoIP && File.Exists(geoippath))
|
if (Config.EnableGeoIP && File.Exists(geoippath))
|
||||||
Geo = new GeoIPCountry(geoippath);
|
Geo = new GeoIPCountry(geoippath);
|
||||||
|
|
||||||
Log.ConsoleInfo(string.Format("|> Version {0} ({1}) now running.", Version, VersionCodename));
|
Log.ConsoleInfo("TShock {0} ({1}) now running.", Version, VersionCodename);
|
||||||
|
|
||||||
ServerApi.Hooks.GamePostInitialize.Register(this, OnPostInit);
|
ServerApi.Hooks.GamePostInitialize.Register(this, OnPostInit);
|
||||||
ServerApi.Hooks.GameUpdate.Register(this, OnUpdate);
|
ServerApi.Hooks.GameUpdate.Register(this, OnUpdate);
|
||||||
|
|
@ -265,12 +264,13 @@ namespace TShockAPI
|
||||||
ServerApi.Hooks.WorldChristmasCheck.Register(this, OnXmasCheck);
|
ServerApi.Hooks.WorldChristmasCheck.Register(this, OnXmasCheck);
|
||||||
ServerApi.Hooks.WorldHalloweenCheck.Register(this, OnHalloweenCheck);
|
ServerApi.Hooks.WorldHalloweenCheck.Register(this, OnHalloweenCheck);
|
||||||
ServerApi.Hooks.NetNameCollision.Register(this, NetHooks_NameCollision);
|
ServerApi.Hooks.NetNameCollision.Register(this, NetHooks_NameCollision);
|
||||||
TShockAPI.Hooks.PlayerHooks.PlayerPreLogin += OnPlayerPreLogin;
|
Hooks.PlayerHooks.PlayerPreLogin += OnPlayerPreLogin;
|
||||||
TShockAPI.Hooks.PlayerHooks.PlayerPostLogin += OnPlayerLogin;
|
Hooks.PlayerHooks.PlayerPostLogin += OnPlayerLogin;
|
||||||
|
Hooks.AccountHooks.AccountDelete += OnAccountDelete;
|
||||||
|
Hooks.AccountHooks.AccountCreate += OnAccountCreate;
|
||||||
|
|
||||||
GetDataHandlers.InitGetDataHandler();
|
GetDataHandlers.InitGetDataHandler();
|
||||||
Commands.InitCommands();
|
Commands.InitCommands();
|
||||||
//RconHandler.StartThread();
|
|
||||||
|
|
||||||
if (Config.RestApiEnabled)
|
if (Config.RestApiEnabled)
|
||||||
RestApi.Start();
|
RestApi.Start();
|
||||||
|
|
@ -283,6 +283,8 @@ namespace TShockAPI
|
||||||
|
|
||||||
if (Initialized != null)
|
if (Initialized != null)
|
||||||
Initialized();
|
Initialized();
|
||||||
|
|
||||||
|
Log.ConsoleInfo("Welcome to TShock for Terraria. Initialization complete.");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -292,25 +294,6 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void getTShockAscii()
|
|
||||||
{
|
|
||||||
// ReSharper disable LocalizableElement
|
|
||||||
Console.Write(" ___ ___ ___ ___ ___ \n" +
|
|
||||||
" ___ / /\\ /__/\\ / /\\ / /\\ /__/| \n" +
|
|
||||||
" / /\\ / /:/_ \\ \\:\\ / /::\\ / /:/ | |:| \n" +
|
|
||||||
" / /:/ / /:/ /\\ \\__\\:\\ / /:/\\:\\ / /:/ | |:| \n" +
|
|
||||||
" / /:/ / /:/ /::\\ ___ / /::\\ / /:/ \\:\\ / /:/ ___ __| |:| \n" +
|
|
||||||
" / /::\\ /__/:/ /:/\\:\\/__/\\ /:/\\:\\/__/:/ \\__\\:\\/__/:/ / /\\/__/\\_|:|____\n" +
|
|
||||||
"/__/:/\\:\\\\ \\:\\/:/~/:/\\ \\:\\/:/__\\/\\ \\:\\ / /:/\\ \\:\\ / /:/\\ \\:\\/:::::/\n" +
|
|
||||||
"\\__\\/ \\:\\\\ \\::/ /:/ \\ \\::/ \\ \\:\\ /:/ \\ \\:\\ /:/ \\ \\::/~~~~ \n" +
|
|
||||||
" \\ \\:\\\\__\\/ /:/ \\ \\:\\ \\ \\:\\/:/ \\ \\:\\/:/ \\ \\:\\ \n" +
|
|
||||||
" \\__\\/ /__/:/ \\ \\:\\ \\ \\::/ \\ \\::/ \\ \\:\\ \n" +
|
|
||||||
" \\__\\/ \\__\\/ \\__\\/ \\__\\/ \\__\\/ \n" +
|
|
||||||
"");
|
|
||||||
Console.WriteLine("TShock for Terraria is open & free software. If you paid, you were scammed.");
|
|
||||||
// ReSharper restore LocalizableElement
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
|
|
@ -379,6 +362,16 @@ namespace TShockAPI
|
||||||
Users.UpdateLogin(u);
|
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)
|
private void OnPlayerPreLogin(Hooks.PlayerPreLoginEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.Player.IsLoggedIn)
|
if (args.Player.IsLoggedIn)
|
||||||
|
|
@ -572,14 +565,14 @@ namespace TShockAPI
|
||||||
|
|
||||||
private void OnPostInit(EventArgs args)
|
private void OnPostInit(EventArgs args)
|
||||||
{
|
{
|
||||||
SetConsoleTitle();
|
SetConsoleTitle(false);
|
||||||
if (!File.Exists(Path.Combine(SavePath, "auth.lck")) && !File.Exists(Path.Combine(SavePath, "authcode.txt")))
|
if (!File.Exists(Path.Combine(SavePath, "auth.lck")) && !File.Exists(Path.Combine(SavePath, "authcode.txt")))
|
||||||
{
|
{
|
||||||
var r = new Random((int) DateTime.Now.ToBinary());
|
var r = new Random((int) DateTime.Now.ToBinary());
|
||||||
AuthToken = r.Next(100000, 10000000);
|
AuthToken = r.Next(100000, 10000000);
|
||||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
Console.WriteLine("TShock Notice: To become SuperAdmin, join the game and type /auth " + AuthToken);
|
Console.WriteLine("TShock Notice: To become SuperAdmin, join the game and type {0}auth {1}", Commands.Specifier, AuthToken);
|
||||||
Console.WriteLine("This token will display until disabled by verification. (/auth-verify)");
|
Console.WriteLine("This token will display until disabled by verification. ({0}auth-verify)", Commands.Specifier);
|
||||||
Console.ForegroundColor = ConsoleColor.Gray;
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
FileTools.CreateFile(Path.Combine(SavePath, "authcode.txt"));
|
FileTools.CreateFile(Path.Combine(SavePath, "authcode.txt"));
|
||||||
using (var tw = new StreamWriter(Path.Combine(SavePath, "authcode.txt")))
|
using (var tw = new StreamWriter(Path.Combine(SavePath, "authcode.txt")))
|
||||||
|
|
@ -596,8 +589,8 @@ namespace TShockAPI
|
||||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
"TShock Notice: authcode.txt is still present, and the AuthToken located in that file will be used.");
|
"TShock Notice: authcode.txt is still present, and the AuthToken located in that file will be used.");
|
||||||
Console.WriteLine("To become superadmin, join the game and type /auth " + AuthToken);
|
Console.WriteLine("To become superadmin, join the game and type {0}auth {1}", Commands.Specifier, AuthToken);
|
||||||
Console.WriteLine("This token will display until disabled by verification. (/auth-verify)");
|
Console.WriteLine("This token will display until disabled by verification. ({0}auth-verify)", Commands.Specifier);
|
||||||
Console.ForegroundColor = ConsoleColor.Gray;
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -613,6 +606,7 @@ namespace TShockAPI
|
||||||
FixChestStacks();
|
FixChestStacks();
|
||||||
|
|
||||||
UpdateManager = new UpdateManager();
|
UpdateManager = new UpdateManager();
|
||||||
|
StatTracker.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ComputeMaxStyles()
|
private void ComputeMaxStyles()
|
||||||
|
|
@ -811,7 +805,7 @@ namespace TShockAPI
|
||||||
player.SetBuff(36, 120); //Broken Armor
|
player.SetBuff(36, 120); //Broken Armor
|
||||||
check = "Remove armor/accessory " + item.name;
|
check = "Remove armor/accessory " + item.name;
|
||||||
|
|
||||||
player.SendErrorMessage(string.Format("You are wearing banned equipment. {0}", check));
|
player.SendErrorMessage("You are wearing banned equipment. {0}", check);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -824,16 +818,32 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
player.SetBuff(23, 120); //Cursed
|
player.SetBuff(23, 120); //Cursed
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
var oldRegion = player.CurrentRegion;
|
||||||
SetConsoleTitle();
|
player.CurrentRegion = Regions.GetTopRegion(Regions.InAreaRegion(player.TileX, player.TileY));
|
||||||
|
|
||||||
|
if (oldRegion != player.CurrentRegion)
|
||||||
|
{
|
||||||
|
if (oldRegion != null)
|
||||||
|
{
|
||||||
|
Hooks.RegionHooks.OnRegionLeft(player, oldRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetConsoleTitle()
|
if (player.CurrentRegion != null)
|
||||||
{
|
{
|
||||||
Console.Title = string.Format("{0}{1}/{2} @ {3}:{4} (TerrariaShock v{5})",
|
Hooks.RegionHooks.OnRegionEntered(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetConsoleTitle(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetConsoleTitle(bool empty)
|
||||||
|
{
|
||||||
|
Console.Title = string.Format("{0}{1}/{2} @ {3}:{4} (TShock for Terraria v{5})",
|
||||||
!string.IsNullOrWhiteSpace(Config.ServerName) ? Config.ServerName + " - " : "",
|
!string.IsNullOrWhiteSpace(Config.ServerName) ? Config.ServerName + " - " : "",
|
||||||
Utils.ActivePlayers(),
|
empty ? 0 : Utils.ActivePlayers(),
|
||||||
Config.MaxSlots, Netplay.serverListenIP, Netplay.serverPort, Version);
|
Config.MaxSlots, Netplay.serverListenIP, Netplay.serverPort, Version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -997,7 +1007,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (!tsplr.SilentKickInProgress && tsplr.State >= 3)
|
if (!tsplr.SilentKickInProgress && tsplr.State >= 3)
|
||||||
Utils.Broadcast(tsplr.Name + " has left.", Color.Yellow);
|
Utils.Broadcast(tsplr.Name + " has left.", Color.Yellow);
|
||||||
Log.Info(string.Format("{0} disconnected.", tsplr.Name));
|
Log.Info("{0} disconnected.", tsplr.Name);
|
||||||
|
|
||||||
if (tsplr.IsLoggedIn && !tsplr.IgnoreActionsForClearingTrashCan && Main.ServerSideCharacter && (!tsplr.Dead || tsplr.TPlayer.difficulty != 2))
|
if (tsplr.IsLoggedIn && !tsplr.IgnoreActionsForClearingTrashCan && Main.ServerSideCharacter && (!tsplr.Dead || tsplr.TPlayer.difficulty != 2))
|
||||||
{
|
{
|
||||||
|
|
@ -1010,6 +1020,14 @@ namespace TShockAPI
|
||||||
RememberedPos.InsertLeavePos(tsplr.Name, tsplr.IP, (int) (tsplr.X/16), (int) (tsplr.Y/16));
|
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)
|
||||||
|
{
|
||||||
|
if (Config.SaveWorldOnLastPlayerExit)
|
||||||
|
SaveManager.Instance.SaveWorld();
|
||||||
|
SetConsoleTitle(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnChat(ServerChatEventArgs args)
|
private void OnChat(ServerChatEventArgs args)
|
||||||
|
|
@ -1037,7 +1055,8 @@ namespace TShockAPI
|
||||||
return;
|
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
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -1045,7 +1064,7 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.ConsoleError("Command exception");
|
Log.ConsoleError("An exeption occurred executing a command.");
|
||||||
Log.Error(ex.ToString());
|
Log.Error(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1087,7 +1106,7 @@ namespace TShockAPI
|
||||||
tsplr.SendMessage(msg, tsplr.Group.R, tsplr.Group.G, tsplr.Group.B);
|
tsplr.SendMessage(msg, tsplr.Group.R, tsplr.Group.G, tsplr.Group.B);
|
||||||
|
|
||||||
TSPlayer.Server.SendMessage(msg, tsplr.Group.R, tsplr.Group.G, tsplr.Group.B);
|
TSPlayer.Server.SendMessage(msg, tsplr.Group.R, tsplr.Group.G, tsplr.Group.B);
|
||||||
Log.Info(string.Format("Broadcast: {0}", msg));
|
Log.Info("Broadcast: {0}", msg);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1113,7 +1132,7 @@ namespace TShockAPI
|
||||||
WorldGen.genRand = new Random();
|
WorldGen.genRand = new Random();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.Command.StartsWith("playing") || args.Command.StartsWith("/playing"))
|
if (args.Command.StartsWith("playing") || args.Command.StartsWith("{0}playing".SFormat(Commands.Specifier)))
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
foreach (TSPlayer player in Players)
|
foreach (TSPlayer player in Players)
|
||||||
|
|
@ -1121,18 +1140,18 @@ namespace TShockAPI
|
||||||
if (player != null && player.Active)
|
if (player != null && player.Active)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
TSPlayer.Server.SendInfoMessage(string.Format("{0} ({1}) [{2}] <{3}>", player.Name, player.IP,
|
TSPlayer.Server.SendInfoMessage("{0} ({1}) [{2}] <{3}>", player.Name, player.IP,
|
||||||
player.Group.Name, player.UserAccountName));
|
player.Group.Name, player.UserAccountName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TSPlayer.Server.SendInfoMessage(string.Format("{0} players connected.", count));
|
TSPlayer.Server.SendInfoMessage("{0} players connected.", count);
|
||||||
}
|
}
|
||||||
else if (args.Command == "autosave")
|
else if (args.Command == "autosave")
|
||||||
{
|
{
|
||||||
Main.autoSave = Config.AutoSave = !Config.AutoSave;
|
Main.autoSave = Config.AutoSave = !Config.AutoSave;
|
||||||
Log.ConsoleInfo("AutoSave " + (Config.AutoSave ? "Enabled" : "Disabled"));
|
Log.ConsoleInfo("AutoSave " + (Config.AutoSave ? "Enabled" : "Disabled"));
|
||||||
}
|
}
|
||||||
else if (args.Command.StartsWith("/"))
|
else if (args.Command.StartsWith(Commands.Specifier))
|
||||||
{
|
{
|
||||||
Commands.HandleCommand(TSPlayer.Server, args.Command);
|
Commands.HandleCommand(TSPlayer.Server, args.Command);
|
||||||
}
|
}
|
||||||
|
|
@ -1190,24 +1209,24 @@ namespace TShockAPI
|
||||||
|
|
||||||
player.LoginMS = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
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,
|
Log.Info("{0} ({1}) from '{2}' group from '{3}' joined. ({4}/{5})", player.Name, player.IP,
|
||||||
player.Group.Name, player.Country, TShock.Utils.ActivePlayers(),
|
player.Group.Name, player.Country, TShock.Utils.ActivePlayers(),
|
||||||
TShock.Config.MaxSlots));
|
TShock.Config.MaxSlots);
|
||||||
if (!player.SilentJoinInProgress)
|
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
|
else
|
||||||
{
|
{
|
||||||
Log.Info(string.Format("{0} ({1}) from '{2}' group joined. ({3}/{4})", player.Name, player.IP,
|
Log.Info("{0} ({1}) from '{2}' group joined. ({3}/{4})", player.Name, player.IP,
|
||||||
player.Group.Name, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots));
|
player.Group.Name, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots);
|
||||||
if (!player.SilentJoinInProgress)
|
if (!player.SilentJoinInProgress)
|
||||||
TShock.Utils.Broadcast(player.Name + " has joined.", Color.Yellow);
|
Utils.Broadcast(player.Name + " has joined.", Color.Yellow);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TShock.Config.DisplayIPToAdmins)
|
if (Config.DisplayIPToAdmins)
|
||||||
TShock.Utils.SendLogs(string.Format("{0} has joined. IP: {1}", player.Name, player.IP), Color.Blue);
|
Utils.SendLogs(string.Format("{0} has joined. IP: {1}", player.Name, player.IP), Color.Blue);
|
||||||
|
|
||||||
Utils.ShowFileToUser(player, "motd.txt");
|
Utils.ShowFileToUser(player, "motd.txt");
|
||||||
|
|
||||||
|
|
@ -1223,14 +1242,13 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (Main.ServerSideCharacter)
|
if (Main.ServerSideCharacter)
|
||||||
{
|
{
|
||||||
player.SendMessage(
|
player.SendErrorMessage(
|
||||||
player.IgnoreActionsForInventory = "Server side characters is enabled! Please /register or /login to play!",
|
player.IgnoreActionsForInventory = "Server side characters is enabled! Please {0}register or {0}login to play!", Commands.Specifier);
|
||||||
Color.Red);
|
|
||||||
player.LoginHarassed = true;
|
player.LoginHarassed = true;
|
||||||
}
|
}
|
||||||
else if (Config.RequireLogin)
|
else if (Config.RequireLogin)
|
||||||
{
|
{
|
||||||
player.SendMessage("Please /register or /login to play!", Color.Red);
|
player.SendErrorMessage("Please {0}register or {0}login to play!", Commands.Specifier);
|
||||||
player.LoginHarassed = true;
|
player.LoginHarassed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1240,7 +1258,7 @@ namespace TShockAPI
|
||||||
if (Config.RememberLeavePos && (RememberedPos.GetLeavePos(player.Name, player.IP) != Vector2.Zero) && !player.LoginHarassed)
|
if (Config.RememberLeavePos && (RememberedPos.GetLeavePos(player.Name, player.IP) != Vector2.Zero) && !player.LoginHarassed)
|
||||||
{
|
{
|
||||||
player.RPPending = 3;
|
player.RPPending = 3;
|
||||||
player.SendMessage("You will be teleported to your last known location...", Color.Red);
|
player.SendInfoMessage("You will be teleported to your last known location...");
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
|
|
@ -1552,7 +1570,7 @@ namespace TShockAPI
|
||||||
|
|
||||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000)
|
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000)
|
||||||
{
|
{
|
||||||
player.SendMessage("You do not have permission to build!", Color.Red);
|
player.SendErrorMessage("You do not have permission to build!");
|
||||||
player.BPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
player.BPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1566,7 +1584,7 @@ namespace TShockAPI
|
||||||
|
|
||||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000)
|
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000)
|
||||||
{
|
{
|
||||||
player.SendMessage("You do not have permission to build!", Color.Red);
|
player.SendErrorMessage("You do not have permission to build!");
|
||||||
player.BPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
player.BPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1577,7 +1595,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000)
|
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000)
|
||||||
{
|
{
|
||||||
player.SendMessage("This region is protected from changes.", Color.Red);
|
player.SendErrorMessage("This region is protected from changes.");
|
||||||
player.RPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
player.RPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1589,7 +1607,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.WPm) > 2000)
|
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.WPm) > 2000)
|
||||||
{
|
{
|
||||||
player.SendMessage("The world is protected from changes.", Color.Red);
|
player.SendErrorMessage("The world is protected from changes.");
|
||||||
player.WPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
player.WPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1604,7 +1622,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.SPm) > 2000)
|
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.SPm) > 2000)
|
||||||
{
|
{
|
||||||
player.SendMessage("Spawn is protected from changes.", Color.Red);
|
player.SendErrorMessage("Spawn is protected from changes.");
|
||||||
player.SPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
player.SPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1621,7 +1639,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000)
|
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000)
|
||||||
{
|
{
|
||||||
player.SendMessage("You do not have permission to build!", Color.Red);
|
player.SendErrorMessage("You do not have permission to build!");
|
||||||
player.BPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
player.BPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1632,7 +1650,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000)
|
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000)
|
||||||
{
|
{
|
||||||
player.SendMessage("This region is protected from changes.", Color.Red);
|
player.SendErrorMessage("This region is protected from changes.");
|
||||||
player.RPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
player.RPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1644,7 +1662,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.WPm) > 2000)
|
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.WPm) > 2000)
|
||||||
{
|
{
|
||||||
player.SendMessage("The world is protected from changes.", Color.Red);
|
player.SendErrorMessage("The world is protected from changes.");
|
||||||
player.WPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
player.WPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1659,7 +1677,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.SPm) > 1000)
|
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.SPm) > 1000)
|
||||||
{
|
{
|
||||||
player.SendMessage("Spawn is protected from changes.", Color.Red);
|
player.SendErrorMessage("Spawn is protected from changes.");
|
||||||
player.SPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
player.SPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1778,9 +1796,6 @@ namespace TShockAPI
|
||||||
Netplay.password = "";
|
Netplay.password = "";
|
||||||
Netplay.spamCheck = false;
|
Netplay.spamCheck = false;
|
||||||
|
|
||||||
RconHandler.Password = file.RconPassword;
|
|
||||||
RconHandler.ListenPort = file.RconPort;
|
|
||||||
|
|
||||||
Utils.HashAlgo = file.HashAlgorithm;
|
Utils.HashAlgo = file.HashAlgorithm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<DocumentationFile>bin\Debug\TShockAPI.XML</DocumentationFile>
|
<DocumentationFile>bin\Debug\TShockAPI.XML</DocumentationFile>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<NoWarn>1591</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
|
|
@ -78,6 +79,11 @@
|
||||||
<Compile Include="Hooks\AccountHooks.cs" />
|
<Compile Include="Hooks\AccountHooks.cs" />
|
||||||
<Compile Include="Hooks\GeneralHooks.cs" />
|
<Compile Include="Hooks\GeneralHooks.cs" />
|
||||||
<Compile Include="Hooks\PlayerHooks.cs" />
|
<Compile Include="Hooks\PlayerHooks.cs" />
|
||||||
|
<Compile Include="Hooks\RegionHooks.cs" />
|
||||||
|
<Compile Include="ILog.cs" />
|
||||||
|
<Compile Include="Log.cs" />
|
||||||
|
<Compile Include="SqlLog.cs" />
|
||||||
|
<Compile Include="TextLog.cs" />
|
||||||
<Compile Include="PaginationTools.cs" />
|
<Compile Include="PaginationTools.cs" />
|
||||||
<Compile Include="Rest\RestPermissions.cs" />
|
<Compile Include="Rest\RestPermissions.cs" />
|
||||||
<Compile Include="SaveManager.cs" />
|
<Compile Include="SaveManager.cs" />
|
||||||
|
|
@ -102,7 +108,6 @@
|
||||||
<Compile Include="GetDataHandlers.cs" />
|
<Compile Include="GetDataHandlers.cs" />
|
||||||
<Compile Include="Group.cs" />
|
<Compile Include="Group.cs" />
|
||||||
<Compile Include="Extensions\LinqExt.cs" />
|
<Compile Include="Extensions\LinqExt.cs" />
|
||||||
<Compile Include="Log.cs" />
|
|
||||||
<Compile Include="Net\BaseMsg.cs" />
|
<Compile Include="Net\BaseMsg.cs" />
|
||||||
<Compile Include="Net\DisconnectMsg.cs" />
|
<Compile Include="Net\DisconnectMsg.cs" />
|
||||||
<Compile Include="Net\NetTile.cs" />
|
<Compile Include="Net\NetTile.cs" />
|
||||||
|
|
@ -111,7 +116,6 @@
|
||||||
<Compile Include="Net\WorldInfoMsg.cs" />
|
<Compile Include="Net\WorldInfoMsg.cs" />
|
||||||
<Compile Include="PacketBufferer.cs" />
|
<Compile Include="PacketBufferer.cs" />
|
||||||
<Compile Include="Permissions.cs" />
|
<Compile Include="Permissions.cs" />
|
||||||
<Compile Include="RconHandler.cs" />
|
|
||||||
<Compile Include="DB\RememberedPosManager.cs" />
|
<Compile Include="DB\RememberedPosManager.cs" />
|
||||||
<Compile Include="Resources.Designer.cs">
|
<Compile Include="Resources.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
|
@ -182,7 +186,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<VisualStudio>
|
<VisualStudio>
|
||||||
<UserProperties BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" BuildVersion_BuildAction="Both" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_StartDate="2011/6/17" BuildVersion_IncrementBeforeBuild="False" />
|
<UserProperties BuildVersion_IncrementBeforeBuild="False" BuildVersion_StartDate="2011/6/17" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_BuildAction="Both" BuildVersion_UpdateFileVersion="True" BuildVersion_UpdateAssemblyVersion="True" />
|
||||||
</VisualStudio>
|
</VisualStudio>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
|
|
||||||
250
TShockAPI/TextLog.cs
Normal file
250
TShockAPI/TextLog.cs
Normal file
|
|
@ -0,0 +1,250 @@
|
||||||
|
/*
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace TShockAPI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class inheriting ILog for writing logs to a text file
|
||||||
|
/// </summary>
|
||||||
|
public class TextLog : ILog, IDisposable
|
||||||
|
{
|
||||||
|
private readonly StreamWriter _logWriter;
|
||||||
|
private readonly LogLevel _logLevel;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log file name
|
||||||
|
/// </summary>
|
||||||
|
public static string fileName { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the TextLog
|
||||||
|
/// </summary>
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "Text Log Writer"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Sql
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the log file stream and sets the initial log level.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename">The output filename. This file will be overwritten if 'clear' is set.</param>
|
||||||
|
/// <param name="logLevel">The <see cref="LogLevel" /> value which sets the type of messages to output.</param>
|
||||||
|
/// <param name="clear">Whether or not to clear the log file on initialization.</param>
|
||||||
|
public TextLog(string filename, LogLevel logLevel, bool clear)
|
||||||
|
{
|
||||||
|
fileName = filename;
|
||||||
|
_logLevel = logLevel;
|
||||||
|
_logWriter = new StreamWriter(filename, !clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MayWriteType(LogLevel type)
|
||||||
|
{
|
||||||
|
return ((_logLevel & type) == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes data to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void Data(String message)
|
||||||
|
{
|
||||||
|
Write(message, LogLevel.Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes data to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void Data(string format, params object[] args)
|
||||||
|
{
|
||||||
|
Data(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void Error(String message)
|
||||||
|
{
|
||||||
|
Write(message, LogLevel.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void Error(string format, params object[] args)
|
||||||
|
{
|
||||||
|
Error(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void ConsoleError(String message)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.WriteLine(message);
|
||||||
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
|
Write(message, LogLevel.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an error to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void ConsoleError(string format, params object[] args)
|
||||||
|
{
|
||||||
|
ConsoleError(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a warning to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void Warn(String message)
|
||||||
|
{
|
||||||
|
Write(message, LogLevel.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a warning to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void Warn(string format, params object[] args)
|
||||||
|
{
|
||||||
|
Warn(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void Info(String message)
|
||||||
|
{
|
||||||
|
Write(message, LogLevel.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void Info(string format, params object[] args)
|
||||||
|
{
|
||||||
|
Info(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log file. Also outputs to the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void ConsoleInfo(String message)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.WriteLine(message);
|
||||||
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
|
Write(message, LogLevel.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an informative string to the log file. Also outputs to the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void ConsoleInfo(string format, params object[] args)
|
||||||
|
{
|
||||||
|
ConsoleInfo(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a debug string to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to be written.</param>
|
||||||
|
public void Debug(String message)
|
||||||
|
{
|
||||||
|
Write(message, LogLevel.Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a debug string to the log file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format of the message to be written.</param>
|
||||||
|
/// <param name="args">The format arguments.</param>
|
||||||
|
public void Debug(string format, params object[] args)
|
||||||
|
{
|
||||||
|
Debug(String.Format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a message to the log
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <param name="level"></param>
|
||||||
|
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
|
||||||
|
{
|
||||||
|
_logWriter.WriteLine("{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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_logWriter.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -94,7 +94,7 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.ConsoleError("UpdateManager Exception: {0}", e);
|
TShock.Log.ConsoleError("UpdateManager Exception: {0}", e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -182,21 +182,11 @@ namespace TShockAPI
|
||||||
SaveManager.Instance.SaveWorld();
|
SaveManager.Instance.SaveWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Broadcasts a message to all players
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="msg">string message</param>
|
|
||||||
[Obsolete("Use TSPlayer.All and send a message via that method rather than using Broadcast.")]
|
|
||||||
public void Broadcast(string msg)
|
|
||||||
{
|
|
||||||
Broadcast(msg, Color.Green);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Broadcast(string msg, byte red, byte green, byte blue)
|
public void Broadcast(string msg, byte red, byte green, byte blue)
|
||||||
{
|
{
|
||||||
TSPlayer.All.SendMessage(msg, red, green, blue);
|
TSPlayer.All.SendMessage(msg, red, green, blue);
|
||||||
TSPlayer.Server.SendMessage(msg, red, green, blue);
|
TSPlayer.Server.SendMessage(msg, red, green, blue);
|
||||||
Log.Info(string.Format("Broadcast: {0}", msg));
|
TShock.Log.Info(string.Format("Broadcast: {0}", msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Broadcast(string msg, Color color)
|
public void Broadcast(string msg, Color color)
|
||||||
|
|
@ -216,7 +206,7 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
TSPlayer.All.SendMessageFromPlayer(msg, red, green, blue, ply);
|
TSPlayer.All.SendMessageFromPlayer(msg, red, green, blue, ply);
|
||||||
TSPlayer.Server.SendMessage(Main.player[ply].name + ": " + msg, red, green, blue);
|
TSPlayer.Server.SendMessage(Main.player[ply].name + ": " + msg, red, green, blue);
|
||||||
Log.Info(string.Format("Broadcast: {0}", Main.player[ply].name + ": " + msg));
|
TShock.Log.Info(string.Format("Broadcast: {0}", Main.player[ply].name + ": " + msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -227,7 +217,7 @@ namespace TShockAPI
|
||||||
/// <param name="excludedPlayer">The player to not send the message to.</param>
|
/// <param name="excludedPlayer">The player to not send the message to.</param>
|
||||||
public void SendLogs(string log, Color color, TSPlayer excludedPlayer = null)
|
public void SendLogs(string log, Color color, TSPlayer excludedPlayer = null)
|
||||||
{
|
{
|
||||||
Log.Info(log);
|
TShock.Log.Info(log);
|
||||||
TSPlayer.Server.SendMessage(log, color);
|
TSPlayer.Server.SendMessage(log, color);
|
||||||
foreach (TSPlayer player in TShock.Players)
|
foreach (TSPlayer player in TShock.Players)
|
||||||
{
|
{
|
||||||
|
|
@ -593,13 +583,6 @@ namespace TShockAPI
|
||||||
Hooks.GeneralHooks.OnReloadEvent(player);
|
Hooks.GeneralHooks.OnReloadEvent(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if COMPAT_SIGS
|
|
||||||
[Obsolete("This method is for signature compatibility for external code only")]
|
|
||||||
public void ForceKick(TSPlayer player, string reason)
|
|
||||||
{
|
|
||||||
Kick(player, reason, true, false, string.Empty);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Kicks a player from the server without checking for immunetokick permission.
|
/// Kicks a player from the server without checking for immunetokick permission.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -611,13 +594,6 @@ namespace TShockAPI
|
||||||
Kick(player, reason, true, silent, null, saveSSI);
|
Kick(player, reason, true, silent, null, saveSSI);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if COMPAT_SIGS
|
|
||||||
[Obsolete("This method is for signature compatibility for external code only")]
|
|
||||||
public bool Kick(TSPlayer player, string reason, string adminUserName)
|
|
||||||
{
|
|
||||||
return Kick(player, reason, false, false, adminUserName);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Kicks a player from the server..
|
/// Kicks a player from the server..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -638,7 +614,7 @@ namespace TShockAPI
|
||||||
if (player.IsLoggedIn && saveSSI)
|
if (player.IsLoggedIn && saveSSI)
|
||||||
player.SaveServerCharacter();
|
player.SaveServerCharacter();
|
||||||
player.Disconnect(string.Format("Kicked: {0}", reason));
|
player.Disconnect(string.Format("Kicked: {0}", reason));
|
||||||
Log.ConsoleInfo(string.Format("Kicked {0} for : '{1}'", playerName, reason));
|
TShock.Log.ConsoleInfo(string.Format("Kicked {0} for : '{1}'", playerName, reason));
|
||||||
string verb = force ? "force " : "";
|
string verb = force ? "force " : "";
|
||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
|
|
@ -652,13 +628,6 @@ namespace TShockAPI
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if COMPAT_SIGS
|
|
||||||
[Obsolete("This method is for signature compatibility for external code only")]
|
|
||||||
public bool Ban(TSPlayer player, string reason, string adminUserName)
|
|
||||||
{
|
|
||||||
return Ban(player, reason, false, adminUserName);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Bans and kicks a player from the server.
|
/// Bans and kicks a player from the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 50a04c45bfc2d1de2de1a31b215f7bdc546cfdd5
|
Subproject commit f4075507475be946870a83d65a14cb5ae2c348cf
|
||||||
|
|
@ -2,31 +2,48 @@ import requests
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
create_release_url = 'https://api.github.com/repos/NyxStudios/TShock/releases'
|
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"]
|
branch = os.environ["GIT_BRANCH"]
|
||||||
tag_name = os.environ["bamboo_tag_name"]
|
tag_name = os.environ["bamboo_tag_name"]
|
||||||
name = os.environ["bamboo_release_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 :'(
|
#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:
|
with open('/home/bamboo/scripts/token.py') as f:
|
||||||
token = f.read().rsplit('=', 1)[1].strip()
|
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}
|
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}
|
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)
|
json_data = json.dumps(data)
|
||||||
|
|
||||||
|
#make the post request, creating a release
|
||||||
r = requests.post(create_release_url, data=json_data, headers=create_headers)
|
r = requests.post(create_release_url, data=json_data, headers=create_headers)
|
||||||
|
#parse the response into an object
|
||||||
json_response = json.loads(r.text)
|
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']
|
release_id = json_response['id']
|
||||||
upload_url = json_response['upload_url'].rsplit('{')[0]
|
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
|
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_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)
|
r = requests.post(upload_url, data=open(release_name, 'rb'), headers = upload_headers, verify=False)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue