Merge branch 'general-devel'
This commit is contained in:
commit
0622350653
41 changed files with 2138 additions and 1735 deletions
10
.travis.yml
10
.travis.yml
|
|
@ -1,9 +1,5 @@
|
|||
language: c
|
||||
install:
|
||||
- sudo apt-get install mono-devel mono-gmcs nunit-console
|
||||
script:
|
||||
- xbuild ./TShockAPI/TShockAPI.csproj
|
||||
language: csharp
|
||||
solution: ./TShockAPI/TShockAPI.csproj
|
||||
notifications:
|
||||
irc: irc.rizon.net#tshock
|
||||
hipchat:
|
||||
secure: hpRLWiHF2j6O2qJOVs++aqAmryN6G5kY0SF26/rKCpQ7klhMlDZIgI1V1dbkKqlculFtW1neS0EBJyV9lmcV5b26H+KhlZYGN0j7q1VcOTM3rvtU6wW0Ap22uRLl2RrnA4kEsgDAsNouPOkyLZ19hlHAISlsId6G4+Rfqg6k+zQ=
|
||||
secure: hpRLWiHF2j6O2qJOVs++aqAmryN6G5kY0SF26/rKCpQ7klhMlDZIgI1V1dbkKqlculFtW1neS0EBJyV9lmcV5b26H+KhlZYGN0j7q1VcOTM3rvtU6wW0Ap22uRLl2RrnA4kEsgDAsNouPOkyLZ19hlHAISlsId6G4+Rfqg6k+zQ=
|
||||
|
|
|
|||
|
|
@ -1,36 +1,40 @@
|
|||
### Issue Guidelines
|
||||
Please follow these simple requirements before posting an issue:
|
||||
|
||||
1. TShock version number
|
||||
2. Any stack traces that may have happened when the issue occurred
|
||||
3. How to reproduce the issue
|
||||
- TShock version number
|
||||
- Any stack traces that may have happened when the issue occurred
|
||||
- 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
|
||||
|
||||
These guidelines are for contributors. If you do not follow these guidelines your commits will be reverted.
|
||||
These guidelines are for all contributors.
|
||||
|
||||
Required:
|
||||
- Follow the code style. We generally use microsofts except for m_ infront of private variables.
|
||||
- Do not push unfinished features to the master branch, instead create a remote branch and push to that.
|
||||
- Do not push untested code to the master branch, instead push to the test branch.
|
||||
- Document all compatibility issues in the COMPATIBILITY file. (IE file formats changing)
|
||||
- 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/).
|
||||
|
||||
----
|
||||
- Push code to the general-devel branch. Do not push it anywhere else.
|
||||
- Use tabs, not spaces.
|
||||
- Use UpperCamelCase for public function names.
|
||||
- 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.
|
||||
|
||||
### Dev Team Guidelines
|
||||
|
||||
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:
|
||||
- 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.
|
||||
- __Document code prior to marking it done in JIRA__
|
||||
- Move any un-tested code to the "Needs Validation" section on JIRA prior to marking it as done.
|
||||
- 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__.
|
||||
- Submit all pull requests to the general-devel branch prior to the master branch, or you will be ignored.
|
||||
- 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.
|
||||
- __Do not force push the repo__, or you will be removed.
|
||||
- __Do not revert commits__, unless you have sign-off from one other developer (the two-man rule), or you will be removed.
|
||||
- __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 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?
|
||||
|
||||
* [Website & Forums](http://tshock.co/xf/)
|
||||
* [Website & Forums](https://tshock.co/xf/)
|
||||
* [Wiki](https://tshock.atlassian.net/wiki/display/TSHOCKPLUGINS/Home)
|
||||
* [IRC: #tshock @ irc.rizon.net](http://tshock.co/xf/index.php?ezirc/)
|
||||
|
||||
## Download
|
||||
|
||||
* [Github Releases](https://github.com/TShock/TShock/releases)
|
||||
* [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))
|
||||
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...");
|
||||
|
||||
SaveManager.Instance.SaveWorld();
|
||||
Console.WriteLine("World backed up.");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Log.Info(string.Format("World backed up ({0}).", Main.worldPathName));
|
||||
TShock.Log.Info(string.Format("World backed up ({0}).", Main.worldPathName));
|
||||
|
||||
Main.worldPathName = worldname;
|
||||
}
|
||||
|
|
@ -76,8 +76,8 @@ namespace TShockAPI
|
|||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("Backup failed!");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Log.Error("Backup failed!");
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error("Backup failed!");
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
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.")]
|
||||
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.")]
|
||||
public string ServerName = "";
|
||||
[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.")]
|
||||
public string LogPath = "tshock";
|
||||
|
||||
[Description("Save logs to an SQL database instead of a text file. Default = false")]
|
||||
public bool UseSqlLogs = false;
|
||||
|
||||
[Description("Number of times the SQL log must fail to insert logs before falling back to the text log")]
|
||||
public int RevertToTextLogsOnSqlFailures = 10;
|
||||
|
||||
[Description("Prevents players from placing tiles with an invalid style.")]
|
||||
public bool PreventInvalidPlaceStyle = true;
|
||||
|
||||
|
|
@ -367,8 +368,11 @@ namespace TShockAPI
|
|||
[Description("Allows anyone to break grass, pots, etc.")]
|
||||
public bool AllowCutTilesAndBreakables = false;
|
||||
|
||||
[Description("Specifies which string starts a command")]
|
||||
[Description("Specifies which string starts a command.")]
|
||||
public string CommandSpecifier = "/";
|
||||
|
||||
[Description("Specifies which string starts a command silently.")]
|
||||
public string CommandSilentSpecifier = ".";
|
||||
|
||||
[Description("Kicks a hardcore player on death.")]
|
||||
public bool KickOnHardcoreDeath;
|
||||
|
|
@ -391,6 +395,9 @@ namespace TShockAPI
|
|||
[Description("The maximum allowable MP, before equipment buffs.")]
|
||||
public int MaxMP = 200;
|
||||
|
||||
[Description("Determines if the server should save the world if the last player exits.")]
|
||||
public bool SaveWorldOnLastPlayerExit = true;
|
||||
|
||||
/// <summary>
|
||||
/// Reads a configuration file from a given path
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -96,7 +96,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
Console.WriteLine(ex.StackTrace);
|
||||
}
|
||||
return null;
|
||||
|
|
@ -123,7 +123,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -145,18 +145,11 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
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 = "")
|
||||
{
|
||||
try
|
||||
|
|
@ -167,18 +160,11 @@ namespace TShockAPI.DB
|
|||
{
|
||||
if (exceptions)
|
||||
throw ex;
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
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)
|
||||
{
|
||||
try
|
||||
|
|
@ -193,7 +179,7 @@ namespace TShockAPI.DB
|
|||
{
|
||||
if (exceptions)
|
||||
throw ex;
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -206,7 +192,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
|
||||
return playerData;
|
||||
|
|
@ -104,7 +104,7 @@ namespace TShockAPI.DB
|
|||
public bool SeedInitialData(User user)
|
||||
{
|
||||
var inventory = new StringBuilder();
|
||||
for (int i = 0; i < Terraria.Main.maxInventory; i++)
|
||||
for (int i = 0; i < NetItem.maxNetInventory; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
|
|
@ -137,7 +137,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -162,7 +162,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -176,7 +176,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
@ -191,7 +191,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ namespace TShockAPI.DB
|
|||
var error = "Invalid parent {0} for group {1}".SFormat(parentname, group.Name);
|
||||
if (exceptions)
|
||||
throw new GroupManagerException(error);
|
||||
Log.ConsoleError(error);
|
||||
TShock.Log.ConsoleError(error);
|
||||
return error;
|
||||
}
|
||||
group.Parent = parent;
|
||||
|
|
@ -162,19 +162,6 @@ namespace TShockAPI.DB
|
|||
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>
|
||||
/// Updates a group including permissions
|
||||
/// </summary>
|
||||
|
|
@ -224,13 +211,6 @@ namespace TShockAPI.DB
|
|||
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)
|
||||
{
|
||||
if (!GroupExists(name))
|
||||
|
|
@ -298,7 +278,7 @@ namespace TShockAPI.DB
|
|||
string groupName = reader.Get<string>("GroupName");
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -314,7 +294,7 @@ namespace TShockAPI.DB
|
|||
catch (ArgumentException)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -349,14 +329,14 @@ namespace TShockAPI.DB
|
|||
group.Parent = groups.FirstOrDefault(g => g.Name == parentGroupName);
|
||||
if (group.Parent == null)
|
||||
{
|
||||
Log.ConsoleError(
|
||||
TShock.Log.ConsoleError(
|
||||
"ERROR: Group \"{0}\" is referencing non existent parent group \"{1}\", parent reference was removed.",
|
||||
group.Name, parentGroupName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (group.Parent == group)
|
||||
Log.ConsoleInfo(
|
||||
TShock.Log.ConsoleInfo(
|
||||
"WARNING: Group \"{0}\" is referencing itself as parent group, parent reference was removed.", group.Name);
|
||||
|
||||
List<Group> groupChain = new List<Group> { group };
|
||||
|
|
@ -365,7 +345,7 @@ namespace TShockAPI.DB
|
|||
{
|
||||
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.",
|
||||
checkingGroup.Name, checkingGroup.Parent.Name);
|
||||
|
||||
|
|
@ -386,7 +366,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
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)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
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
|
||||
r.AllowedIDs.Add(id);
|
||||
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)
|
||||
{
|
||||
Log.Error("Your database contains invalid UserIDs (they should be ints).");
|
||||
Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field.");
|
||||
Log.Error(e.ToString());
|
||||
Log.Error(e.StackTrace);
|
||||
TShock.Log.Error("Your database contains invalid UserIDs (they should be ints).");
|
||||
TShock.Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field.");
|
||||
TShock.Log.Error(e.ToString());
|
||||
TShock.Log.Error(e.StackTrace);
|
||||
}
|
||||
|
||||
Regions.Add(r);
|
||||
|
|
@ -111,10 +111,22 @@ namespace TShockAPI.DB
|
|||
}
|
||||
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)
|
||||
{
|
||||
if (GetRegionByName(regionname) != null)
|
||||
|
|
@ -126,28 +138,37 @@ namespace TShockAPI.DB
|
|||
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);",
|
||||
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;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
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)
|
||||
{
|
||||
try
|
||||
{
|
||||
database.Query("DELETE FROM Regions WHERE RegionName=@0 AND WorldID=@1", name, 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);
|
||||
Hooks.RegionHooks.OnRegionDeleted(region);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -165,7 +186,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -182,7 +203,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -308,7 +329,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -363,7 +384,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -390,7 +411,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -413,7 +434,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return regions;
|
||||
}
|
||||
|
|
@ -518,7 +539,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
|
||||
return new Vector2();
|
||||
|
|
@ -88,7 +88,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
|
||||
return new Vector2();
|
||||
|
|
@ -105,7 +105,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -117,7 +117,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
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.")]
|
||||
public void EnsureExists(SqlTable table)
|
||||
{
|
||||
var columns = GetColumns(table);
|
||||
if (columns.Count > 0)
|
||||
{
|
||||
if (!table.Columns.All(c => columns.Contains(c.Name)) || !columns.All(c => table.Columns.Any(c2 => c2.Name == c)))
|
||||
{
|
||||
var from = new SqlTable(table.Name, columns.Select(s => new SqlColumn(s, MySqlDbType.String)).ToList());
|
||||
database.Query(creator.AlterTable(from, table));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
database.Query(creator.CreateTable(table));
|
||||
}
|
||||
EnsureTableStructure(table);
|
||||
}
|
||||
|
||||
public List<string> GetColumns(SqlTable table)
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex);
|
||||
TShock.Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -285,7 +285,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -117,7 +117,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -186,7 +186,7 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,10 +62,10 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
public class TileEditEventArgs : HandledEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The TSPlayer who made the tile edit
|
||||
/// </summary>
|
||||
public TSPlayer Player { get; set; }
|
||||
/// <summary>
|
||||
/// The TSPlayer who made the tile edit
|
||||
/// </summary>
|
||||
public TSPlayer Player { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The tile coordinate on the X plane
|
||||
|
|
@ -87,10 +87,10 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
public EditAction Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Did the tile get destroyed successfully.
|
||||
/// </summary>
|
||||
public EditType editDetail { get; set; }
|
||||
/// <summary>
|
||||
/// Did the tile get destroyed successfully.
|
||||
/// </summary>
|
||||
public EditType editDetail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used when a tile is placed to denote a subtype of tile. (e.g. for tile id 21: Chest = 0, Gold Chest = 1)
|
||||
|
|
@ -109,12 +109,12 @@ namespace TShockAPI
|
|||
|
||||
var args = new TileEditEventArgs
|
||||
{
|
||||
Player = ply,
|
||||
Player = ply,
|
||||
X = x,
|
||||
Y = y,
|
||||
Action = action,
|
||||
EditData = editData,
|
||||
editDetail = editDetail,
|
||||
editDetail = editDetail,
|
||||
Style = style
|
||||
};
|
||||
TileEdit.Invoke(null, args);
|
||||
|
|
@ -152,37 +152,37 @@ namespace TShockAPI
|
|||
return args.Handled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For use in a PlayerTeam event
|
||||
/// </summary>
|
||||
public class PlayerTeamEventArgs : HandledEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The Terraria player ID of the player
|
||||
/// </summary>
|
||||
public byte PlayerId { get; set; }
|
||||
/// <summary>
|
||||
/// Enable/disable pvp?
|
||||
/// </summary>
|
||||
public byte Team { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// TogglePvp - called when a player toggles pvp
|
||||
/// </summary>
|
||||
public static HandlerList<PlayerTeamEventArgs> PlayerTeam;
|
||||
private static bool OnPlayerTeam(byte _id, byte _team)
|
||||
{
|
||||
if (PlayerTeam == null)
|
||||
return false;
|
||||
/// <summary>
|
||||
/// For use in a PlayerTeam event
|
||||
/// </summary>
|
||||
public class PlayerTeamEventArgs : HandledEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The Terraria player ID of the player
|
||||
/// </summary>
|
||||
public byte PlayerId { get; set; }
|
||||
/// <summary>
|
||||
/// Enable/disable pvp?
|
||||
/// </summary>
|
||||
public byte Team { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// TogglePvp - called when a player toggles pvp
|
||||
/// </summary>
|
||||
public static HandlerList<PlayerTeamEventArgs> PlayerTeam;
|
||||
private static bool OnPlayerTeam(byte _id, byte _team)
|
||||
{
|
||||
if (PlayerTeam == null)
|
||||
return false;
|
||||
|
||||
var args = new PlayerTeamEventArgs
|
||||
{
|
||||
PlayerId = _id,
|
||||
Team = _team,
|
||||
};
|
||||
PlayerTeam.Invoke(null, args);
|
||||
return args.Handled;
|
||||
}
|
||||
var args = new PlayerTeamEventArgs
|
||||
{
|
||||
PlayerId = _id,
|
||||
Team = _team,
|
||||
};
|
||||
PlayerTeam.Invoke(null, args);
|
||||
return args.Handled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For use in a PlayerSlot event
|
||||
|
|
@ -1261,7 +1261,7 @@ namespace TShockAPI
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1469,7 +1469,7 @@ namespace TShockAPI
|
|||
TShock.CharacterDB.InsertPlayerData(args.Player);
|
||||
}
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1500,56 +1500,56 @@ namespace TShockAPI
|
|||
|
||||
string password = args.Data.ReadString();
|
||||
|
||||
if (Hooks.PlayerHooks.OnPlayerPreLogin(args.Player, args.Player.Name, password))
|
||||
return true;
|
||||
if (Hooks.PlayerHooks.OnPlayerPreLogin(args.Player, args.Player.Name, password))
|
||||
return true;
|
||||
|
||||
var user = TShock.Users.GetUserByName(args.Player.Name);
|
||||
if (user != null && !TShock.Config.DisableLoginBeforeJoin)
|
||||
if (user != null && !TShock.Config.DisableLoginBeforeJoin)
|
||||
{
|
||||
string encrPass = TShock.Utils.HashPassword(password);
|
||||
if (user.Password.ToUpper() == encrPass.ToUpper())
|
||||
{
|
||||
args.Player.RequiresPassword = false;
|
||||
args.Player.PlayerData = TShock.CharacterDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Player.Name));
|
||||
args.Player.RequiresPassword = false;
|
||||
args.Player.PlayerData = TShock.CharacterDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Player.Name));
|
||||
|
||||
if (args.Player.State == 1)
|
||||
args.Player.State = 2;
|
||||
NetMessage.SendData((int) PacketTypes.WorldInfo, args.Player.Index);
|
||||
if (args.Player.State == 1)
|
||||
args.Player.State = 2;
|
||||
NetMessage.SendData((int) PacketTypes.WorldInfo, args.Player.Index);
|
||||
|
||||
var group = TShock.Utils.GetGroup(user.Group);
|
||||
var group = TShock.Utils.GetGroup(user.Group);
|
||||
|
||||
if (Main.ServerSideCharacter)
|
||||
{
|
||||
if (group.HasPermission(Permissions.bypassssc))
|
||||
{
|
||||
args.Player.IgnoreActionsForClearingTrashCan = false;
|
||||
}
|
||||
if (Main.ServerSideCharacter)
|
||||
{
|
||||
if (group.HasPermission(Permissions.bypassssc))
|
||||
{
|
||||
args.Player.IgnoreActionsForClearingTrashCan = false;
|
||||
}
|
||||
args.Player.PlayerData.RestoreCharacter(args.Player);
|
||||
}
|
||||
}
|
||||
args.Player.LoginFailsBySsi = false;
|
||||
|
||||
if (group.HasPermission(Permissions.ignorestackhackdetection))
|
||||
args.Player.IgnoreActionsForCheating = "none";
|
||||
if (group.HasPermission(Permissions.ignorestackhackdetection))
|
||||
args.Player.IgnoreActionsForCheating = "none";
|
||||
|
||||
if (group.HasPermission(Permissions.usebanneditem))
|
||||
args.Player.IgnoreActionsForDisabledArmor = "none";
|
||||
if (group.HasPermission(Permissions.usebanneditem))
|
||||
args.Player.IgnoreActionsForDisabledArmor = "none";
|
||||
|
||||
args.Player.Group = group;
|
||||
args.Player.tempGroup = null;
|
||||
args.Player.UserAccountName = args.Player.Name;
|
||||
args.Player.UserID = TShock.Users.GetUserID(args.Player.UserAccountName);
|
||||
args.Player.IsLoggedIn = true;
|
||||
args.Player.IgnoreActionsForInventory = "none";
|
||||
args.Player.Group = group;
|
||||
args.Player.tempGroup = null;
|
||||
args.Player.UserAccountName = args.Player.Name;
|
||||
args.Player.UserID = TShock.Users.GetUserID(args.Player.UserAccountName);
|
||||
args.Player.IsLoggedIn = true;
|
||||
args.Player.IgnoreActionsForInventory = "none";
|
||||
|
||||
if (!args.Player.IgnoreActionsForClearingTrashCan && Main.ServerSideCharacter)
|
||||
{
|
||||
args.Player.PlayerData.CopyCharacter(args.Player);
|
||||
TShock.CharacterDB.InsertPlayerData(args.Player);
|
||||
}
|
||||
args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen);
|
||||
Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + ".");
|
||||
if (!args.Player.IgnoreActionsForClearingTrashCan && Main.ServerSideCharacter)
|
||||
{
|
||||
args.Player.PlayerData.CopyCharacter(args.Player);
|
||||
TShock.CharacterDB.InsertPlayerData(args.Player);
|
||||
}
|
||||
args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen);
|
||||
TShock.Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + ".");
|
||||
TShock.Users.SetUserUUID(user, args.Player.UUID);
|
||||
Hooks.PlayerHooks.OnPlayerPostLogin(args.Player);
|
||||
Hooks.PlayerHooks.OnPlayerPostLogin(args.Player);
|
||||
return true;
|
||||
}
|
||||
TShock.Utils.ForceKick(args.Player, "Invalid user account password.", true);
|
||||
|
|
@ -1577,7 +1577,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (args.Player.RequestedSection)
|
||||
return true;
|
||||
args.Player.RequestedSection = true;
|
||||
args.Player.RequestedSection = true;
|
||||
if (String.IsNullOrEmpty(args.Player.Name))
|
||||
{
|
||||
TShock.Utils.ForceKick(args.Player, "Blank name.", true);
|
||||
|
|
@ -2180,15 +2180,15 @@ namespace TShockAPI
|
|||
return false;
|
||||
}
|
||||
|
||||
private static bool HandlePlayerTeam(GetDataHandlerArgs args)
|
||||
{
|
||||
byte id = args.Data.ReadInt8();
|
||||
byte team = args.Data.ReadInt8();
|
||||
if (OnPlayerTeam(id, team))
|
||||
return true;
|
||||
private static bool HandlePlayerTeam(GetDataHandlerArgs args)
|
||||
{
|
||||
byte id = args.Data.ReadInt8();
|
||||
byte team = args.Data.ReadInt8();
|
||||
if (OnPlayerTeam(id, team))
|
||||
return true;
|
||||
|
||||
if (id != args.Player.Index)
|
||||
return true;
|
||||
if (id != args.Player.Index)
|
||||
return true;
|
||||
|
||||
if ((DateTime.UtcNow - args.Player.LastPvPTeamChange).TotalSeconds < 5)
|
||||
{
|
||||
|
|
@ -2197,8 +2197,8 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
args.Player.LastPvPTeamChange = DateTime.UtcNow;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool HandlePlayerUpdate(GetDataHandlerArgs args)
|
||||
{
|
||||
|
|
@ -2232,34 +2232,30 @@ namespace TShockAPI
|
|||
if (!pos.Equals(args.Player.LastNetPosition))
|
||||
{
|
||||
float distance = Vector2.Distance(new Vector2(pos.X/16f, pos.Y/16f),
|
||||
new Vector2(args.Player.LastNetPosition.X/16f, args.Player.LastNetPosition.Y/16f));
|
||||
new Vector2(args.Player.LastNetPosition.X/16f, args.Player.LastNetPosition.Y/16f));
|
||||
if (TShock.CheckIgnores(args.Player))
|
||||
{
|
||||
if (distance > TShock.Config.MaxRangeForDisabled)
|
||||
{
|
||||
if (args.Player.IgnoreActionsForCheating != "none")
|
||||
{
|
||||
args.Player.SendMessage("Disabled for cheating: " + args.Player.IgnoreActionsForCheating,
|
||||
Color.Red);
|
||||
args.Player.SendErrorMessage("Disabled for cheating: " + args.Player.IgnoreActionsForCheating);
|
||||
}
|
||||
else if (args.Player.IgnoreActionsForDisabledArmor != "none")
|
||||
{
|
||||
args.Player.SendMessage(
|
||||
"Disabled for banned armor: " + args.Player.IgnoreActionsForDisabledArmor, Color.Red);
|
||||
args.Player.SendErrorMessage("Disabled for banned armor: " + args.Player.IgnoreActionsForDisabledArmor);
|
||||
}
|
||||
else if (args.Player.IgnoreActionsForInventory != "none")
|
||||
{
|
||||
args.Player.SendMessage(
|
||||
"Disabled for Server Side Inventory: " + args.Player.IgnoreActionsForInventory,
|
||||
Color.Red);
|
||||
args.Player.SendErrorMessage("Disabled for Server Side Inventory: " + args.Player.IgnoreActionsForInventory);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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 lastTileY = args.Player.LastNetPosition.Y - 48;
|
||||
|
|
@ -2299,9 +2295,8 @@ namespace TShockAPI
|
|||
{
|
||||
control[5] = false;
|
||||
args.Player.Disable("Using banned item");
|
||||
args.Player.SendMessage(
|
||||
string.Format("You cannot use {0} on this server. Your actions are being ignored.",
|
||||
args.TPlayer.inventory[item].name), Color.Red);
|
||||
args.Player.SendErrorMessage("You cannot use {0} on this server. Your actions are being ignored.",
|
||||
args.TPlayer.inventory[item].name);
|
||||
}
|
||||
|
||||
if (args.TPlayer.inventory[item].name == "Mana Crystal" && args.Player.TPlayer.statManaMax <= 180)
|
||||
|
|
@ -2419,7 +2414,7 @@ namespace TShockAPI
|
|||
var owner = args.Data.ReadInt8();
|
||||
var type = args.Data.ReadInt16();
|
||||
var bits = (BitsByte) args.Data.ReadInt8();
|
||||
owner = (byte)args.Player.Index;
|
||||
owner = (byte)args.Player.Index;
|
||||
float[] ai = new float[Projectile.maxAI];
|
||||
|
||||
for (int i = 0; i < Projectile.maxAI; i++)
|
||||
|
|
@ -2449,15 +2444,8 @@ namespace TShockAPI
|
|||
args.Player.RemoveProjectile(ident, owner);
|
||||
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))
|
||||
{
|
||||
args.Player.Disable(String.Format("Projectile damage is higher than {0}.", TShock.Config.MaxProjDamage));
|
||||
args.Player.RemoveProjectile(ident, owner);
|
||||
|
|
@ -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))
|
||||
{
|
||||
Log.Debug("Certain projectiles have been ignored for cheat detection.");
|
||||
TShock.Log.Debug("Certain projectiles have been ignored for cheat detection.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2502,7 +2490,7 @@ namespace TShockAPI
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
|
@ -2527,7 +2515,7 @@ namespace TShockAPI
|
|||
{
|
||||
var ident = args.Data.ReadInt16();
|
||||
var owner = args.Data.ReadInt8();
|
||||
owner = (byte)args.Player.Index;
|
||||
owner = (byte)args.Player.Index;
|
||||
var index = TShock.Utils.SearchProjectile(ident, owner);
|
||||
|
||||
if (index > Main.maxProjectiles || index < 0)
|
||||
|
|
@ -2537,7 +2525,7 @@ namespace TShockAPI
|
|||
|
||||
var type = Main.projectile[index].type;
|
||||
|
||||
// Players can no longer destroy projectiles that are not theirs as of 1.1.2
|
||||
// Players can no longer destroy projectiles that are not theirs as of 1.1.2
|
||||
/*if (args.Player.Index != Main.projectile[index].owner && type != 102 && type != 100 && !TShock.Config.IgnoreProjKill) // workaround for skeletron prime projectiles
|
||||
{
|
||||
args.Player.Disable(String.Format("Owner ({0}) and player ID ({1}) does not match to kill projectile of type: {3}", Main.projectile[index].owner, args.Player.Index, type));
|
||||
|
|
@ -2551,7 +2539,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (TShock.CheckProjectilePermission(args.Player, index, type) && type != 102 && type != 100 && !TShock.Config.IgnoreProjKill)
|
||||
if (TShock.CheckProjectilePermission(args.Player, index, type) && type != 102 && type != 100 && !TShock.Config.IgnoreProjKill)
|
||||
{
|
||||
args.Player.Disable("Does not have projectile permission to kill projectile.");
|
||||
args.Player.RemoveProjectile(ident, owner);
|
||||
|
|
@ -2579,7 +2567,7 @@ namespace TShockAPI
|
|||
if (dmg > 20000) //Abnormal values have the potential to cause infinite loops in the server.
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -2610,18 +2598,18 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
if (args.TPlayer.difficulty == 2 && (TShock.Config.KickOnHardcoreDeath || TShock.Config.BanOnHardcoreDeath))
|
||||
{
|
||||
if (TShock.Config.BanOnHardcoreDeath)
|
||||
{
|
||||
if (!TShock.Utils.Ban(args.Player, TShock.Config.HardcoreBanReason, false, "hardcore-death"))
|
||||
TShock.Utils.ForceKick(args.Player, "Death results in a ban, but can't ban you.", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
TShock.Utils.ForceKick(args.Player, TShock.Config.HardcoreKickReason, true, false);
|
||||
}
|
||||
}
|
||||
if (args.TPlayer.difficulty == 2 && (TShock.Config.KickOnHardcoreDeath || TShock.Config.BanOnHardcoreDeath))
|
||||
{
|
||||
if (TShock.Config.BanOnHardcoreDeath)
|
||||
{
|
||||
if (!TShock.Utils.Ban(args.Player, TShock.Config.HardcoreBanReason, false, "hardcore-death"))
|
||||
TShock.Utils.ForceKick(args.Player, "Death results in a ban, but can't ban you.", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
TShock.Utils.ForceKick(args.Player, TShock.Config.HardcoreKickReason, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (args.TPlayer.difficulty == 2 && Main.ServerSideCharacter && args.Player.IsLoggedIn)
|
||||
{
|
||||
|
|
@ -2686,32 +2674,32 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
if (type == 1 && !(bucket == 2 || bucket == 0))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.Disable("Spreading lava without holding a lava bucket");
|
||||
args.Player.SendTileSquare(tileX, tileY, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(type == 1 && TShock.Itembans.ItemIsBanned("Lava Bucket", args.Player))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.Disable("Using banned lava bucket without permissions");
|
||||
args.Player.SendTileSquare(tileX, tileY, 1);
|
||||
return true;
|
||||
}
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.Disable("Spreading lava without holding a lava bucket");
|
||||
args.Player.SendTileSquare(tileX, tileY, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(type == 1 && TShock.Itembans.ItemIsBanned("Lava Bucket", args.Player))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.Disable("Using banned lava bucket without permissions");
|
||||
args.Player.SendTileSquare(tileX, tileY, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type == 0 && !(bucket == 1 || bucket == 0))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.Disable("Spreading water without holding a water bucket");
|
||||
args.Player.SendTileSquare(tileX, tileY, 1);
|
||||
return true;
|
||||
}
|
||||
if (type == 0 && !(bucket == 1 || bucket == 0))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.Disable("Spreading water without holding a water bucket");
|
||||
args.Player.SendTileSquare(tileX, tileY, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type == 0 && TShock.Itembans.ItemIsBanned("Water Bucket", args.Player))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.Disable("Using banned water bucket without permissions");
|
||||
args.Player.SendTileSquare(tileX, tileY, 1);
|
||||
return true;
|
||||
|
|
@ -2825,20 +2813,20 @@ namespace TShockAPI
|
|||
args.Player.InitSpawn = true;
|
||||
|
||||
if ((Main.ServerSideCharacter) && (args.Player.sX > 0) && (args.Player.sY > 0) && (args.TPlayer.SpawnX > 0) && ((args.TPlayer.SpawnX != args.Player.sX) && (args.TPlayer.SpawnY != args.Player.sY)))
|
||||
{
|
||||
{
|
||||
|
||||
args.Player.sX=args.TPlayer.SpawnX;
|
||||
args.Player.sY=args.TPlayer.SpawnY;
|
||||
|
||||
if (((Main.tile[args.Player.sX, args.Player.sY - 1].active() && Main.tile[args.Player.sX, args.Player.sY - 1].type == 79)) && (WorldGen.StartRoomCheck(args.Player.sX, args.Player.sY -1)))
|
||||
args.Player.Teleport(args.Player.sX * 16, (args.Player.sY * 16) -48);
|
||||
}
|
||||
}
|
||||
|
||||
else if ((Main.ServerSideCharacter) && (args.Player.sX > 0) && (args.Player.sY > 0))
|
||||
{
|
||||
else if ((Main.ServerSideCharacter) && (args.Player.sX > 0) && (args.Player.sY > 0))
|
||||
{
|
||||
if (((Main.tile[args.Player.sX, args.Player.sY - 1].active() && Main.tile[args.Player.sX, args.Player.sY - 1].type == 79)) && (WorldGen.StartRoomCheck(args.Player.sX, args.Player.sY -1)))
|
||||
args.Player.Teleport(args.Player.sX * 16, (args.Player.sY * 16) -48);
|
||||
}
|
||||
}
|
||||
|
||||
args.Player.Dead = false;
|
||||
return false;
|
||||
|
|
@ -2970,7 +2958,7 @@ namespace TShockAPI
|
|||
|
||||
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,
|
||||
Convert.ToByte(Main.npc[id].homeless));
|
||||
return true;
|
||||
|
|
@ -2978,13 +2966,13 @@ namespace TShockAPI
|
|||
|
||||
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,
|
||||
Convert.ToByte(Main.npc[id].homeless));
|
||||
return true;
|
||||
}
|
||||
|
||||
//removed until NPC Home packet actually sends their home coords.
|
||||
//removed until NPC Home packet actually sends their home coords.
|
||||
/*if (TShock.CheckRangePermission(args.Player, x, y))
|
||||
{
|
||||
args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY,
|
||||
|
|
@ -3099,7 +3087,7 @@ namespace TShockAPI
|
|||
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!!!
|
||||
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);
|
||||
return true;
|
||||
|
||||
|
|
@ -3214,7 +3202,7 @@ namespace TShockAPI
|
|||
if (Main.npc[id] == null)
|
||||
return true;
|
||||
|
||||
if (dmg > TShock.Config.MaxDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap))
|
||||
if (dmg > TShock.Config.MaxDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap))
|
||||
{
|
||||
if (TShock.Config.KickOnDamageThresholdBroken)
|
||||
{
|
||||
|
|
@ -3382,12 +3370,12 @@ namespace TShockAPI
|
|||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (!spawnboss && !invasion)
|
||||
|
|
|
|||
|
|
@ -153,13 +153,6 @@ namespace TShockAPI
|
|||
public byte B = 255;
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace TShockAPI.Hooks
|
|||
{
|
||||
public class AccountDeleteEventArgs
|
||||
{
|
||||
public User User { get; set; }
|
||||
public User User { get; private set; }
|
||||
|
||||
public AccountDeleteEventArgs(User user)
|
||||
{
|
||||
|
|
@ -31,7 +31,7 @@ namespace TShockAPI.Hooks
|
|||
|
||||
public class AccountCreateEventArgs
|
||||
{
|
||||
public User User { get; set; }
|
||||
public User User { get; private set; }
|
||||
|
||||
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.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
[Flags]
|
||||
public enum LogLevel
|
||||
{
|
||||
None = 0,
|
||||
Debug = 1,
|
||||
Info = 2,
|
||||
Warning = 4,
|
||||
Error = 8,
|
||||
Data = 16,
|
||||
All = 31
|
||||
}
|
||||
|
||||
public static class Log
|
||||
{
|
||||
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>
|
||||
/// Writes data to the log file.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to be written.</param>
|
||||
[Obsolete("Please use TShock.Log.Data")]
|
||||
public static void Data(String message)
|
||||
{
|
||||
Write(message, LogLevel.Data);
|
||||
|
|
@ -78,6 +37,7 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
[Obsolete("Please use TShock.Log.Data")]
|
||||
public static void Data(string format, params object[] args)
|
||||
{
|
||||
Data(String.Format(format, args));
|
||||
|
|
@ -87,6 +47,7 @@ namespace TShockAPI
|
|||
/// Writes an error to the log file.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to be written.</param>
|
||||
[Obsolete("Please use TShock.Log.Error")]
|
||||
public static void Error(String message)
|
||||
{
|
||||
Write(message, LogLevel.Error);
|
||||
|
|
@ -97,6 +58,7 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
[Obsolete("Please use TShock.Log.Error")]
|
||||
public static void Error(string format, params object[] args)
|
||||
{
|
||||
Error(String.Format(format, args));
|
||||
|
|
@ -106,6 +68,7 @@ namespace TShockAPI
|
|||
/// Writes an error to the log file.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to be written.</param>
|
||||
[Obsolete("Please use TShock.Log.ConsoleError")]
|
||||
public static void ConsoleError(String message)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
|
|
@ -119,6 +82,7 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
[Obsolete("Please use TShock.Log.ConsoleError")]
|
||||
public static void ConsoleError(string format, params object[] args)
|
||||
{
|
||||
ConsoleError(String.Format(format, args));
|
||||
|
|
@ -128,6 +92,7 @@ namespace TShockAPI
|
|||
/// Writes a warning to the log file.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to be written.</param>
|
||||
[Obsolete("Please use TShock.Log.Warn")]
|
||||
public static void Warn(String message)
|
||||
{
|
||||
Write(message, LogLevel.Warning);
|
||||
|
|
@ -138,6 +103,7 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
[Obsolete("Please use TShock.Log.Warn")]
|
||||
public static void Warn(string format, params object[] args)
|
||||
{
|
||||
Warn(String.Format(format, args));
|
||||
|
|
@ -147,6 +113,7 @@ namespace TShockAPI
|
|||
/// Writes an informative string to the log file.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to be written.</param>
|
||||
[Obsolete("Please use TShock.Log.Info")]
|
||||
public static void Info(String message)
|
||||
{
|
||||
Write(message, LogLevel.Info);
|
||||
|
|
@ -157,6 +124,7 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
[Obsolete("Please use TShock.Log.Info")]
|
||||
public static void Info(string format, params object[] args)
|
||||
{
|
||||
Info(String.Format(format, args));
|
||||
|
|
@ -166,6 +134,7 @@ namespace TShockAPI
|
|||
/// Writes an informative string to the log file. Also outputs to the console.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to be written.</param>
|
||||
[Obsolete("Please use TShock.Log.ConsoleInfo")]
|
||||
public static void ConsoleInfo(String message)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
|
|
@ -179,6 +148,7 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
[Obsolete("Please use TShock.Log.ConsoleInfo")]
|
||||
public static void ConsoleInfo(string format, params object[] args)
|
||||
{
|
||||
ConsoleInfo(String.Format(format, args));
|
||||
|
|
@ -188,6 +158,7 @@ namespace TShockAPI
|
|||
/// Writes a debug string to the log file.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to be written.</param>
|
||||
[Obsolete("Please use TShock.Log.Debug")]
|
||||
public static void Debug(String message)
|
||||
{
|
||||
Write(message, LogLevel.Debug);
|
||||
|
|
@ -198,53 +169,18 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
[Obsolete("Please use TShock.Log.Debug")]
|
||||
public static void Debug(string format, params object[] args)
|
||||
{
|
||||
Debug(String.Format(format, args));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes objects that are being used.
|
||||
/// </summary>
|
||||
public static void Dispose()
|
||||
{
|
||||
_logWriter.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method which writes a message directly to the log file.
|
||||
/// </summary>
|
||||
private static void Write(String message, LogLevel level)
|
||||
{
|
||||
if (!MayWriteType(level))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string caller = "TShock";
|
||||
|
||||
StackFrame frame = new StackTrace().GetFrame(2);
|
||||
if (frame != null)
|
||||
{
|
||||
var meth = frame.GetMethod();
|
||||
if (meth != null)
|
||||
caller = meth.DeclaringType.Name;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_logWriter.WriteLine(string.Format("{0} - {1}: {2}: {3}",
|
||||
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture),
|
||||
caller, level.ToString().ToUpper(), message));
|
||||
_logWriter.Flush();
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
Console.WriteLine("Unable to write to log as log has been disposed.");
|
||||
Console.WriteLine("{0} - {1}: {2}: {3}",
|
||||
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture),
|
||||
caller, level.ToString().ToUpper(), message);
|
||||
}
|
||||
TShock.Log.Write(message, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -145,7 +145,7 @@ namespace TShockAPI
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.ConsoleError(e.ToString());
|
||||
TShock.Log.ConsoleError(e.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -206,7 +206,7 @@ namespace TShockAPI
|
|||
}
|
||||
catch (ObjectDisposedException e)
|
||||
{
|
||||
Log.Warn(e.ToString());
|
||||
TShock.Log.Warn(e.ToString());
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
|
|
@ -216,7 +216,7 @@ namespace TShockAPI
|
|||
case 10053:
|
||||
break;
|
||||
default:
|
||||
Log.Warn(e.ToString());
|
||||
TShock.Log.Warn(e.ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -230,12 +230,12 @@ namespace TShockAPI
|
|||
case SocketError.ConnectionReset:
|
||||
break;
|
||||
default:
|
||||
Log.Warn(e.ToString());
|
||||
TShock.Log.Warn(e.ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
Log.Warn(e.ToString());
|
||||
TShock.Log.Warn(e.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -349,6 +349,9 @@ namespace TShockAPI
|
|||
[Description("Player recovers health as damage is taken. Can be one shotted.")]
|
||||
public static readonly string godmode = "tshock.godmode";
|
||||
|
||||
[Description("User can godmode other players")]
|
||||
public static readonly string godmodeother = "tshock.godmode.other";
|
||||
|
||||
[Description("Player can chat")]
|
||||
public static readonly string canchat = "tshock.canchat";
|
||||
|
||||
|
|
|
|||
|
|
@ -53,5 +53,5 @@ using System.Runtime.InteropServices;
|
|||
// 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)
|
||||
|
||||
[assembly: AssemblyVersion("4.2.6")]
|
||||
[assembly: AssemblyFileVersion("4.2.6")]
|
||||
[assembly: AssemblyVersion("4.2.7")]
|
||||
[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.ContentType = new ContentTypeHeader("application/json; charset=utf-8");
|
||||
e.Response.Add(serverHeader);
|
||||
e.Response.Body.Write(Encoding.UTF8.GetBytes(str), 0, str.Length);
|
||||
var bytes = Encoding.UTF8.GetBytes(str);
|
||||
e.Response.Body.Write(bytes, 0, bytes.Length);
|
||||
e.Response.Status = HttpStatusCode.OK;
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +213,7 @@ namespace Rests
|
|||
object result = cmd.Execute(verbs, parms, request);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ namespace TShockAPI
|
|||
var msg = args.Parameters["msg"];
|
||||
if (string.IsNullOrWhiteSpace(msg))
|
||||
return RestMissingParam("msg");
|
||||
TShock.Utils.Broadcast(msg);
|
||||
TSPlayer.All.SendInfoMessage(msg);
|
||||
return RestResponse("The message was broadcasted successfully");
|
||||
}
|
||||
|
||||
|
|
@ -660,7 +660,7 @@ namespace TShockAPI
|
|||
TSPlayer player = (TSPlayer)ret;
|
||||
player.DamagePlayer(999999);
|
||||
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");
|
||||
}
|
||||
|
||||
|
|
@ -916,7 +916,7 @@ namespace TShockAPI
|
|||
TSPlayer player = (TSPlayer)ret;
|
||||
player.mute = mute;
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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, ",
|
||||
"change the config setting \"RestUseNewPermissionModel\" to true."
|
||||
);
|
||||
Log.Warn(warningMessage);
|
||||
TShock.Log.Warn(warningMessage);
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(warningMessage);
|
||||
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 ",
|
||||
"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)
|
||||
{
|
||||
Log.Error("World saved notification failed");
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error("World saved notification failed");
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -130,12 +130,12 @@ namespace TShockAPI
|
|||
else
|
||||
WorldFile.saveWorld(task.resetTime);
|
||||
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)
|
||||
{
|
||||
Log.Error("World saved failed");
|
||||
Log.Error(e.ToString());
|
||||
TShock.Log.Error("World saved failed");
|
||||
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 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);
|
||||
client.Timeout = 5000;
|
||||
try
|
||||
|
|
@ -64,7 +64,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (!failed)
|
||||
{
|
||||
Log.ConsoleError("StatTracker Exception: {0}", e);
|
||||
TShock.Log.ConsoleError("StatTracker Exception: {0}", e);
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,29 +30,29 @@ namespace TShockAPI
|
|||
{
|
||||
public class TSPlayer
|
||||
{
|
||||
/// <summary>
|
||||
/// This represents the server as a player.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// This represents the server as a player.
|
||||
/// </summary>
|
||||
public static readonly TSServerPlayer Server = new TSServerPlayer();
|
||||
|
||||
/// <summary>
|
||||
/// This player represents all the players.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// This player represents all the players.
|
||||
/// </summary>
|
||||
public static readonly TSPlayer All = new TSPlayer("All");
|
||||
|
||||
/// <summary>
|
||||
/// The amount of tiles that the player has killed in the last second.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The amount of tiles that the player has killed in the last second.
|
||||
/// </summary>
|
||||
public int TileKillThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of tiles the player has placed in the last second.
|
||||
/// </summary>
|
||||
public int TilePlaceThreshold { get; set; }
|
||||
/// <summary>
|
||||
/// The amount of tiles the player has placed in the last second.
|
||||
/// </summary>
|
||||
public int TilePlaceThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of liquid (in tiles) that the player has placed in the last second.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The amount of liquid (in tiles) that the player has placed in the last second.
|
||||
/// </summary>
|
||||
public int TileLiquidThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -60,9 +60,9 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
public int PaintThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of projectiles created by the player in the last second.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The number of projectiles created by the player in the last second.
|
||||
/// </summary>
|
||||
public int ProjectileThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -83,130 +83,130 @@ namespace TShockAPI
|
|||
public int sX = -1;
|
||||
public int sY = -1;
|
||||
|
||||
/// <summary>
|
||||
/// A queue of tiles destroyed by the player for reverting.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// A queue of tiles destroyed by the player for reverting.
|
||||
/// </summary>
|
||||
public Dictionary<Vector2, Tile> TilesDestroyed { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// A queue of tiles placed by the player for reverting.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// A queue of tiles placed by the player for reverting.
|
||||
/// </summary>
|
||||
public Dictionary<Vector2, Tile> TilesCreated { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The player's group.
|
||||
/// </summary>
|
||||
public Group Group
|
||||
{
|
||||
get
|
||||
{
|
||||
if (tempGroup != null)
|
||||
return tempGroup;
|
||||
return group;
|
||||
}
|
||||
set { group = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The player's group.
|
||||
/// </summary>
|
||||
public Group Group
|
||||
{
|
||||
get
|
||||
{
|
||||
if (tempGroup != null)
|
||||
return tempGroup;
|
||||
return group;
|
||||
}
|
||||
set { group = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The player's temporary group. This overrides the user's actual group.
|
||||
/// </summary>
|
||||
public Group tempGroup = null;
|
||||
/// <summary>
|
||||
/// The player's temporary group. This overrides the user's actual group.
|
||||
/// </summary>
|
||||
public Group tempGroup = null;
|
||||
|
||||
private Group group = null;
|
||||
private Group group = null;
|
||||
|
||||
public bool ReceivedInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The players index in the player array( Main.players[] ).
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The players index in the player array( Main.players[] ).
|
||||
/// </summary>
|
||||
public int Index { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The last time the player changed their team or pvp status.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The last time the player changed their team or pvp status.
|
||||
/// </summary>
|
||||
public DateTime LastPvPTeamChange;
|
||||
|
||||
/// <summary>
|
||||
/// Temp points for use in regions and other plugins.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Temp points for use in regions and other plugins.
|
||||
/// </summary>
|
||||
public Point[] TempPoints = new Point[2];
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player is waiting to place/break a tile to set as a temp point.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Whether the player is waiting to place/break a tile to set as a temp point.
|
||||
/// </summary>
|
||||
public int AwaitingTempPoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of command callbacks indexed by the command they need to do.
|
||||
/// </summary>
|
||||
public Dictionary<string, Action<object>> AwaitingResponse;
|
||||
/// <summary>
|
||||
/// A list of command callbacks indexed by the command they need to do.
|
||||
/// </summary>
|
||||
public Dictionary<string, Action<object>> AwaitingResponse;
|
||||
|
||||
public bool AwaitingName { get; set; }
|
||||
|
||||
public string[] AwaitingNameParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The last time a player broke a grief check.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The last time a player broke a grief check.
|
||||
/// </summary>
|
||||
public DateTime LastThreat { get; set; }
|
||||
|
||||
public bool InitSpawn;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player should see logs.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Whether the player should see logs.
|
||||
/// </summary>
|
||||
public bool DisplayLogs = true;
|
||||
|
||||
/// <summary>
|
||||
/// The last player that the player whispered with (to or from).
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The last player that the player whispered with (to or from).
|
||||
/// </summary>
|
||||
public TSPlayer LastWhisper;
|
||||
|
||||
/// <summary>
|
||||
/// The number of unsuccessful login attempts.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The number of unsuccessful login attempts.
|
||||
/// </summary>
|
||||
public int LoginAttempts { get; set; }
|
||||
|
||||
public Vector2 TeleportCoords = new Vector2(-1, -1);
|
||||
|
||||
public Vector2 LastNetPosition = Vector2.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// The player's login name.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The player's login name.
|
||||
/// </summary>
|
||||
public string UserAccountName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player performed a valid login attempt (i.e. entered valid user name and password) but is still blocked
|
||||
/// from logging in because of SSI.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Whether the player performed a valid login attempt (i.e. entered valid user name and password) but is still blocked
|
||||
/// from logging in because of SSI.
|
||||
/// </summary>
|
||||
public bool LoginFailsBySsi { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player is logged in or not.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Whether the player is logged in or not.
|
||||
/// </summary>
|
||||
public bool IsLoggedIn;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player has sent their whole inventory to the server while connecting.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Whether the player has sent their whole inventory to the server while connecting.
|
||||
/// </summary>
|
||||
public bool HasSentInventory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The player's user id( from the db ).
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The player's user id( from the db ).
|
||||
/// </summary>
|
||||
public int UserID = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player has been nagged about logging in.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Whether the player has been nagged about logging in.
|
||||
/// </summary>
|
||||
public bool HasBeenNaggedAboutLoggingIn;
|
||||
|
||||
public bool TPAllow = true;
|
||||
public bool TPAllow = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player is muted or not.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Whether the player is muted or not.
|
||||
/// </summary>
|
||||
public bool mute;
|
||||
|
||||
private Player FakePlayer;
|
||||
|
|
@ -218,16 +218,16 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
public int RespawnTimer;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player is dead or not.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Whether the player is dead or not.
|
||||
/// </summary>
|
||||
public bool Dead;
|
||||
|
||||
public string Country = "??";
|
||||
|
||||
/// <summary>
|
||||
/// The players difficulty( normal[softcore], mediumcore, hardcore ).
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The players difficulty( normal[softcore], mediumcore, hardcore ).
|
||||
/// </summary>
|
||||
public int Difficulty;
|
||||
|
||||
private string CacheIP;
|
||||
|
|
@ -240,53 +240,53 @@ namespace TShockAPI
|
|||
|
||||
public bool IgnoreActionsForClearingTrashCan;
|
||||
|
||||
/// <summary>
|
||||
/// The player's server side inventory data.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The player's server side inventory data.
|
||||
/// </summary>
|
||||
public PlayerData PlayerData;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player needs to specify a password upon connection( either server or user account ).
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Whether the player needs to specify a password upon connection( either server or user account ).
|
||||
/// </summary>
|
||||
public bool RequiresPassword;
|
||||
|
||||
public bool SilentKickInProgress;
|
||||
|
||||
public bool SilentJoinInProgress;
|
||||
|
||||
/// <summary>
|
||||
/// A list of points where ice tiles have been placed.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// A list of points where ice tiles have been placed.
|
||||
/// </summary>
|
||||
public List<Point> IceTiles;
|
||||
|
||||
/// <summary>
|
||||
/// Unused, can be removed.
|
||||
/// </summary>
|
||||
public long RPm = 1;
|
||||
/// <summary>
|
||||
/// Unused, can be removed.
|
||||
/// </summary>
|
||||
public long RPm = 1;
|
||||
|
||||
/// <summary>
|
||||
/// World protection message cool down.
|
||||
/// </summary>
|
||||
public long WPm = 1;
|
||||
/// <summary>
|
||||
/// World protection message cool down.
|
||||
/// </summary>
|
||||
public long WPm = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Spawn protection message cool down.
|
||||
/// </summary>
|
||||
public long SPm = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Permission to build message cool down.
|
||||
/// </summary>
|
||||
public long BPm = 1;
|
||||
/// <summary>
|
||||
/// Spawn protection message cool down.
|
||||
/// </summary>
|
||||
public long SPm = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Permission to build message cool down.
|
||||
/// </summary>
|
||||
public long BPm = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The time in ms when the player has logged in.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// The time in ms when the player has logged in.
|
||||
/// </summary>
|
||||
public long LoginMS;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player has been harrassed about logging in due to server side inventory or forced login.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Whether the player has been harrassed about logging in due to server side inventory or forced login.
|
||||
/// </summary>
|
||||
public bool LoginHarassed = false;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -303,10 +303,15 @@ namespace TShockAPI
|
|||
/// The last projectile type this player tried to kill.
|
||||
/// </summary>
|
||||
public int LastKilledProjectile = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The current region this player is in, or null if none.
|
||||
/// </summary>
|
||||
public Region CurrentRegion = null;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player is a real, human, player on the server.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Whether the player is a real, human, player on the server.
|
||||
/// </summary>
|
||||
public bool RealPlayer
|
||||
{
|
||||
get { return Index >= 0 && Index < Main.maxNetPlayers && Main.player[Index] != null; }
|
||||
|
|
@ -317,7 +322,7 @@ namespace TShockAPI
|
|||
get
|
||||
{
|
||||
return RealPlayer &&
|
||||
(Netplay.serverSock[Index] != null && Netplay.serverSock[Index].active && !Netplay.serverSock[Index].kill);
|
||||
(Netplay.serverSock[Index] != null && Netplay.serverSock[Index].active && !Netplay.serverSock[Index].kill);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -372,28 +377,28 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the player's inventory to SSI
|
||||
/// </summary>
|
||||
/// <returns>bool - True/false if it saved successfully</returns>
|
||||
public bool SaveServerCharacter()
|
||||
{
|
||||
if (!Main.ServerSideCharacter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
PlayerData.CopyCharacter(this);
|
||||
TShock.CharacterDB.InsertPlayerData(this);
|
||||
return true;
|
||||
} catch (Exception e)
|
||||
{
|
||||
Log.Error(e.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Saves the player's inventory to SSI
|
||||
/// </summary>
|
||||
/// <returns>bool - True/false if it saved successfully</returns>
|
||||
public bool SaveServerCharacter()
|
||||
{
|
||||
if (!Main.ServerSideCharacter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
PlayerData.CopyCharacter(this);
|
||||
TShock.CharacterDB.InsertPlayerData(this);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
TShock.Log.Error(e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the players server side character to client
|
||||
|
|
@ -412,7 +417,7 @@ namespace TShockAPI
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e.Message);
|
||||
TShock.Log.Error(e.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -488,9 +493,9 @@ namespace TShockAPI
|
|||
TilesDestroyed = new Dictionary<Vector2, Tile>();
|
||||
TilesCreated = new Dictionary<Vector2, Tile>();
|
||||
Index = index;
|
||||
Group = Group.DefaultGroup;
|
||||
Group = Group.DefaultGroup;
|
||||
IceTiles = new List<Point>();
|
||||
AwaitingResponse = new Dictionary<string, Action<object>>();
|
||||
AwaitingResponse = new Dictionary<string, Action<object>>();
|
||||
}
|
||||
|
||||
protected TSPlayer(String playerName)
|
||||
|
|
@ -499,8 +504,8 @@ namespace TShockAPI
|
|||
TilesCreated = new Dictionary<Vector2, Tile>();
|
||||
Index = -1;
|
||||
FakePlayer = new Player {name = playerName, whoAmi = -1};
|
||||
Group = Group.DefaultGroup;
|
||||
AwaitingResponse = new Dictionary<string, Action<object>>();
|
||||
Group = Group.DefaultGroup;
|
||||
AwaitingResponse = new Dictionary<string, Action<object>>();
|
||||
}
|
||||
|
||||
public virtual void Disconnect(string reason)
|
||||
|
|
@ -622,7 +627,6 @@ namespace TShockAPI
|
|||
|
||||
public void Spawn()
|
||||
{
|
||||
// TPlayer.FindSpawn();
|
||||
if (this.sX > 0 && this.sY > 0)
|
||||
{
|
||||
Spawn(this.sX, this.sY);
|
||||
|
|
@ -662,8 +666,8 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
public virtual bool SendTileSquare(int x, int y, int size = 10)
|
||||
{
|
||||
public virtual bool SendTileSquare(int x, int y, int size = 10)
|
||||
{
|
||||
try
|
||||
{
|
||||
int num = (size - 1)/2;
|
||||
|
|
@ -707,22 +711,22 @@ namespace TShockAPI
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
TShock.Log.Error(ex.ToString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool GiveItemCheck(int type, string name, int width, int height, int stack, int prefix = 0)
|
||||
{
|
||||
if ((TShock.Itembans.ItemIsBanned(name) && TShock.Config.PreventBannedItemSpawn) &&
|
||||
(TShock.Itembans.ItemIsBanned(name, this) || !TShock.Config.AllowAllowedGroupsToSpawnBannedItems))
|
||||
return false;
|
||||
public bool GiveItemCheck(int type, string name, int width, int height, int stack, int prefix = 0)
|
||||
{
|
||||
if ((TShock.Itembans.ItemIsBanned(name) && TShock.Config.PreventBannedItemSpawn) &&
|
||||
(TShock.Itembans.ItemIsBanned(name, this) || !TShock.Config.AllowAllowedGroupsToSpawnBannedItems))
|
||||
return false;
|
||||
|
||||
GiveItem(type,name,width,height,stack,prefix);
|
||||
return true;
|
||||
}
|
||||
GiveItem(type,name,width,height,stack,prefix);
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void GiveItem(int type, string name, int width, int height, int stack, int prefix = 0)
|
||||
public virtual void GiveItem(int type, string name, int width, int height, int stack, int prefix = 0)
|
||||
{
|
||||
int itemid = Item.NewItem((int) X, (int) Y, width, height, type, stack, true, prefix, true);
|
||||
|
||||
|
|
@ -730,7 +734,7 @@ namespace TShockAPI
|
|||
Main.item[itemid].SetDefaults(name);
|
||||
// The set default overrides the wet and stack set by NewItem
|
||||
Main.item[itemid].wet = Collision.WetCollision(Main.item[itemid].position, Main.item[itemid].width,
|
||||
Main.item[itemid].height);
|
||||
Main.item[itemid].height);
|
||||
Main.item[itemid].stack = stack;
|
||||
Main.item[itemid].owner = Index;
|
||||
Main.item[itemid].prefix = (byte) prefix;
|
||||
|
|
@ -740,50 +744,44 @@ namespace TShockAPI
|
|||
NetMessage.SendData((int)PacketTypes.ItemOwner, -1, -1, "", itemid, 0f, 0f, 0f);
|
||||
}
|
||||
|
||||
public virtual void SendInfoMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.Yellow);
|
||||
}
|
||||
|
||||
public void SendInfoMessage(string format, params object[] args)
|
||||
{
|
||||
SendInfoMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
public virtual void SendSuccessMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.Green);
|
||||
}
|
||||
|
||||
public void SendSuccessMessage(string format, params object[] args)
|
||||
{
|
||||
SendSuccessMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
public virtual void SendWarningMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.OrangeRed);
|
||||
}
|
||||
|
||||
public void SendWarningMessage(string format, params object[] args)
|
||||
{
|
||||
SendWarningMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
public virtual void SendErrorMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.Red);
|
||||
}
|
||||
|
||||
public void SendErrorMessage(string format, params object[] args)
|
||||
{
|
||||
SendErrorMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
[Obsolete("Use SendErrorMessage, SendInfoMessage, or SendWarningMessage, or a custom color instead.")]
|
||||
public virtual void SendMessage(string msg)
|
||||
public virtual void SendInfoMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, 0, 255, 0);
|
||||
SendMessage(msg, Color.Yellow);
|
||||
}
|
||||
|
||||
public void SendInfoMessage(string format, params object[] args)
|
||||
{
|
||||
SendInfoMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
public virtual void SendSuccessMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.Green);
|
||||
}
|
||||
|
||||
public void SendSuccessMessage(string format, params object[] args)
|
||||
{
|
||||
SendSuccessMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
public virtual void SendWarningMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.OrangeRed);
|
||||
}
|
||||
|
||||
public void SendWarningMessage(string format, params object[] args)
|
||||
{
|
||||
SendWarningMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
public virtual void SendErrorMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.Red);
|
||||
}
|
||||
|
||||
public void SendErrorMessage(string format, params object[] args)
|
||||
{
|
||||
SendErrorMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
public virtual void SendMessage(string msg, Color color)
|
||||
|
|
@ -796,10 +794,10 @@ namespace TShockAPI
|
|||
SendData(PacketTypes.ChatText, msg, 255, red, green, blue);
|
||||
}
|
||||
|
||||
public virtual void SendMessageFromPlayer(string msg, byte red, byte green, byte blue, int ply)
|
||||
{
|
||||
SendDataFromPlayer(PacketTypes.ChatText, ply, msg, red, green, blue, 0);
|
||||
}
|
||||
public virtual void SendMessageFromPlayer(string msg, byte red, byte green, byte blue, int ply)
|
||||
{
|
||||
SendDataFromPlayer(PacketTypes.ChatText, ply, msg, red, green, blue, 0);
|
||||
}
|
||||
|
||||
public virtual void DamagePlayer(int damage)
|
||||
{
|
||||
|
|
@ -836,11 +834,11 @@ namespace TShockAPI
|
|||
{
|
||||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
@ -849,7 +847,7 @@ namespace TShockAPI
|
|||
StackFrame frame = null;
|
||||
frame = trace.GetFrame(1);
|
||||
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)
|
||||
|
|
@ -857,7 +855,7 @@ namespace TShockAPI
|
|||
var time2 = (int) time;
|
||||
var launch = DateTime.UtcNow;
|
||||
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)
|
||||
{
|
||||
SendData(PacketTypes.NpcSpecial, number: Index, number2: 2f);
|
||||
|
|
@ -883,13 +881,13 @@ namespace TShockAPI
|
|||
NetMessage.SendData((int) msgType, Index, -1, text, number, number2, number3, number4, number5);
|
||||
}
|
||||
|
||||
public virtual void SendDataFromPlayer(PacketTypes msgType, int ply, string text = "", float number2 = 0f, float number3 = 0f, float number4 = 0f, int number5 = 0)
|
||||
{
|
||||
if (RealPlayer && !ConnectionAlive)
|
||||
return;
|
||||
public virtual void SendDataFromPlayer(PacketTypes msgType, int ply, string text = "", float number2 = 0f, float number3 = 0f, float number4 = 0f, int number5 = 0)
|
||||
{
|
||||
if (RealPlayer && !ConnectionAlive)
|
||||
return;
|
||||
|
||||
NetMessage.SendData((int) msgType, Index, -1, text, ply, number2, number3, number4, number5);
|
||||
}
|
||||
NetMessage.SendData((int) msgType, Index, -1, text, ply, number2, number3, number4, number5);
|
||||
}
|
||||
|
||||
public virtual void SendRawData(byte[] data)
|
||||
{
|
||||
|
|
@ -898,20 +896,20 @@ namespace TShockAPI
|
|||
NetMessage.SendBytes(Netplay.serverSock[Index], data, 0, data.Length, Netplay.serverSock[Index].ServerWriteCallBack, Netplay.serverSock[Index].networkStream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a command callback to a specified command string.
|
||||
/// </summary>
|
||||
/// <param name="name">The string representing the command i.e "yes" == /yes</param>
|
||||
/// <param name="callback">The method that will be executed on confirmation ie user accepts</param>
|
||||
public void AddResponse( string name, Action<object> callback)
|
||||
{
|
||||
if( AwaitingResponse.ContainsKey(name))
|
||||
{
|
||||
AwaitingResponse.Remove(name);
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds a command callback to a specified command string.
|
||||
/// </summary>
|
||||
/// <param name="name">The string representing the command i.e "yes" == /yes</param>
|
||||
/// <param name="callback">The method that will be executed on confirmation ie user accepts</param>
|
||||
public void AddResponse( string name, Action<object> callback)
|
||||
{
|
||||
if( AwaitingResponse.ContainsKey(name))
|
||||
{
|
||||
AwaitingResponse.Remove(name);
|
||||
}
|
||||
|
||||
AwaitingResponse.Add(name, callback);
|
||||
}
|
||||
AwaitingResponse.Add(name, callback);
|
||||
}
|
||||
}
|
||||
|
||||
public class TSRestPlayer : TSPlayer
|
||||
|
|
@ -924,11 +922,6 @@ namespace TShockAPI
|
|||
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)
|
||||
{
|
||||
SendMessage(msg, color.R, color.G, color.B);
|
||||
|
|
@ -967,45 +960,40 @@ namespace TShockAPI
|
|||
|
||||
public class TSServerPlayer : TSPlayer
|
||||
{
|
||||
public static string AccountName = "ServerConsole";
|
||||
public static string AccountName = "ServerConsole";
|
||||
public TSServerPlayer()
|
||||
: base("Server")
|
||||
{
|
||||
Group = new SuperAdminGroup();
|
||||
UserAccountName = AccountName;
|
||||
UserAccountName = AccountName;
|
||||
}
|
||||
|
||||
public override void SendErrorMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendInfoMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendSuccessMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendWarningMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendMessage(string msg)
|
||||
public override void SendErrorMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, 0, 255, 0);
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendInfoMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendSuccessMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendWarningMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendMessage(string msg, Color color)
|
||||
|
|
@ -1016,7 +1004,6 @@ namespace TShockAPI
|
|||
public override void SendMessage(string msg, byte red, byte green, byte blue)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
//RconHandler.Response += msg + "\n";
|
||||
}
|
||||
|
||||
public void SetFullMoon()
|
||||
|
|
@ -1093,7 +1080,7 @@ namespace TShockAPI
|
|||
int spawnTileX;
|
||||
int spawnTileY;
|
||||
TShock.Utils.GetRandomClearTileWithInRange(startTileX, startTileY, tileXRange, tileYRange, out spawnTileX,
|
||||
out spawnTileY);
|
||||
out spawnTileY);
|
||||
int npcid = NPC.NewNPC(spawnTileX*16, spawnTileY*16, type, 0);
|
||||
// This is for special slimes
|
||||
Main.npc[npcid].SetDefaults(name);
|
||||
|
|
@ -1407,19 +1394,19 @@ namespace TShockAPI
|
|||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[8].name, player.Index, 67f, (float)Main.player[player.Index].armor[8].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[9].name, player.Index, 68f, (float)Main.player[player.Index].armor[9].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[10].name, player.Index, 69f, (float)Main.player[player.Index].armor[10].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[11].name, player.Index, 70f, (float)Main.player[player.Index].armor[11].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[12].name, player.Index, 71f, (float)Main.player[player.Index].armor[12].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[13].name, player.Index, 72f, (float)Main.player[player.Index].armor[13].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[14].name, player.Index, 73f, (float)Main.player[player.Index].armor[14].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[15].name, player.Index, 74f, (float)Main.player[player.Index].armor[15].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[11].name, player.Index, 70f, (float)Main.player[player.Index].armor[11].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[12].name, player.Index, 71f, (float)Main.player[player.Index].armor[12].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[13].name, player.Index, 72f, (float)Main.player[player.Index].armor[13].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[14].name, player.Index, 73f, (float)Main.player[player.Index].armor[14].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[15].name, player.Index, 74f, (float)Main.player[player.Index].armor[15].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[0].name, player.Index, 75f, (float)Main.player[player.Index].dye[0].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[1].name, player.Index, 76f, (float)Main.player[player.Index].dye[1].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[2].name, player.Index, 77f, (float)Main.player[player.Index].dye[2].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[3].name, player.Index, 78f, (float)Main.player[player.Index].dye[3].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[4].name, player.Index, 79f, (float)Main.player[player.Index].dye[4].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[5].name, player.Index, 80f, (float)Main.player[player.Index].dye[5].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[6].name, player.Index, 81f, (float)Main.player[player.Index].dye[6].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[7].name, player.Index, 82f, (float)Main.player[player.Index].dye[7].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[3].name, player.Index, 78f, (float)Main.player[player.Index].dye[3].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[4].name, player.Index, 79f, (float)Main.player[player.Index].dye[4].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[5].name, player.Index, 80f, (float)Main.player[player.Index].dye[5].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[6].name, player.Index, 81f, (float)Main.player[player.Index].dye[6].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[7].name, player.Index, 82f, (float)Main.player[player.Index].dye[7].prefix, 0f, 0);
|
||||
NetMessage.SendData(4, -1, -1, player.Name, player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(42, -1, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(16, -1, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
|
|
@ -1428,30 +1415,31 @@ 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].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[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[3].name, player.Index, 62f, (float)Main.player[player.Index].armor[3].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[4].name, player.Index, 63f, (float)Main.player[player.Index].armor[4].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[5].name, player.Index, 64f, (float)Main.player[player.Index].armor[5].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[6].name, player.Index, 65f, (float)Main.player[player.Index].armor[6].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[7].name, player.Index, 66f, (float)Main.player[player.Index].armor[7].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[8].name, player.Index, 67f, (float)Main.player[player.Index].armor[8].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[9].name, player.Index, 68f, (float)Main.player[player.Index].armor[9].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[10].name, player.Index, 69f, (float)Main.player[player.Index].armor[10].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[11].name, player.Index, 70f, (float)Main.player[player.Index].armor[11].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[12].name, player.Index, 71f, (float)Main.player[player.Index].armor[12].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[13].name, player.Index, 72f, (float)Main.player[player.Index].armor[13].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[14].name, player.Index, 73f, (float)Main.player[player.Index].armor[14].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[15].name, player.Index, 74f, (float)Main.player[player.Index].armor[15].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[0].name, player.Index, 75f, (float)Main.player[player.Index].dye[0].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[1].name, player.Index, 76f, (float)Main.player[player.Index].dye[1].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[2].name, player.Index, 77f, (float)Main.player[player.Index].dye[2].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[3].name, player.Index, 78f, (float)Main.player[player.Index].dye[3].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[4].name, player.Index, 79f, (float)Main.player[player.Index].dye[4].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[5].name, player.Index, 80f, (float)Main.player[player.Index].dye[5].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[6].name, player.Index, 81f, (float)Main.player[player.Index].dye[6].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[7].name, player.Index, 82f, (float)Main.player[player.Index].dye[7].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[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[3].name, player.Index, 62f, (float)Main.player[player.Index].armor[3].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[4].name, player.Index, 63f, (float)Main.player[player.Index].armor[4].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[5].name, player.Index, 64f, (float)Main.player[player.Index].armor[5].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[6].name, player.Index, 65f, (float)Main.player[player.Index].armor[6].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[7].name, player.Index, 66f, (float)Main.player[player.Index].armor[7].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[8].name, player.Index, 67f, (float)Main.player[player.Index].armor[8].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[9].name, player.Index, 68f, (float)Main.player[player.Index].armor[9].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[10].name, player.Index, 69f, (float)Main.player[player.Index].armor[10].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[11].name, player.Index, 70f, (float)Main.player[player.Index].armor[11].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[12].name, player.Index, 71f, (float)Main.player[player.Index].armor[12].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[13].name, player.Index, 72f, (float)Main.player[player.Index].armor[13].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[14].name, player.Index, 73f, (float)Main.player[player.Index].armor[14].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[15].name, player.Index, 74f, (float)Main.player[player.Index].armor[15].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[0].name, player.Index, 75f, (float)Main.player[player.Index].dye[0].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[1].name, player.Index, 76f, (float)Main.player[player.Index].dye[1].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[2].name, player.Index, 77f, (float)Main.player[player.Index].dye[2].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[3].name, player.Index, 78f, (float)Main.player[player.Index].dye[3].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[4].name, player.Index, 79f, (float)Main.player[player.Index].dye[4].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[5].name, player.Index, 80f, (float)Main.player[player.Index].dye[5].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[6].name, player.Index, 81f, (float)Main.player[player.Index].dye[6].prefix, 0f, 0);
|
||||
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[7].name, player.Index, 82f, (float)Main.player[player.Index].dye[7].prefix, 0f, 0);
|
||||
NetMessage.SendData(4, player.Index, -1, player.Name, player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(42, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
NetMessage.SendData(16, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0);
|
||||
|
|
|
|||
|
|
@ -36,29 +36,27 @@ using Terraria;
|
|||
using TerrariaApi.Server;
|
||||
using TShockAPI.DB;
|
||||
using TShockAPI.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using TShockAPI.ServerSideCharacters;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
[ApiVersion(1, 16)]
|
||||
[ApiVersion(1, 17)]
|
||||
public class TShock : TerrariaPlugin
|
||||
{
|
||||
public static readonly Version VersionNum = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
public static readonly string VersionCodename = "And the great beast rose from its slumber, ready to take on the world again.";
|
||||
public static readonly string VersionCodename = "2015!!";
|
||||
|
||||
public static string SavePath = "tshock";
|
||||
private const string LogFormatDefault = "yyyy-MM-dd_HH-mm-ss";
|
||||
private static string LogFormat = LogFormatDefault;
|
||||
private const string LogPathDefault = "tshock";
|
||||
private static string LogPath = LogPathDefault;
|
||||
private static bool LogClear = false;
|
||||
private static bool LogClear;
|
||||
|
||||
public static TSPlayer[] Players = new TSPlayer[Main.maxPlayers];
|
||||
public static BanManager Bans;
|
||||
public static WarpManager Warps;
|
||||
public static RegionManager Regions;
|
||||
public static RegionManager Regions;
|
||||
public static BackupManager Backups;
|
||||
public static GroupManager Groups;
|
||||
public static UserManager Users;
|
||||
|
|
@ -76,7 +74,9 @@ namespace TShockAPI
|
|||
public static SecureRest RestApi;
|
||||
public static RestManager RestManager;
|
||||
public static Utils Utils = Utils.Instance;
|
||||
public static StatTracker StatTracker = new StatTracker();
|
||||
public static UpdateManager UpdateManager;
|
||||
public static ILog Log;
|
||||
/// <summary>
|
||||
/// Used for implementing REST Tokens prior to the REST system starting up.
|
||||
/// </summary>
|
||||
|
|
@ -107,10 +107,6 @@ namespace TShockAPI
|
|||
get { return "The administration modification of the future."; }
|
||||
}
|
||||
|
||||
public override string UpdateURL
|
||||
{
|
||||
get { return ""; }
|
||||
}
|
||||
public TShock(Main game)
|
||||
: base(game)
|
||||
{
|
||||
|
|
@ -126,13 +122,13 @@ namespace TShockAPI
|
|||
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
|
||||
public override void Initialize()
|
||||
{
|
||||
string logFilename;
|
||||
string logPathSetupWarning;
|
||||
|
||||
try
|
||||
{
|
||||
HandleCommandLine(Environment.GetCommandLineArgs());
|
||||
|
||||
if (Version.Major >= 4)
|
||||
getTShockAscii();
|
||||
|
||||
if (!Directory.Exists(SavePath))
|
||||
Directory.CreateDirectory(SavePath);
|
||||
|
||||
|
|
@ -142,37 +138,29 @@ namespace TShockAPI
|
|||
Main.ServerSideCharacter = ServerSideCharacterConfig.Enabled;
|
||||
|
||||
DateTime now = DateTime.Now;
|
||||
string logFilename;
|
||||
string logPathSetupWarning = null;
|
||||
// Log path was not already set by the command line parameter?
|
||||
if (LogPath == LogPathDefault)
|
||||
LogPath = Config.LogPath;
|
||||
try
|
||||
{
|
||||
logFilename = Path.Combine(LogPath, now.ToString(LogFormat)+".log");
|
||||
logFilename = Path.Combine(LogPath, now.ToString(LogFormat) + ".log");
|
||||
if (!Directory.Exists(LogPath))
|
||||
Directory.CreateDirectory(LogPath);
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
logPathSetupWarning = "Could not apply the given log path / log format, defaults will be used. Exception details:\n" + ex;
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(logPathSetupWarning);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
logPathSetupWarning =
|
||||
"Could not apply the given log path / log format, defaults will be used. Exception details:\n" + ex;
|
||||
|
||||
ServerApi.LogWriter.PluginWriteLine(this, logPathSetupWarning, TraceLevel.Error);
|
||||
|
||||
// Problem with the log path or format use the default
|
||||
logFilename = Path.Combine(LogPathDefault, now.ToString(LogFormatDefault) + ".log");
|
||||
}
|
||||
#if DEBUG
|
||||
Log.Initialize(logFilename, LogLevel.All, false);
|
||||
#else
|
||||
Log.Initialize(logFilename, LogLevel.All & ~LogLevel.Debug, LogClear);
|
||||
#endif
|
||||
if (logPathSetupWarning != null)
|
||||
Log.Warn(logPathSetupWarning);
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Will be handled by the server api and written to its crashlog.txt.
|
||||
throw new Exception("Fatal TShock initialization exception. See inner exception for details.", ex);
|
||||
|
|
@ -181,16 +169,6 @@ namespace TShockAPI
|
|||
// Further exceptions are written to TShock's log from now on.
|
||||
try
|
||||
{
|
||||
if (File.Exists(Path.Combine(SavePath, "tshock.pid")))
|
||||
{
|
||||
Log.ConsoleInfo(
|
||||
"TShock was improperly shut down. Please use the exit command in the future to prevent this.");
|
||||
File.Delete(Path.Combine(SavePath, "tshock.pid"));
|
||||
}
|
||||
File.WriteAllText(Path.Combine(SavePath, "tshock.pid"), Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
HandleCommandLinePostConfigLoad(Environment.GetCommandLineArgs());
|
||||
|
||||
if (Config.StorageType.ToLower() == "sqlite")
|
||||
{
|
||||
string sql = Path.Combine(SavePath, "tshock.sqlite");
|
||||
|
|
@ -204,16 +182,16 @@ namespace TShockAPI
|
|||
DB = new MySqlConnection();
|
||||
DB.ConnectionString =
|
||||
String.Format("Server={0}; Port={1}; Database={2}; Uid={3}; Pwd={4};",
|
||||
hostport[0],
|
||||
hostport.Length > 1 ? hostport[1] : "3306",
|
||||
Config.MySqlDbName,
|
||||
Config.MySqlUsername,
|
||||
Config.MySqlPassword
|
||||
hostport[0],
|
||||
hostport.Length > 1 ? hostport[1] : "3306",
|
||||
Config.MySqlDbName,
|
||||
Config.MySqlUsername,
|
||||
Config.MySqlPassword
|
||||
);
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
ServerApi.LogWriter.PluginWriteLine(this, ex.ToString(), TraceLevel.Error);
|
||||
throw new Exception("MySql not setup correctly");
|
||||
}
|
||||
}
|
||||
|
|
@ -222,12 +200,33 @@ namespace TShockAPI
|
|||
throw new Exception("Invalid storage type");
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
var level = LogLevel.All;
|
||||
#else
|
||||
var level = LogLevel.All & ~LogLevel.Debug;
|
||||
#endif
|
||||
if (Config.UseSqlLogs)
|
||||
Log = new SqlLog(level, DB, logFilename, LogClear);
|
||||
else
|
||||
Log = new TextLog(logFilename, level, LogClear);
|
||||
|
||||
if (File.Exists(Path.Combine(SavePath, "tshock.pid")))
|
||||
{
|
||||
Log.ConsoleInfo(
|
||||
"TShock was improperly shut down. Please use the exit command in the future to prevent this.");
|
||||
File.Delete(Path.Combine(SavePath, "tshock.pid"));
|
||||
}
|
||||
File.WriteAllText(Path.Combine(SavePath, "tshock.pid"),
|
||||
Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
HandleCommandLinePostConfigLoad(Environment.GetCommandLineArgs());
|
||||
|
||||
Backups = new BackupManager(Path.Combine(SavePath, "backups"));
|
||||
Backups.KeepFor = Config.BackupKeepFor;
|
||||
Backups.Interval = Config.BackupInterval;
|
||||
Bans = new BanManager(DB);
|
||||
Warps = new WarpManager(DB);
|
||||
Regions = new RegionManager(DB);
|
||||
Regions = new RegionManager(DB);
|
||||
Users = new UserManager(DB);
|
||||
Groups = new GroupManager(DB);
|
||||
Itembans = new ItemManager(DB);
|
||||
|
|
@ -244,7 +243,7 @@ namespace TShockAPI
|
|||
if (Config.EnableGeoIP && File.Exists(geoippath))
|
||||
Geo = new GeoIPCountry(geoippath);
|
||||
|
||||
Log.ConsoleInfo(string.Format("|> Version {0} ({1}) now running.", Version, VersionCodename));
|
||||
Log.ConsoleInfo("TShock {0} ({1}) now running.", Version, VersionCodename);
|
||||
|
||||
ServerApi.Hooks.GamePostInitialize.Register(this, OnPostInit);
|
||||
ServerApi.Hooks.GameUpdate.Register(this, OnUpdate);
|
||||
|
|
@ -262,15 +261,16 @@ namespace TShockAPI
|
|||
ServerApi.Hooks.ProjectileSetDefaults.Register(this, OnProjectileSetDefaults);
|
||||
ServerApi.Hooks.WorldStartHardMode.Register(this, OnStartHardMode);
|
||||
ServerApi.Hooks.WorldSave.Register(this, SaveManager.Instance.OnSaveWorld);
|
||||
ServerApi.Hooks.WorldChristmasCheck.Register(this, OnXmasCheck);
|
||||
ServerApi.Hooks.WorldChristmasCheck.Register(this, OnXmasCheck);
|
||||
ServerApi.Hooks.WorldHalloweenCheck.Register(this, OnHalloweenCheck);
|
||||
ServerApi.Hooks.NetNameCollision.Register(this, NetHooks_NameCollision);
|
||||
TShockAPI.Hooks.PlayerHooks.PlayerPreLogin += OnPlayerPreLogin;
|
||||
TShockAPI.Hooks.PlayerHooks.PlayerPostLogin += OnPlayerLogin;
|
||||
Hooks.PlayerHooks.PlayerPreLogin += OnPlayerPreLogin;
|
||||
Hooks.PlayerHooks.PlayerPostLogin += OnPlayerLogin;
|
||||
Hooks.AccountHooks.AccountDelete += OnAccountDelete;
|
||||
Hooks.AccountHooks.AccountCreate += OnAccountCreate;
|
||||
|
||||
GetDataHandlers.InitGetDataHandler();
|
||||
Commands.InitCommands();
|
||||
//RconHandler.StartThread();
|
||||
|
||||
if (Config.RestApiEnabled)
|
||||
RestApi.Start();
|
||||
|
|
@ -283,6 +283,8 @@ namespace TShockAPI
|
|||
|
||||
if (Initialized != null)
|
||||
Initialized();
|
||||
|
||||
Log.ConsoleInfo("Welcome to TShock for Terraria. Initialization complete.");
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (disposing)
|
||||
|
|
@ -342,7 +325,7 @@ namespace TShockAPI
|
|||
ServerApi.Hooks.WorldChristmasCheck.Deregister(this, OnXmasCheck);
|
||||
ServerApi.Hooks.WorldHalloweenCheck.Deregister(this, OnHalloweenCheck);
|
||||
ServerApi.Hooks.NetNameCollision.Deregister(this, NetHooks_NameCollision);
|
||||
TShockAPI.Hooks.PlayerHooks.PlayerPostLogin -= OnPlayerLogin;
|
||||
TShockAPI.Hooks.PlayerHooks.PlayerPostLogin -= OnPlayerLogin;
|
||||
|
||||
if (File.Exists(Path.Combine(SavePath, "tshock.pid")))
|
||||
{
|
||||
|
|
@ -379,6 +362,16 @@ namespace TShockAPI
|
|||
Users.UpdateLogin(u);
|
||||
}
|
||||
|
||||
private void OnAccountDelete(Hooks.AccountDeleteEventArgs args)
|
||||
{
|
||||
CharacterDB.RemovePlayer(args.User.ID);
|
||||
}
|
||||
|
||||
private void OnAccountCreate(Hooks.AccountCreateEventArgs args)
|
||||
{
|
||||
CharacterDB.SeedInitialData(Users.GetUser(args.User));
|
||||
}
|
||||
|
||||
private void OnPlayerPreLogin(Hooks.PlayerPreLoginEventArgs args)
|
||||
{
|
||||
if (args.Player.IsLoggedIn)
|
||||
|
|
@ -418,17 +411,17 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
private void OnXmasCheck(ChristmasCheckEventArgs args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
private void OnXmasCheck(ChristmasCheckEventArgs args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if(Config.ForceXmas)
|
||||
{
|
||||
args.Xmas = true;
|
||||
args.Handled = true;
|
||||
}
|
||||
if(Config.ForceXmas)
|
||||
{
|
||||
args.Xmas = true;
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHalloweenCheck(HalloweenCheckEventArgs args)
|
||||
{
|
||||
|
|
@ -572,14 +565,14 @@ namespace TShockAPI
|
|||
|
||||
private void OnPostInit(EventArgs args)
|
||||
{
|
||||
SetConsoleTitle();
|
||||
SetConsoleTitle(false);
|
||||
if (!File.Exists(Path.Combine(SavePath, "auth.lck")) && !File.Exists(Path.Combine(SavePath, "authcode.txt")))
|
||||
{
|
||||
var r = new Random((int) DateTime.Now.ToBinary());
|
||||
AuthToken = r.Next(100000, 10000000);
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine("TShock Notice: To become SuperAdmin, join the game and type /auth " + AuthToken);
|
||||
Console.WriteLine("This token will display until disabled by verification. (/auth-verify)");
|
||||
Console.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. ({0}auth-verify)", Commands.Specifier);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
FileTools.CreateFile(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.WriteLine(
|
||||
"TShock Notice: authcode.txt is still present, and the AuthToken located in that file will be used.");
|
||||
Console.WriteLine("To become superadmin, join the game and type /auth " + AuthToken);
|
||||
Console.WriteLine("This token will display until disabled by verification. (/auth-verify)");
|
||||
Console.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. ({0}auth-verify)", Commands.Specifier);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
else
|
||||
|
|
@ -613,6 +606,7 @@ namespace TShockAPI
|
|||
FixChestStacks();
|
||||
|
||||
UpdateManager = new UpdateManager();
|
||||
StatTracker.Initialize();
|
||||
}
|
||||
|
||||
private void ComputeMaxStyles()
|
||||
|
|
@ -811,7 +805,7 @@ namespace TShockAPI
|
|||
player.SetBuff(36, 120); //Broken Armor
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -824,16 +818,32 @@ namespace TShockAPI
|
|||
{
|
||||
player.SetBuff(23, 120); //Cursed
|
||||
}
|
||||
|
||||
var oldRegion = player.CurrentRegion;
|
||||
player.CurrentRegion = Regions.GetTopRegion(Regions.InAreaRegion(player.TileX, player.TileY));
|
||||
|
||||
if (oldRegion != player.CurrentRegion)
|
||||
{
|
||||
if (oldRegion != null)
|
||||
{
|
||||
Hooks.RegionHooks.OnRegionLeft(player, oldRegion);
|
||||
}
|
||||
|
||||
if (player.CurrentRegion != null)
|
||||
{
|
||||
Hooks.RegionHooks.OnRegionEntered(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SetConsoleTitle();
|
||||
SetConsoleTitle(false);
|
||||
}
|
||||
|
||||
private void SetConsoleTitle()
|
||||
private void SetConsoleTitle(bool empty)
|
||||
{
|
||||
Console.Title = string.Format("{0}{1}/{2} @ {3}:{4} (TerrariaShock v{5})",
|
||||
Console.Title = string.Format("{0}{1}/{2} @ {3}:{4} (TShock for Terraria v{5})",
|
||||
!string.IsNullOrWhiteSpace(Config.ServerName) ? Config.ServerName + " - " : "",
|
||||
Utils.ActivePlayers(),
|
||||
empty ? 0 : Utils.ActivePlayers(),
|
||||
Config.MaxSlots, Netplay.serverListenIP, Netplay.serverPort, Version);
|
||||
}
|
||||
|
||||
|
|
@ -997,7 +1007,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (!tsplr.SilentKickInProgress && tsplr.State >= 3)
|
||||
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))
|
||||
{
|
||||
|
|
@ -1010,6 +1020,14 @@ namespace TShockAPI
|
|||
RememberedPos.InsertLeavePos(tsplr.Name, tsplr.IP, (int) (tsplr.X/16), (int) (tsplr.Y/16));
|
||||
}
|
||||
}
|
||||
|
||||
// The last player will leave after this hook is executed.
|
||||
if (Utils.ActivePlayers() == 1)
|
||||
{
|
||||
if (Config.SaveWorldOnLastPlayerExit)
|
||||
SaveManager.Instance.SaveWorld();
|
||||
SetConsoleTitle(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnChat(ServerChatEventArgs args)
|
||||
|
|
@ -1037,7 +1055,8 @@ namespace TShockAPI
|
|||
return;
|
||||
}*/
|
||||
|
||||
if (args.Text.StartsWith(Config.CommandSpecifier) && !string.IsNullOrWhiteSpace(args.Text.Substring(1)))
|
||||
if ((args.Text.StartsWith(Config.CommandSpecifier) || args.Text.StartsWith(Config.CommandSilentSpecifier))
|
||||
&& !string.IsNullOrWhiteSpace(args.Text.Substring(1)))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -1045,7 +1064,7 @@ namespace TShockAPI
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ConsoleError("Command exception");
|
||||
Log.ConsoleError("An exeption occurred executing a command.");
|
||||
Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
|
@ -1087,7 +1106,7 @@ namespace TShockAPI
|
|||
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);
|
||||
Log.Info(string.Format("Broadcast: {0}", msg));
|
||||
Log.Info("Broadcast: {0}", msg);
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1113,7 +1132,7 @@ namespace TShockAPI
|
|||
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;
|
||||
foreach (TSPlayer player in Players)
|
||||
|
|
@ -1121,18 +1140,18 @@ namespace TShockAPI
|
|||
if (player != null && player.Active)
|
||||
{
|
||||
count++;
|
||||
TSPlayer.Server.SendInfoMessage(string.Format("{0} ({1}) [{2}] <{3}>", player.Name, player.IP,
|
||||
player.Group.Name, player.UserAccountName));
|
||||
TSPlayer.Server.SendInfoMessage("{0} ({1}) [{2}] <{3}>", player.Name, player.IP,
|
||||
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")
|
||||
{
|
||||
Main.autoSave = Config.AutoSave = !Config.AutoSave;
|
||||
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);
|
||||
}
|
||||
|
|
@ -1190,24 +1209,24 @@ namespace TShockAPI
|
|||
|
||||
player.LoginMS = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
|
||||
if (TShock.Config.EnableGeoIP && TShock.Geo != null)
|
||||
if (Config.EnableGeoIP && TShock.Geo != null)
|
||||
{
|
||||
Log.Info(string.Format("{0} ({1}) from '{2}' group from '{3}' joined. ({4}/{5})", player.Name, player.IP,
|
||||
Log.Info("{0} ({1}) from '{2}' group from '{3}' joined. ({4}/{5})", player.Name, player.IP,
|
||||
player.Group.Name, player.Country, TShock.Utils.ActivePlayers(),
|
||||
TShock.Config.MaxSlots));
|
||||
TShock.Config.MaxSlots);
|
||||
if (!player.SilentJoinInProgress)
|
||||
TShock.Utils.Broadcast(string.Format("{0} ({1}) has joined.", player.Name, player.Country), Color.Yellow);
|
||||
Utils.Broadcast(string.Format("{0} ({1}) has joined.", player.Name, player.Country), Color.Yellow);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Info(string.Format("{0} ({1}) from '{2}' group joined. ({3}/{4})", player.Name, player.IP,
|
||||
player.Group.Name, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots));
|
||||
Log.Info("{0} ({1}) from '{2}' group joined. ({3}/{4})", player.Name, player.IP,
|
||||
player.Group.Name, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots);
|
||||
if (!player.SilentJoinInProgress)
|
||||
TShock.Utils.Broadcast(player.Name + " has joined.", Color.Yellow);
|
||||
Utils.Broadcast(player.Name + " has joined.", Color.Yellow);
|
||||
}
|
||||
|
||||
if (TShock.Config.DisplayIPToAdmins)
|
||||
TShock.Utils.SendLogs(string.Format("{0} has joined. IP: {1}", player.Name, player.IP), Color.Blue);
|
||||
if (Config.DisplayIPToAdmins)
|
||||
Utils.SendLogs(string.Format("{0} has joined. IP: {1}", player.Name, player.IP), Color.Blue);
|
||||
|
||||
Utils.ShowFileToUser(player, "motd.txt");
|
||||
|
||||
|
|
@ -1223,14 +1242,13 @@ namespace TShockAPI
|
|||
{
|
||||
if (Main.ServerSideCharacter)
|
||||
{
|
||||
player.SendMessage(
|
||||
player.IgnoreActionsForInventory = "Server side characters is enabled! Please /register or /login to play!",
|
||||
Color.Red);
|
||||
player.SendErrorMessage(
|
||||
player.IgnoreActionsForInventory = "Server side characters is enabled! Please {0}register or {0}login to play!", Commands.Specifier);
|
||||
player.LoginHarassed = true;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1240,7 +1258,7 @@ namespace TShockAPI
|
|||
if (Config.RememberLeavePos && (RememberedPos.GetLeavePos(player.Name, player.IP) != Vector2.Zero) && !player.LoginHarassed)
|
||||
{
|
||||
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;
|
||||
|
|
@ -1552,7 +1570,7 @@ namespace TShockAPI
|
|||
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1566,7 +1584,7 @@ namespace TShockAPI
|
|||
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1577,7 +1595,7 @@ namespace TShockAPI
|
|||
{
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1589,7 +1607,7 @@ namespace TShockAPI
|
|||
{
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1604,7 +1622,7 @@ namespace TShockAPI
|
|||
{
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1621,7 +1639,7 @@ namespace TShockAPI
|
|||
{
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1632,7 +1650,7 @@ namespace TShockAPI
|
|||
{
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1644,7 +1662,7 @@ namespace TShockAPI
|
|||
{
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1659,7 +1677,7 @@ namespace TShockAPI
|
|||
{
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1778,9 +1796,6 @@ namespace TShockAPI
|
|||
Netplay.password = "";
|
||||
Netplay.spamCheck = false;
|
||||
|
||||
RconHandler.Password = file.RconPassword;
|
||||
RconHandler.ListenPort = file.RconPort;
|
||||
|
||||
Utils.HashAlgo = file.HashAlgorithm;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Debug\TShockAPI.XML</DocumentationFile>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<NoWarn>1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
|
|
@ -78,6 +79,11 @@
|
|||
<Compile Include="Hooks\AccountHooks.cs" />
|
||||
<Compile Include="Hooks\GeneralHooks.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="Rest\RestPermissions.cs" />
|
||||
<Compile Include="SaveManager.cs" />
|
||||
|
|
@ -102,7 +108,6 @@
|
|||
<Compile Include="GetDataHandlers.cs" />
|
||||
<Compile Include="Group.cs" />
|
||||
<Compile Include="Extensions\LinqExt.cs" />
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="Net\BaseMsg.cs" />
|
||||
<Compile Include="Net\DisconnectMsg.cs" />
|
||||
<Compile Include="Net\NetTile.cs" />
|
||||
|
|
@ -111,7 +116,6 @@
|
|||
<Compile Include="Net\WorldInfoMsg.cs" />
|
||||
<Compile Include="PacketBufferer.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="RconHandler.cs" />
|
||||
<Compile Include="DB\RememberedPosManager.cs" />
|
||||
<Compile Include="Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
|
|
@ -182,7 +186,7 @@
|
|||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
<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>
|
||||
</ProjectExtensions>
|
||||
<!-- 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)
|
||||
{
|
||||
Log.ConsoleError("UpdateManager Exception: {0}", e);
|
||||
TShock.Log.ConsoleError("UpdateManager Exception: {0}", e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,17 +35,17 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
public class Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// The lowest id for a prefix.
|
||||
/// </summary>
|
||||
private const int FirstItemPrefix = 1;
|
||||
/// <summary>
|
||||
/// The lowest id for a prefix.
|
||||
/// </summary>
|
||||
private const int FirstItemPrefix = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The highest id for a prefix.
|
||||
/// </summary>
|
||||
private const int LastItemPrefix = 83;
|
||||
/// <summary>
|
||||
/// The highest id for a prefix.
|
||||
/// </summary>
|
||||
private const int LastItemPrefix = 83;
|
||||
|
||||
// Utils is a Singleton
|
||||
// Utils is a Singleton
|
||||
private static readonly Utils instance = new Utils();
|
||||
private Utils() {}
|
||||
public static Utils Instance { get { return instance; } }
|
||||
|
|
@ -67,7 +67,7 @@ namespace TShockAPI
|
|||
/// Used for some places where a list of players might be used.
|
||||
/// </summary>
|
||||
/// <returns>String of players seperated by commas.</returns>
|
||||
[Obsolete("Use GetPlayers and manually create strings. This should never have been kept as far as actual functions go.")]
|
||||
[Obsolete("Use GetPlayers and manually create strings. This should never have been kept as far as actual functions go.")]
|
||||
public string GetPlayers()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
|
@ -85,56 +85,56 @@ namespace TShockAPI
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of current players on the server
|
||||
/// </summary>
|
||||
/// <param name="includeIDs">bool includeIDs - whether or not the string of each player name should include ID data</param>
|
||||
/// <returns>List of strings with names</returns>
|
||||
public List<string> GetPlayers(bool includeIDs)
|
||||
{
|
||||
var players = new List<string>();
|
||||
/// <summary>
|
||||
/// Returns a list of current players on the server
|
||||
/// </summary>
|
||||
/// <param name="includeIDs">bool includeIDs - whether or not the string of each player name should include ID data</param>
|
||||
/// <returns>List of strings with names</returns>
|
||||
public List<string> GetPlayers(bool includeIDs)
|
||||
{
|
||||
var players = new List<string>();
|
||||
|
||||
foreach (TSPlayer ply in TShock.Players)
|
||||
{
|
||||
if (ply != null && ply.Active)
|
||||
{
|
||||
if (includeIDs)
|
||||
{
|
||||
players.Add(ply.Name + " (IX: " + ply.Index + ", ID: " + ply.UserID + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
players.Add(ply.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (TSPlayer ply in TShock.Players)
|
||||
{
|
||||
if (ply != null && ply.Active)
|
||||
{
|
||||
if (includeIDs)
|
||||
{
|
||||
players.Add(ply.Name + " (IX: " + ply.Index + ", ID: " + ply.UserID + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
players.Add(ply.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used for some places where a list of players might be used.
|
||||
/// </summary>
|
||||
/// <returns>String of players and their id seperated by commas.</returns>
|
||||
[Obsolete("Use GetPlayers and manually create strings. This should never have been kept as far as actual functions go.")]
|
||||
public string GetPlayersWithIds()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
{
|
||||
if (player != null && player.Active)
|
||||
{
|
||||
if (sb.Length != 0)
|
||||
{
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Append(player.Name);
|
||||
string id = "(ID: " + Convert.ToString(TShock.Users.GetUserID(player.UserAccountName)) + ", IX:" + player.Index + ")";
|
||||
sb.Append(id);
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
/// <summary>
|
||||
/// Used for some places where a list of players might be used.
|
||||
/// </summary>
|
||||
/// <returns>String of players and their id seperated by commas.</returns>
|
||||
[Obsolete("Use GetPlayers and manually create strings. This should never have been kept as far as actual functions go.")]
|
||||
public string GetPlayersWithIds()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
{
|
||||
if (player != null && player.Active)
|
||||
{
|
||||
if (sb.Length != 0)
|
||||
{
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Append(player.Name);
|
||||
string id = "(ID: " + Convert.ToString(TShock.Users.GetUserID(player.UserAccountName)) + ", IX:" + player.Index + ")";
|
||||
sb.Append(id);
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a player and gets IP as string
|
||||
|
|
@ -182,21 +182,11 @@ namespace TShockAPI
|
|||
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)
|
||||
{
|
||||
TSPlayer.All.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)
|
||||
|
|
@ -204,20 +194,20 @@ namespace TShockAPI
|
|||
Broadcast(msg, color.R, color.G, color.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts a message from a player, not TShock
|
||||
/// </summary>
|
||||
/// <param name="ply">TSPlayer ply - the player that will send the packet</param>
|
||||
/// <param name="msg">string msg - the message</param>
|
||||
/// <param name="red">r</param>
|
||||
/// <param name="green">g</param>
|
||||
/// <param name="blue">b</param>
|
||||
public void Broadcast(int ply, string msg, byte red, byte green, byte blue)
|
||||
{
|
||||
TSPlayer.All.SendMessageFromPlayer(msg, red, green, blue, ply);
|
||||
TSPlayer.Server.SendMessage(Main.player[ply].name + ": " + msg, red, green, blue);
|
||||
Log.Info(string.Format("Broadcast: {0}", Main.player[ply].name + ": " + msg));
|
||||
}
|
||||
/// <summary>
|
||||
/// Broadcasts a message from a player, not TShock
|
||||
/// </summary>
|
||||
/// <param name="ply">TSPlayer ply - the player that will send the packet</param>
|
||||
/// <param name="msg">string msg - the message</param>
|
||||
/// <param name="red">r</param>
|
||||
/// <param name="green">g</param>
|
||||
/// <param name="blue">b</param>
|
||||
public void Broadcast(int ply, string msg, byte red, byte green, byte blue)
|
||||
{
|
||||
TSPlayer.All.SendMessageFromPlayer(msg, red, green, blue, ply);
|
||||
TSPlayer.Server.SendMessage(Main.player[ply].name + ": " + msg, red, green, blue);
|
||||
TShock.Log.Info(string.Format("Broadcast: {0}", Main.player[ply].name + ": " + msg));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends message to all players with 'logs' permission.
|
||||
|
|
@ -227,12 +217,12 @@ namespace TShockAPI
|
|||
/// <param name="excludedPlayer">The player to not send the message to.</param>
|
||||
public void SendLogs(string log, Color color, TSPlayer excludedPlayer = null)
|
||||
{
|
||||
Log.Info(log);
|
||||
TShock.Log.Info(log);
|
||||
TSPlayer.Server.SendMessage(log, color);
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
{
|
||||
if (player != null && player != excludedPlayer && player.Active && player.Group.HasPermission(Permissions.logs) &&
|
||||
player.DisplayLogs && TShock.Config.DisableSpewLogs == false)
|
||||
player.DisplayLogs && TShock.Config.DisableSpewLogs == false)
|
||||
player.SendMessage(log, color);
|
||||
}
|
||||
}
|
||||
|
|
@ -293,7 +283,7 @@ namespace TShockAPI
|
|||
/// <param name="tileX">X location</param>
|
||||
/// <param name="tileY">Y location</param>
|
||||
public void GetRandomClearTileWithInRange(int startTileX, int startTileY, int tileXRange, int tileYRange,
|
||||
out int tileX, out int tileY)
|
||||
out int tileX, out int tileY)
|
||||
{
|
||||
int j = 0;
|
||||
do
|
||||
|
|
@ -509,8 +499,8 @@ namespace TShockAPI
|
|||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// <summary>
|
||||
/// Gets a prefix by ID or name
|
||||
/// </summary>
|
||||
/// <param name="idOrName">ID or name</param>
|
||||
|
|
@ -593,13 +583,6 @@ namespace TShockAPI
|
|||
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>
|
||||
/// Kicks a player from the server without checking for immunetokick permission.
|
||||
/// </summary>
|
||||
|
|
@ -611,13 +594,6 @@ namespace TShockAPI
|
|||
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>
|
||||
/// Kicks a player from the server..
|
||||
/// </summary>
|
||||
|
|
@ -635,30 +611,23 @@ namespace TShockAPI
|
|||
{
|
||||
string playerName = player.Name;
|
||||
player.SilentKickInProgress = silent;
|
||||
if (player.IsLoggedIn && saveSSI)
|
||||
player.SaveServerCharacter();
|
||||
if (player.IsLoggedIn && saveSSI)
|
||||
player.SaveServerCharacter();
|
||||
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 " : "";
|
||||
if (!silent)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(adminUserName))
|
||||
Broadcast(string.Format("{0} was {1}kicked for '{2}'", playerName, verb, reason.ToLower()), Color.Green);
|
||||
else
|
||||
if (!silent)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(adminUserName))
|
||||
Broadcast(string.Format("{0} was {1}kicked for '{2}'", playerName, verb, reason.ToLower()), Color.Green);
|
||||
else
|
||||
Broadcast(string.Format("{0} {1}kicked {2} for '{3}'", adminUserName, verb, playerName, reason.ToLower()), Color.Green);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
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>
|
||||
/// Bans and kicks a player from the server.
|
||||
/// </summary>
|
||||
|
|
@ -687,28 +656,28 @@ namespace TShockAPI
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool HasBanExpired(Ban ban, bool byName = false)
|
||||
{
|
||||
DateTime exp;
|
||||
bool expirationExists = DateTime.TryParse(ban.Expiration, out exp);
|
||||
public bool HasBanExpired(Ban ban, bool byName = false)
|
||||
{
|
||||
DateTime exp;
|
||||
bool expirationExists = DateTime.TryParse(ban.Expiration, out exp);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(ban.Expiration) && (expirationExists) &&
|
||||
(DateTime.UtcNow >= exp))
|
||||
{
|
||||
if (byName)
|
||||
{
|
||||
TShock.Bans.RemoveBan(ban.Name, true, true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
TShock.Bans.RemoveBan(ban.IP, false, false, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(ban.Expiration) && (expirationExists) &&
|
||||
(DateTime.UtcNow >= exp))
|
||||
{
|
||||
if (byName)
|
||||
{
|
||||
TShock.Bans.RemoveBan(ban.Name, true, true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
TShock.Bans.RemoveBan(ban.IP, false, false, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows a file to the user.
|
||||
|
|
@ -762,7 +731,7 @@ namespace TShockAPI
|
|||
return TShock.Groups.groups[i];
|
||||
}
|
||||
}
|
||||
return Group.DefaultGroup;
|
||||
return Group.DefaultGroup;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -796,23 +765,23 @@ namespace TShockAPI
|
|||
ply.SendErrorMessage("Use \"my query\" for items with spaces");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default hashing algorithm.
|
||||
/// </summary>
|
||||
public string HashAlgo = "sha512";
|
||||
/// <summary>
|
||||
/// Default hashing algorithm.
|
||||
/// </summary>
|
||||
public string HashAlgo = "sha512";
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary of hashing algortihms and an implementation object.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// A dictionary of hashing algortihms and an implementation object.
|
||||
/// </summary>
|
||||
public readonly Dictionary<string, Func<HashAlgorithm>> HashTypes = new Dictionary<string, Func<HashAlgorithm>>
|
||||
{
|
||||
{"sha512", () => new SHA512Managed()},
|
||||
{"sha256", () => new SHA256Managed()},
|
||||
{"md5", () => new MD5Cng()},
|
||||
{"sha512-xp", () => SHA512.Create()},
|
||||
{"sha256-xp", () => SHA256.Create()},
|
||||
{"md5-xp", () => MD5.Create()},
|
||||
};
|
||||
{
|
||||
{"sha512", () => new SHA512Managed()},
|
||||
{"sha256", () => new SHA256Managed()},
|
||||
{"md5", () => new MD5Cng()},
|
||||
{"sha512-xp", () => SHA512.Create()},
|
||||
{"sha256-xp", () => SHA256.Create()},
|
||||
{"md5-xp", () => MD5.Create()},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Returns a Sha256 string for a given string
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 50a04c45bfc2d1de2de1a31b215f7bdc546cfdd5
|
||||
Subproject commit f4075507475be946870a83d65a14cb5ae2c348cf
|
||||
|
|
@ -2,31 +2,48 @@ import requests
|
|||
import json
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
create_release_url = 'https://api.github.com/repos/NyxStudios/TShock/releases'
|
||||
release_name = 'tshock_release.zip'
|
||||
|
||||
#Load variables from ENV, which are put there by the bamboo build.
|
||||
branch = os.environ["GIT_BRANCH"]
|
||||
tag_name = os.environ["bamboo_tag_name"]
|
||||
name = os.environ["bamboo_release_name"]
|
||||
body = os.environ["bamboo_release_body"]
|
||||
|
||||
#build release file name using the tag, stripping the 'v' off the front ie 'v.1.2.3' => '.1.2.3' resulting in a file called 'tshock.1.2.3.zip'
|
||||
release_name = 'tshock_' + tag_name[1:] + '.zip'
|
||||
|
||||
#because we can't find any other secure way to get a token into this script run from bamboo :'(
|
||||
with open('/home/bamboo/scripts/token.py') as f:
|
||||
token = f.read().rsplit('=', 1)[1].strip()
|
||||
|
||||
body = 'This is the newest release for TShock. Please see the release thread for more information @ http://tshock.co/xf'
|
||||
#invoke the mv command on the artifact from bamboo to the new name above
|
||||
subprocess.call('mv tshock_release.zip ' + release_name, shell=True)
|
||||
|
||||
#construct the payload for the post request to github to create the release.
|
||||
data = {'tag_name':tag_name, 'target_commitish':branch, 'name':name, 'body':body, 'draft':False, 'prerelease':False}
|
||||
#headers for the post request with our oauth token, allowing us write access
|
||||
create_headers = {'Content-Type': 'application/json', 'Authorization': 'token ' + token}
|
||||
#payload is a json string, not a strong typed json object
|
||||
json_data = json.dumps(data)
|
||||
|
||||
#make the post request, creating a release
|
||||
r = requests.post(create_release_url, data=json_data, headers=create_headers)
|
||||
#parse the response into an object
|
||||
json_response = json.loads(r.text)
|
||||
|
||||
#extract the relevant information from the object needed to attach a binary to the release created previously
|
||||
release_id = json_response['id']
|
||||
upload_url = json_response['upload_url'].rsplit('{')[0]
|
||||
|
||||
#construct the post url using the release name, as that is required by the api
|
||||
upload_url = upload_url + '?name=' + release_name
|
||||
|
||||
#headers for the post request, need to specify that our file is a zip, and how large it is
|
||||
upload_headers = {'Authorization': 'token ' + token, 'Content-Type':'application/zip', 'Content-Length':str(os.path.getsize(release_name))}
|
||||
|
||||
#upload the binary, resulting in a complete binary
|
||||
r = requests.post(upload_url, data=open(release_name, 'rb'), headers = upload_headers, verify=False)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue