Merge pull request #1591 from Pryaxis/oop

Fragments: Clean up the Utils.cs file.
This commit is contained in:
Chris 2018-01-01 06:47:46 +00:00 committed by GitHub
commit e39c9e9eb8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 326 additions and 392 deletions

View file

@ -67,6 +67,18 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
* All `GetDataHandlers` hooks now inherit from `GetDataHandledEventArgs` which includes a `TSPlayer` and a `MemoryStream` of raw data. (@hakusaro) * All `GetDataHandlers` hooks now inherit from `GetDataHandledEventArgs` which includes a `TSPlayer` and a `MemoryStream` of raw data. (@hakusaro)
* Removed _all obsolete methods in TShock marked obsolete prior to this version (all of them)_ (@hakusaro). * Removed _all obsolete methods in TShock marked obsolete prior to this version (all of them)_ (@hakusaro).
* Removed broken noclip detection and attempted prevention. TShock wasn't doing a good job at stopping noclip. It's always worse to claim that you do something that you can't/don't do, so removing this is better than keeping broken detection in. (@hakusaro) * Removed broken noclip detection and attempted prevention. TShock wasn't doing a good job at stopping noclip. It's always worse to claim that you do something that you can't/don't do, so removing this is better than keeping broken detection in. (@hakusaro)
* Replaced `Utils.FindPlayer` with `TSPlayer.FindByNameOrID` to more appropriately be object orientated. (@hakusaro)
* Moved `Utils.Kick()` to `TSPlayer` since its first argument was a `TSPlayer` object. (@hakusaro)
* Removed `Utils.ForceKick()`. (@hakusaro)
* Removed `Utils.GetPlayerIP()`. (@hakusaro)
* Moved `Utils.Ban()` to `TSPlayer.Ban()`. (@hakusaro)
* Moved `Utils.SendMultipleMatchError()` to `TSPlayer.SendMultipleMatchError`. (@hakusaro)
* Removed `Utils.GetPlayers()`. Iterate over the TSPlayers on the server and make your own list.
* Removed `Utils.HasBanExpired()` and replaced with `Bans.RemoveBanIfExpired()`. (@hakusaro)
* Removed `Utils.SendFileToUser()` and replaced with `TSPlayer.SendFileTextAsMessage()`. (@hakusaro)
* Removed `Utils.GetGroup()` also have you seen `Groups.GetGroupByName()`? (@hakusaro)
* `Utils.MaxChests()` is now `Utils.HasWorldReachedMaxChests()`. (@hakusaro)
* `Utils.GetIPv4Address()` is now `Utils.GetIPv4AddressFromHostname()`. (@hakusaro)
## TShock 4.3.25 ## TShock 4.3.25
* Fixed a critical exploit in the Terraria protocol that could cause massive unpreventable world corruption as well as a number of other problems. Thanks to @bartico6 for reporting. Fixed by the efforts of @QuiCM, @hakusaro, and tips in the right directioon from @bartico6. * Fixed a critical exploit in the Terraria protocol that could cause massive unpreventable world corruption as well as a number of other problems. Thanks to @bartico6 for reporting. Fixed by the efforts of @QuiCM, @hakusaro, and tips in the right directioon from @bartico6.

View file

@ -77,7 +77,7 @@ namespace TShockAPI
if (String.IsNullOrEmpty(args.Player.Name)) if (String.IsNullOrEmpty(args.Player.Name))
{ {
TShock.Utils.ForceKick(args.Player, "Blank name.", true); args.Player.Kick("Your client sent a blank character name.", true, true);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -256,7 +256,7 @@ namespace TShockAPI
{ {
if (TShock.Config.KickOnDamageThresholdBroken) if (TShock.Config.KickOnDamageThresholdBroken)
{ {
TShock.Utils.Kick(args.Player, string.Format("NPC damage exceeded {0}.", TShock.Config.MaxDamage)); args.Player.Kick(string.Format("NPC damage exceeded {0}.", TShock.Config.MaxDamage));
args.Handled = true; args.Handled = true;
return; return;
} }
@ -313,7 +313,7 @@ namespace TShockAPI
{ {
if (TShock.Config.KickOnDamageThresholdBroken) if (TShock.Config.KickOnDamageThresholdBroken)
{ {
TShock.Utils.Kick(args.Player, string.Format("Player damage exceeded {0}.", TShock.Config.MaxDamage)); args.Player.Kick(string.Format("Player damage exceeded {0}.", TShock.Config.MaxDamage));
args.Handled = true; args.Handled = true;
return; return;
} }
@ -627,7 +627,7 @@ namespace TShockAPI
&& Main.tile[tileX, tileY].type != TileID.Containers && Main.tile[tileX, tileY].type != TileID.Containers
&& Main.tile[tileX, tileY].type != TileID.Dressers && Main.tile[tileX, tileY].type != TileID.Dressers
&& Main.tile[tileX, tileY].type != TileID.Containers2 && Main.tile[tileX, tileY].type != TileID.Containers2
&& (!TShock.Utils.MaxChests() && Main.tile[tileX, tileY].type != TileID.Dirt)) //Chest && (!TShock.Utils.HasWorldReachedMaxChests() && Main.tile[tileX, tileY].type != TileID.Dirt)) //Chest
{ {
args.Player.SendTileSquare(tileX, tileY, 3); args.Player.SendTileSquare(tileX, tileY, 3);
args.Handled = true; args.Handled = true;
@ -925,7 +925,7 @@ namespace TShockAPI
if (damage > 20000) //Abnormal values have the potential to cause infinite loops in the server. if (damage > 20000) //Abnormal values have the potential to cause infinite loops in the server.
{ {
TShock.Utils.ForceKick(args.Player, "Crash Exploit Attempt", true); args.Player.Kick("Failed to shade polygon normals.", true, true);
TShock.Log.ConsoleError("Death Exploit Attempt: Damage {0}", damage); TShock.Log.ConsoleError("Death Exploit Attempt: Damage {0}", damage);
args.Handled = true; args.Handled = true;
return; return;
@ -942,7 +942,7 @@ namespace TShockAPI
{ {
if (playerDeathReason.GetDeathText(TShock.Players[id].Name).ToString().Length > 500) if (playerDeathReason.GetDeathText(TShock.Players[id].Name).ToString().Length > 500)
{ {
TShock.Utils.Kick(TShock.Players[id], "Death reason outside of normal bounds.", true); TShock.Players[id].Kick("Death reason outside of normal bounds.", true);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1409,7 +1409,7 @@ namespace TShockAPI
} }
if (action == EditAction.PlaceTile && (editData == TileID.Containers || editData == TileID.Containers2)) if (action == EditAction.PlaceTile && (editData == TileID.Containers || editData == TileID.Containers2))
{ {
if (TShock.Utils.MaxChests()) if (TShock.Utils.HasWorldReachedMaxChests())
{ {
args.Player.SendErrorMessage("The world's chest limit has been reached - unable to place more."); args.Player.SendErrorMessage("The world's chest limit has been reached - unable to place more.");
args.Player.SendTileSquare(tileX, tileY, 3); args.Player.SendTileSquare(tileX, tileY, 3);

View file

@ -783,7 +783,7 @@ namespace TShockAPI
{ {
TShock.Log.Warn(String.Format("{0} ({1}) had {2} or more invalid login attempts and was kicked automatically.", TShock.Log.Warn(String.Format("{0} ({1}) had {2} or more invalid login attempts and was kicked automatically.",
args.Player.IP, args.Player.Name, TShock.Config.MaximumLoginAttempts)); args.Player.IP, args.Player.Name, TShock.Config.MaximumLoginAttempts));
TShock.Utils.Kick(args.Player, "Too many invalid login attempts."); args.Player.Kick("Too many invalid login attempts.");
return; return;
} }
@ -842,7 +842,7 @@ namespace TShockAPI
{ {
args.Player.PlayerData = TShock.CharacterDB.GetPlayerData(args.Player, account.ID); args.Player.PlayerData = TShock.CharacterDB.GetPlayerData(args.Player, account.ID);
var group = TShock.Utils.GetGroup(account.Group); var group = TShock.Groups.GetGroupByName(account.Group);
args.Player.Group = group; args.Player.Group = group;
args.Player.tempGroup = null; args.Player.tempGroup = null;
@ -1195,11 +1195,11 @@ namespace TShockAPI
return; return;
} }
var players = TShock.Utils.FindPlayer(args.Parameters[0]); var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count < 1) if (players.Count < 1)
args.Player.SendErrorMessage("Invalid player."); args.Player.SendErrorMessage("Invalid player.");
else if (players.Count > 1) else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else else
{ {
var message = new StringBuilder(); var message = new StringBuilder();
@ -1265,21 +1265,21 @@ namespace TShockAPI
} }
string plStr = args.Parameters[0]; string plStr = args.Parameters[0];
var players = TShock.Utils.FindPlayer(plStr); var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0) if (players.Count == 0)
{ {
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
} }
else if (players.Count > 1) else if (players.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
} }
else else
{ {
string reason = args.Parameters.Count > 1 string reason = args.Parameters.Count > 1
? String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1)) ? String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1))
: "Misbehaviour."; : "Misbehaviour.";
if (!TShock.Utils.Kick(players[0], reason, !args.Player.RealPlayer, false, args.Player.Name)) if (!players[0].Kick(reason, !args.Player.RealPlayer, false, args.Player.Name))
{ {
args.Player.SendErrorMessage("You can't kick another admin!"); args.Player.SendErrorMessage("You can't kick another admin!");
} }
@ -1308,7 +1308,7 @@ namespace TShockAPI
string targetGeneralizedName = ""; string targetGeneralizedName = "";
// Effective ban target assignment // Effective ban target assignment
List<TSPlayer> players = TShock.Utils.FindPlayer(args.Parameters[1]); List<TSPlayer> players = TSPlayer.FindByNameOrID(args.Parameters[1]);
UserAccount offlineUserAccount = TShock.UserAccounts.GetUserAccountByName(args.Parameters[1]); UserAccount offlineUserAccount = TShock.UserAccounts.GetUserAccountByName(args.Parameters[1]);
// Storage variable to determine if the command executor is the server console // Storage variable to determine if the command executor is the server console
@ -1355,7 +1355,7 @@ namespace TShockAPI
// Bad case: Players contains more than 1 person so we can't ban them // Bad case: Players contains more than 1 person so we can't ban them
if (players.Count > 1) if (players.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
return; return;
} }
@ -1658,7 +1658,7 @@ namespace TShockAPI
} }
string playerNameToMatch = string.Join(" ", args.Parameters); string playerNameToMatch = string.Join(" ", args.Parameters);
var matchedPlayers = TShock.Utils.FindPlayer(playerNameToMatch); var matchedPlayers = TSPlayer.FindByNameOrID(playerNameToMatch);
if (matchedPlayers.Count < 1) if (matchedPlayers.Count < 1)
{ {
args.Player.SendErrorMessage("No players matched \"{0}\".", playerNameToMatch); args.Player.SendErrorMessage("No players matched \"{0}\".", playerNameToMatch);
@ -1666,7 +1666,7 @@ namespace TShockAPI
} }
else if (matchedPlayers.Count > 1) else if (matchedPlayers.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, matchedPlayers.Select(p => p.Name)); args.Player.SendMultipleMatchError(matchedPlayers.Select(p => p.Name));
return; return;
} }
@ -1696,10 +1696,10 @@ namespace TShockAPI
TSPlayer targetPlayer = args.Player; TSPlayer targetPlayer = args.Player;
if (args.Parameters.Count == 1 && args.Player.HasPermission(Permissions.uploadothersdata)) if (args.Parameters.Count == 1 && args.Player.HasPermission(Permissions.uploadothersdata))
{ {
List<TSPlayer> players = TShock.Utils.FindPlayer(args.Parameters[0]); List<TSPlayer> players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count > 1) if (players.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
return; return;
} }
else if (players.Count == 0) else if (players.Count == 0)
@ -1777,7 +1777,7 @@ namespace TShockAPI
return; return;
} }
List<TSPlayer> ply = TShock.Utils.FindPlayer(args.Parameters[0]); List<TSPlayer> ply = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (ply.Count < 1) if (ply.Count < 1)
{ {
args.Player.SendErrorMessage("Could not find player {0}.", args.Parameters[0]); args.Player.SendErrorMessage("Could not find player {0}.", args.Parameters[0]);
@ -1786,7 +1786,7 @@ namespace TShockAPI
if (ply.Count > 1) if (ply.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, ply.Select(p => p.Account.Name)); args.Player.SendMultipleMatchError(ply.Select(p => p.Account.Name));
} }
if (!TShock.Groups.GroupExists(args.Parameters[1])) if (!TShock.Groups.GroupExists(args.Parameters[1]))
@ -1810,7 +1810,7 @@ namespace TShockAPI
ply[0].tempGroupTimer.Start(); ply[0].tempGroupTimer.Start();
} }
Group g = TShock.Utils.GetGroup(args.Parameters[1]); Group g = TShock.Groups.GetGroupByName(args.Parameters[1]);
ply[0].tempGroup = g; ply[0].tempGroup = g;
@ -2326,7 +2326,7 @@ namespace TShockAPI
} }
else if (npcs.Count > 1) else if (npcs.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, npcs.Select(n => $"{n.FullName}({n.type})")); args.Player.SendMultipleMatchError(npcs.Select(n => $"{n.FullName}({n.type})"));
} }
else else
{ {
@ -2396,11 +2396,11 @@ namespace TShockAPI
if (args.Parameters.Count == 1) if (args.Parameters.Count == 1)
{ {
var players = TShock.Utils.FindPlayer(args.Parameters[0]); var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0) if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1) else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else else
{ {
var target = players[0]; var target = players[0];
@ -2425,13 +2425,13 @@ namespace TShockAPI
return; return;
} }
var players1 = TShock.Utils.FindPlayer(args.Parameters[0]); var players1 = TSPlayer.FindByNameOrID(args.Parameters[0]);
var players2 = TShock.Utils.FindPlayer(args.Parameters[1]); var players2 = TSPlayer.FindByNameOrID(args.Parameters[1]);
if (players2.Count == 0) if (players2.Count == 0)
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
else if (players2.Count > 1) else if (players2.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players2.Select(p => p.Name)); args.Player.SendMultipleMatchError(players2.Select(p => p.Name));
else if (players1.Count == 0) else if (players1.Count == 0)
{ {
if (args.Parameters[0] == "*") if (args.Parameters[0] == "*")
@ -2471,7 +2471,7 @@ namespace TShockAPI
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
} }
else if (players1.Count > 1) else if (players1.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players1.Select(p => p.Name)); args.Player.SendMultipleMatchError(players1.Select(p => p.Name));
else else
{ {
var source = players1[0]; var source = players1[0];
@ -2520,7 +2520,7 @@ namespace TShockAPI
} }
string playerName = String.Join(" ", args.Parameters); string playerName = String.Join(" ", args.Parameters);
var players = TShock.Utils.FindPlayer(playerName); var players = TSPlayer.FindByNameOrID(playerName);
if (players.Count == 0) if (players.Count == 0)
{ {
if (playerName == "*") if (playerName == "*")
@ -2544,7 +2544,7 @@ namespace TShockAPI
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
} }
else if (players.Count > 1) else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else else
{ {
var plr = players[0]; var plr = players[0];
@ -2583,7 +2583,7 @@ namespace TShockAPI
if (matches.Count > 1) if (matches.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, matches.Select(n => $"{n.FullName}({n.whoAmI})")); args.Player.SendMultipleMatchError(matches.Select(n => $"{n.FullName}({n.whoAmI})"));
return; return;
} }
if (matches.Count == 0) if (matches.Count == 0)
@ -2605,14 +2605,14 @@ namespace TShockAPI
player = String.Join(" ", args.Parameters); player = String.Join(" ", args.Parameters);
} }
var players = TShock.Utils.FindPlayer(player); var players = TSPlayer.FindByNameOrID(player);
if (players.Count == 0) if (players.Count == 0)
{ {
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
} }
else if (players.Count > 1) else if (players.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
} }
else else
{ {
@ -2766,7 +2766,7 @@ namespace TShockAPI
return; return;
} }
var foundplr = TShock.Utils.FindPlayer(args.Parameters[1]); var foundplr = TSPlayer.FindByNameOrID(args.Parameters[1]);
if (foundplr.Count == 0) if (foundplr.Count == 0)
{ {
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
@ -2774,7 +2774,7 @@ namespace TShockAPI
} }
else if (foundplr.Count > 1) else if (foundplr.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, foundplr.Select(p => p.Name)); args.Player.SendMultipleMatchError(foundplr.Select(p => p.Name));
return; return;
} }
@ -3225,7 +3225,7 @@ namespace TShockAPI
args.Player.SendErrorMessage("Invalid group."); args.Player.SendErrorMessage("Invalid group.");
return; return;
} }
Group grp = TShock.Utils.GetGroup(args.Parameters[1]); Group grp = TShock.Groups.GetGroupByName(args.Parameters[1]);
List<string> permissions = grp.TotalPermissions; List<string> permissions = grp.TotalPermissions;
PaginationTools.SendPage(args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(permissions), PaginationTools.SendPage(args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(permissions),
@ -3265,7 +3265,7 @@ namespace TShockAPI
} }
else if (items.Count > 1) else if (items.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, items.Select(i => $"{i.Name}({i.netID})")); args.Player.SendMultipleMatchError(items.Select(i => $"{i.Name}({i.netID})"));
} }
else else
{ {
@ -3291,7 +3291,7 @@ namespace TShockAPI
} }
else if (items.Count > 1) else if (items.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, items.Select(i => $"{i.Name}({i.netID})")); args.Player.SendMultipleMatchError(items.Select(i => $"{i.Name}({i.netID})"));
} }
else else
{ {
@ -3336,7 +3336,7 @@ namespace TShockAPI
} }
else if (items.Count > 1) else if (items.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, items.Select(i => $"{i.Name}({i.netID})")); args.Player.SendMultipleMatchError(items.Select(i => $"{i.Name}({i.netID})"));
} }
else else
{ {
@ -3362,7 +3362,7 @@ namespace TShockAPI
} }
else if (items.Count > 1) else if (items.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, items.Select(i => $"{i.Name}({i.netID})")); args.Player.SendMultipleMatchError(items.Select(i => $"{i.Name}({i.netID})"));
} }
else else
{ {
@ -3798,7 +3798,8 @@ namespace TShockAPI
private static void Reload(CommandArgs args) private static void Reload(CommandArgs args)
{ {
TShock.Utils.Reload(args.Player); TShock.Utils.Reload();
Hooks.GeneralHooks.OnReloadEvent(args.Player);
args.Player.SendSuccessMessage( args.Player.SendSuccessMessage(
"Configuration, permissions, and regions reload complete. Some changes may require a server restart."); "Configuration, permissions, and regions reload complete. Some changes may require a server restart.");
@ -4075,14 +4076,14 @@ namespace TShockAPI
} }
string plStr = args.Parameters[0]; string plStr = args.Parameters[0];
var players = TShock.Utils.FindPlayer(plStr); var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0) if (players.Count == 0)
{ {
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
} }
else if (players.Count > 1) else if (players.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
} }
else else
{ {
@ -4818,9 +4819,27 @@ namespace TShockAPI
return; return;
} }
args.Player.SendSuccessMessage("Online Players ({0}/{1})", TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots); args.Player.SendSuccessMessage("Online Players ({0}/{1})", TShock.Utils.GetActivePlayerCount(), TShock.Config.MaxSlots);
var players = new List<string>();
foreach (TSPlayer ply in TShock.Players)
{
if (ply != null && ply.Active)
{
if (displayIdsRequested)
{
players.Add(String.Format("{0} (ID: {1}{2})", ply.Name, ply.Index, ply.Account != null ? ", ID: " + ply.Account.ID : ""));
}
else
{
players.Add(ply.Name);
}
}
}
PaginationTools.SendPage( PaginationTools.SendPage(
args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(TShock.Utils.GetPlayers(displayIdsRequested)), args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(players),
new PaginationTools.Settings new PaginationTools.Settings
{ {
IncludeHeader = false, IncludeHeader = false,
@ -4838,7 +4857,6 @@ namespace TShockAPI
else else
{ {
args.Player.SendWarningMessage("The initial setup system is disabled. This incident has been logged."); args.Player.SendWarningMessage("The initial setup system is disabled. This incident has been logged.");
TShock.Utils.ForceKick(args.Player, "The initial setup system is disabled.", true, true);
TShock.Log.Warn("{0} attempted to use the initial setup system even though it's disabled.", args.Player.IP); TShock.Log.Warn("{0} attempted to use the initial setup system even though it's disabled.", args.Player.IP);
return; return;
} }
@ -4929,14 +4947,14 @@ namespace TShockAPI
return; return;
} }
var players = TShock.Utils.FindPlayer(args.Parameters[0]); var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0) if (players.Count == 0)
{ {
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
} }
else if (players.Count > 1) else if (players.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
} }
else if (players[0].HasPermission(Permissions.mute)) else if (players[0].HasPermission(Permissions.mute))
{ {
@ -4961,12 +4979,12 @@ namespace TShockAPI
private static void Motd(CommandArgs args) private static void Motd(CommandArgs args)
{ {
TShock.Utils.ShowFileToUser(args.Player, FileTools.MotdPath); args.Player.SendFileTextAsMessage(FileTools.MotdPath);
} }
private static void Rules(CommandArgs args) private static void Rules(CommandArgs args)
{ {
TShock.Utils.ShowFileToUser(args.Player, FileTools.RulesPath); args.Player.SendFileTextAsMessage(FileTools.RulesPath);
} }
private static void Whisper(CommandArgs args) private static void Whisper(CommandArgs args)
@ -4977,14 +4995,14 @@ namespace TShockAPI
return; return;
} }
var players = TShock.Utils.FindPlayer(args.Parameters[0]); var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0) if (players.Count == 0)
{ {
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
} }
else if (players.Count > 1) else if (players.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
} }
else if (args.Player.mute) else if (args.Player.mute)
{ {
@ -5029,11 +5047,11 @@ namespace TShockAPI
int annoy = 5; int annoy = 5;
int.TryParse(args.Parameters[1], out annoy); int.TryParse(args.Parameters[1], out annoy);
var players = TShock.Utils.FindPlayer(args.Parameters[0]); var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0) if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1) else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else else
{ {
var ply = players[0]; var ply = players[0];
@ -5049,11 +5067,11 @@ namespace TShockAPI
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}confuse <player>", Specifier); args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}confuse <player>", Specifier);
return; return;
} }
var players = TShock.Utils.FindPlayer(args.Parameters[0]); var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0) if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1) else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else else
{ {
var ply = players[0]; var ply = players[0];
@ -5069,11 +5087,11 @@ namespace TShockAPI
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}rocket <player>", Specifier); args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}rocket <player>", Specifier);
return; return;
} }
var players = TShock.Utils.FindPlayer(args.Parameters[0]); var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0) if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1) else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else else
{ {
var ply = players[0]; var ply = players[0];
@ -5098,11 +5116,11 @@ namespace TShockAPI
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}firework <player> [red|green|blue|yellow]", Specifier); args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}firework <player> [red|green|blue|yellow]", Specifier);
return; return;
} }
var players = TShock.Utils.FindPlayer(args.Parameters[0]); var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0) if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1) else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else else
{ {
int type = 167; int type = 167;
@ -5266,14 +5284,14 @@ namespace TShockAPI
} }
string plStr = String.Join(" ", args.Parameters); string plStr = String.Join(" ", args.Parameters);
var players = TShock.Utils.FindPlayer(plStr); var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0) if (players.Count == 0)
{ {
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
} }
else if (players.Count > 1) else if (players.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
} }
else else
{ {
@ -5304,7 +5322,7 @@ namespace TShockAPI
} }
else if (npcs.Count > 1) else if (npcs.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, npcs.Select(n => $"{n.FullName}({n.type})")); args.Player.SendMultipleMatchError(npcs.Select(n => $"{n.FullName}({n.type})"));
return; return;
} }
else else
@ -5359,7 +5377,7 @@ namespace TShockAPI
} }
else if (matchedItems.Count > 1) else if (matchedItems.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, matchedItems.Select(i => $"{i.Name}({i.netID})")); args.Player.SendMultipleMatchError(matchedItems.Select(i => $"{i.Name}({i.netID})"));
return; return;
} }
else else
@ -5389,7 +5407,7 @@ namespace TShockAPI
if (prefixIds.Count > 1) if (prefixIds.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, prefixIds.Select(p => p.ToString())); args.Player.SendMultipleMatchError(prefixIds.Select(p => p.ToString()));
return; return;
} }
else if (prefixIds.Count == 0) else if (prefixIds.Count == 0)
@ -5442,7 +5460,7 @@ namespace TShockAPI
} }
else if (npcs.Count > 1) else if (npcs.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, npcs.Select(n => $"{n.FullName}({n.type})")); args.Player.SendMultipleMatchError(npcs.Select(n => $"{n.FullName}({n.type})"));
return; return;
} }
else if (args.Parameters[1].Length > 200) else if (args.Parameters[1].Length > 200)
@ -5507,7 +5525,7 @@ namespace TShockAPI
} }
else if (items.Count > 1) else if (items.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, items.Select(i => $"{i.Name}({i.netID})")); args.Player.SendMultipleMatchError(items.Select(i => $"{i.Name}({i.netID})"));
} }
else else
{ {
@ -5531,14 +5549,14 @@ namespace TShockAPI
if (item.type >= 1 && item.type < Main.maxItemTypes) if (item.type >= 1 && item.type < Main.maxItemTypes)
{ {
var players = TShock.Utils.FindPlayer(plStr); var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0) if (players.Count == 0)
{ {
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
} }
else if (players.Count > 1) else if (players.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
} }
else else
{ {
@ -5577,7 +5595,7 @@ namespace TShockAPI
if (args.Parameters.Count > 0) if (args.Parameters.Count > 0)
{ {
string plStr = String.Join(" ", args.Parameters); string plStr = String.Join(" ", args.Parameters);
var players = TShock.Utils.FindPlayer(plStr); var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0) if (players.Count == 0)
{ {
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
@ -5585,7 +5603,7 @@ namespace TShockAPI
} }
else if (players.Count > 1) else if (players.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
return; return;
} }
else else
@ -5634,7 +5652,7 @@ namespace TShockAPI
} }
else if (found.Count > 1) else if (found.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, found.Select(f => Lang.GetBuffName(f))); args.Player.SendMultipleMatchError(found.Select(f => Lang.GetBuffName(f)));
return; return;
} }
id = found[0]; id = found[0];
@ -5662,7 +5680,7 @@ namespace TShockAPI
} }
int id = 0; int id = 0;
int time = 60; int time = 60;
var foundplr = TShock.Utils.FindPlayer(args.Parameters[0]); var foundplr = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (foundplr.Count == 0) if (foundplr.Count == 0)
{ {
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
@ -5670,7 +5688,7 @@ namespace TShockAPI
} }
else if (foundplr.Count > 1) else if (foundplr.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, foundplr.Select(p => p.Name)); args.Player.SendMultipleMatchError(foundplr.Select(p => p.Name));
return; return;
} }
else else
@ -5685,7 +5703,7 @@ namespace TShockAPI
} }
else if (found.Count > 1) else if (found.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, found.Select(b => Lang.GetBuffName(b))); args.Player.SendMultipleMatchError(found.Select(b => Lang.GetBuffName(b)));
return; return;
} }
id = found[0]; id = found[0];
@ -5794,7 +5812,7 @@ namespace TShockAPI
return; return;
} }
string plStr = String.Join(" ", args.Parameters); string plStr = String.Join(" ", args.Parameters);
var players = TShock.Utils.FindPlayer(plStr); var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0) if (players.Count == 0)
{ {
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
@ -5802,7 +5820,7 @@ namespace TShockAPI
} }
else if (players.Count > 1) else if (players.Count > 1)
{ {
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); args.Player.SendMultipleMatchError(players.Select(p => p.Name));
return; return;
} }
else else

View file

@ -294,6 +294,20 @@ namespace TShockAPI.DB
} }
return false; return false;
} }
/// <summary>Removes a ban if it has expired.</summary>
/// <param name="ban">The candidate ban to check.</param>
/// <returns>If the ban has been removed.</returns>
public bool RemoveBanIfExpired(Ban ban)
{
if (!string.IsNullOrWhiteSpace(ban.Expiration) && (ban.ExpirationDateTime != null) && (DateTime.UtcNow >= ban.ExpirationDateTime))
{
RemoveBan(ban.IP, false, false, false);
return true;
}
return false;
}
} }
/// <summary> /// <summary>

View file

@ -434,7 +434,7 @@ namespace TShockAPI.DB
if (database.Query("DELETE FROM GroupList WHERE GroupName=@0", name) == 1) if (database.Query("DELETE FROM GroupList WHERE GroupName=@0", name) == 1)
{ {
groups.Remove(TShock.Utils.GetGroup(name)); groups.Remove(TShock.Groups.GetGroupByName(name));
return "Group " + name + " has been deleted successfully."; return "Group " + name + " has been deleted successfully.";
} }
@ -454,7 +454,7 @@ namespace TShockAPI.DB
if (!GroupExists(name)) if (!GroupExists(name))
return "Error: Group doesn't exist."; return "Error: Group doesn't exist.";
var group = TShock.Utils.GetGroup(name); var group = TShock.Groups.GetGroupByName(name);
var oldperms = group.Permissions; // Store old permissions in case of error var oldperms = group.Permissions; // Store old permissions in case of error
permissions.ForEach(p => group.AddPermission(p)); permissions.ForEach(p => group.AddPermission(p));
@ -477,7 +477,7 @@ namespace TShockAPI.DB
if (!GroupExists(name)) if (!GroupExists(name))
return "Error: Group doesn't exist."; return "Error: Group doesn't exist.";
var group = TShock.Utils.GetGroup(name); var group = TShock.Groups.GetGroupByName(name);
var oldperms = group.Permissions; // Store old permissions in case of error var oldperms = group.Permissions; // Store old permissions in case of error
permissions.ForEach(p => group.RemovePermission(p)); permissions.ForEach(p => group.RemovePermission(p));

View file

@ -26,7 +26,7 @@ namespace TShockAPI
public class FileTools public class FileTools
{ {
private const string MotdFormat = private const string MotdFormat =
"This server is running TShock for Terraria.\n Type /help for a list of commands.\n%255,000,000%Current map: %map%\nCurrent players: %players%"; "This is [c/FF0000:%map%] on [c/00FFFF:TShock for Terraria].\n[c/00FF00:Current players:] [c/FFFF00:%players%]\nType [c/FF0000:/help] for a list of commands.\n";
/// <summary> /// <summary>
/// Path to the file containing the rules. /// Path to the file containing the rules.
/// </summary> /// </summary>
@ -154,7 +154,7 @@ namespace TShockAPI
{ {
if (string.IsNullOrWhiteSpace(line)) if (string.IsNullOrWhiteSpace(line))
continue; continue;
contains = TShock.Utils.GetIPv4Address(line).Equals(ip); contains = TShock.Utils.GetIPv4AddressFromHostname(line).Equals(ip);
if (contains) if (contains)
return true; return true;
} }

View file

@ -349,7 +349,7 @@ namespace TShockAPI
} }
/// <summary> /// <summary>
/// PlayerInfo - called at a PlayerInfo event /// PlayerInfo - called at a PlayerInfo event
/// If this is cancelled, the server will ForceKick the player. If this should be changed in the future, let someone know. /// If this is cancelled, the server will kick the player. If this should be changed in the future, let someone know.
/// </summary> /// </summary>
public static HandlerList<PlayerInfoEventArgs> PlayerInfo = new HandlerList<PlayerInfoEventArgs>(); public static HandlerList<PlayerInfoEventArgs> PlayerInfo = new HandlerList<PlayerInfoEventArgs>();
@ -1660,13 +1660,13 @@ namespace TShockAPI
if (OnPlayerInfo(args.Player, args.Data, playerid, hair, skinVariant, difficulty, name)) if (OnPlayerInfo(args.Player, args.Data, playerid, hair, skinVariant, difficulty, name))
{ {
TShock.Utils.ForceKick(args.Player, "A plugin cancelled the event.", true); args.Player.Kick("A plugin on this server stopped your login.", true, true);
return true; return true;
} }
if (name.Trim().Length == 0) if (name.Trim().Length == 0)
{ {
TShock.Utils.ForceKick(args.Player, "Empty Name.", true); args.Player.Kick("You have been Bounced.", true, true);
return true; return true;
} }
if (args.Player.ReceivedInfo) if (args.Player.ReceivedInfo)
@ -1694,12 +1694,12 @@ namespace TShockAPI
} }
if (TShock.Config.MediumcoreOnly && difficulty < 1) if (TShock.Config.MediumcoreOnly && difficulty < 1)
{ {
TShock.Utils.ForceKick(args.Player, "Server is set to mediumcore and above characters only!", true); args.Player.Kick("You need to join with a mediumcore player or higher.", true, true);
return true; return true;
} }
if (TShock.Config.HardcoreOnly && difficulty < 2) if (TShock.Config.HardcoreOnly && difficulty < 2)
{ {
TShock.Utils.ForceKick(args.Player, "Server is set to hardcore characters only!", true); args.Player.Kick("You need to join with a hardcore player.", true, true);
return true; return true;
} }
args.Player.Difficulty = difficulty; args.Player.Difficulty = difficulty;
@ -1725,7 +1725,7 @@ namespace TShockAPI
args.Player.PlayerData = TShock.CharacterDB.GetPlayerData(args.Player, account.ID); args.Player.PlayerData = TShock.CharacterDB.GetPlayerData(args.Player, account.ID);
var group = TShock.Utils.GetGroup(account.Group); var group = TShock.Groups.GetGroupByName(account.Group);
args.Player.Group = group; args.Player.Group = group;
args.Player.tempGroup = null; args.Player.tempGroup = null;
@ -1797,7 +1797,7 @@ namespace TShockAPI
args.Player.State = 2; args.Player.State = 2;
NetMessage.SendData((int)PacketTypes.WorldInfo, args.Player.Index); NetMessage.SendData((int)PacketTypes.WorldInfo, args.Player.Index);
var group = TShock.Utils.GetGroup(account.Group); var group = TShock.Groups.GetGroupByName(account.Group);
args.Player.Group = group; args.Player.Group = group;
args.Player.tempGroup = null; args.Player.tempGroup = null;
@ -1829,9 +1829,10 @@ namespace TShockAPI
Hooks.PlayerHooks.OnPlayerPostLogin(args.Player); Hooks.PlayerHooks.OnPlayerPostLogin(args.Player);
return true; return true;
} }
TShock.Utils.ForceKick(args.Player, "Invalid user account password.", true); args.Player.Kick("Your password did not match this character's password.", true, true);
return true; return true;
} }
if (!string.IsNullOrEmpty(TShock.Config.ServerPassword)) if (!string.IsNullOrEmpty(TShock.Config.ServerPassword))
{ {
if (TShock.Config.ServerPassword == password) if (TShock.Config.ServerPassword == password)
@ -1842,11 +1843,11 @@ namespace TShockAPI
NetMessage.SendData((int)PacketTypes.WorldInfo, args.Player.Index); NetMessage.SendData((int)PacketTypes.WorldInfo, args.Player.Index);
return true; return true;
} }
TShock.Utils.ForceKick(args.Player, "Incorrect server password", true); args.Player.Kick("Invalid server password.", true, true);
return true; return true;
} }
TShock.Utils.ForceKick(args.Player, "Bad password attempt", true); args.Player.Kick("You have been Bounced.", true, true);
return true; return true;
} }
@ -1891,10 +1892,10 @@ namespace TShockAPI
if (OnGetSection(args.Player, args.Data, args.Data.ReadInt32(), args.Data.ReadInt32())) if (OnGetSection(args.Player, args.Data, args.Data.ReadInt32(), args.Data.ReadInt32()))
return true; return true;
if (TShock.Utils.ActivePlayers() + 1 > TShock.Config.MaxSlots && if (TShock.Utils.GetActivePlayerCount() + 1 > TShock.Config.MaxSlots &&
!args.Player.HasPermission(Permissions.reservedslot)) !args.Player.HasPermission(Permissions.reservedslot))
{ {
TShock.Utils.ForceKick(args.Player, TShock.Config.ServerFullReason, true); args.Player.Kick(TShock.Config.ServerFullReason, true, true);
return true; return true;
} }
@ -2383,12 +2384,12 @@ namespace TShockAPI
{ {
if (TShock.Config.BanOnHardcoreDeath) if (TShock.Config.BanOnHardcoreDeath)
{ {
if (!TShock.Utils.Ban(args.Player, TShock.Config.HardcoreBanReason, false, "hardcore-death")) if (!args.Player.Ban(TShock.Config.HardcoreBanReason, false, "hardcore-death"))
TShock.Utils.ForceKick(args.Player, "Death results in a ban, but you are immune to bans.", true); args.Player.Kick("You died! Normally, you'd be banned.", true, true);
} }
else else
{ {
TShock.Utils.ForceKick(args.Player, TShock.Config.HardcoreKickReason, true, false); args.Player.Kick(TShock.Config.HardcoreKickReason, true, true, null, false);
} }
} }
@ -2447,12 +2448,12 @@ namespace TShockAPI
{ {
if (TShock.Config.BanOnMediumcoreDeath) if (TShock.Config.BanOnMediumcoreDeath)
{ {
if (!TShock.Utils.Ban(args.Player, TShock.Config.MediumcoreBanReason, false, "mediumcore-death")) if (!args.Player.Ban(TShock.Config.MediumcoreBanReason, false, "mediumcore-death"))
TShock.Utils.ForceKick(args.Player, "Death results in a ban, but you are immune to bans.", true); args.Player.Kick("You died! Normally, you'd be banned.", true, true);
} }
else else
{ {
TShock.Utils.ForceKick(args.Player, TShock.Config.MediumcoreKickReason, true, false); args.Player.Kick(TShock.Config.MediumcoreKickReason, true, true, null, false);
} }
return true; return true;
} }

View file

@ -339,7 +339,8 @@ namespace TShockAPI
[Token] [Token]
private object ServerReload(RestRequestArgs args) private object ServerReload(RestRequestArgs args)
{ {
TShock.Utils.Reload(new TSRestPlayer(args.TokenData.Username, TShock.Groups.GetGroupByName(args.TokenData.UserGroupName))); TShock.Utils.Reload();
Hooks.GeneralHooks.OnReloadEvent(new TSRestPlayer(args.TokenData.Username, TShock.Groups.GetGroupByName(args.TokenData.UserGroupName)));
return RestResponse("Configuration, permissions, and regions reload complete. Some changes may require a server restart."); return RestResponse("Configuration, permissions, and regions reload complete. Some changes may require a server restart.");
} }
@ -410,7 +411,7 @@ namespace TShockAPI
var players = new ArrayList(); var players = new ArrayList();
foreach (TSPlayer tsPlayer in TShock.Players.Where(p => null != p)) foreach (TSPlayer tsPlayer in TShock.Players.Where(p => null != p))
{ {
var p = PlayerFilter(tsPlayer, args.Parameters, ((args.TokenData.UserGroupName) != "" && TShock.Utils.GetGroup(args.TokenData.UserGroupName).HasPermission(RestPermissions.viewips))); var p = PlayerFilter(tsPlayer, args.Parameters, ((args.TokenData.UserGroupName) != "" && TShock.Groups.GetGroupByName(args.TokenData.UserGroupName).HasPermission(RestPermissions.viewips)));
if (null != p) if (null != p)
players.Add(p); players.Add(p);
} }
@ -982,7 +983,7 @@ namespace TShockAPI
return ret; return ret;
TSPlayer player = (TSPlayer)ret; TSPlayer player = (TSPlayer)ret;
TShock.Utils.ForceKick(player, null == args.Parameters["reason"] ? "Kicked via web" : args.Parameters["reason"], false, true); player.Kick(null == args.Parameters["reason"] ? "Kicked via web" : args.Parameters["reason"], false, true, null, true);
return RestResponse("Player " + player.Name + " was kicked"); return RestResponse("Player " + player.Name + " was kicked");
} }
@ -1002,7 +1003,7 @@ namespace TShockAPI
TSPlayer player = (TSPlayer)ret; TSPlayer player = (TSPlayer)ret;
var reason = null == args.Parameters["reason"] ? "Banned via web" : args.Parameters["reason"]; var reason = null == args.Parameters["reason"] ? "Banned via web" : args.Parameters["reason"];
TShock.Bans.AddBan(player.IP, player.Name, "", "", reason); TShock.Bans.AddBan(player.IP, player.Name, "", "", reason);
TShock.Utils.ForceKick(player, reason, false, true); player.Kick(reason, true, false, null, true);
return RestResponse("Player " + player.Name + " was banned"); return RestResponse("Player " + player.Name + " was banned");
} }
@ -1244,7 +1245,7 @@ namespace TShockAPI
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
return RestMissingParam("player"); return RestMissingParam("player");
var found = TShock.Utils.FindPlayer(name); var found = TSPlayer.FindByNameOrID(name);
switch(found.Count) switch(found.Count)
{ {
case 1: case 1:

View file

@ -144,7 +144,7 @@ namespace Rests
return new RestObject("403") { Error = "Username or password may be incorrect or this account may not have sufficient privileges." }; return new RestObject("403") { Error = "Username or password may be incorrect or this account may not have sufficient privileges." };
} }
Group userGroup = TShock.Utils.GetGroup(userAccount.Group); Group userGroup = TShock.Groups.GetGroupByName(userAccount.Group);
if (!userGroup.HasPermission(RestPermissions.restapi) && userAccount.Group != "superadmin") if (!userGroup.HasPermission(RestPermissions.restapi) && userAccount.Group != "superadmin")
{ {
AddTokenToBucket(context.RemoteEndPoint.Address.ToString()); AddTokenToBucket(context.RemoteEndPoint.Address.ToString());

View file

@ -144,7 +144,7 @@ namespace TShockAPI
return new JsonData() return new JsonData()
{ {
port = Terraria.Netplay.ListenPort, port = Terraria.Netplay.ListenPort,
currentPlayers = TShock.Utils.ActivePlayers(), currentPlayers = TShock.Utils.GetActivePlayerCount(),
maxPlayers = TShock.Config.MaxSlots, maxPlayers = TShock.Config.MaxSlots,
systemRam = GetTotalSystemRam(ServerApi.RunningMono), systemRam = GetTotalSystemRam(ServerApi.RunningMono),
version = TShock.VersionNum.ToString(), version = TShock.VersionNum.ToString(),

View file

@ -34,6 +34,7 @@ using TShockAPI.DB;
using TShockAPI.Hooks; using TShockAPI.Hooks;
using TShockAPI.Net; using TShockAPI.Net;
using Timer = System.Timers.Timer; using Timer = System.Timers.Timer;
using System.Linq;
namespace TShockAPI namespace TShockAPI
{ {
@ -73,6 +74,43 @@ namespace TShockAPI
/// </summary> /// </summary>
public static readonly TSPlayer All = new TSPlayer("All"); public static readonly TSPlayer All = new TSPlayer("All");
/// <summary>
/// Finds a TSPlayer based on name or ID
/// </summary>
/// <param name="plr">Player name or ID</param>
/// <returns>A list of matching players</returns>
public static List<TSPlayer> FindByNameOrID(string plr)
{
var found = new List<TSPlayer>();
// Avoid errors caused by null search
if (plr == null)
return found;
byte plrID;
if (byte.TryParse(plr, out plrID) && plrID < Main.maxPlayers)
{
TSPlayer player = TShock.Players[plrID];
if (player != null && player.Active)
{
return new List<TSPlayer> { player };
}
}
string plrLower = plr.ToLower();
foreach (TSPlayer player in TShock.Players)
{
if (player != null)
{
// Must be an EXACT match
if (player.Name == plr)
return new List<TSPlayer> { player };
if (player.Name.ToLower().StartsWith(plrLower))
found.Add(player);
}
}
return found;
}
/// <summary> /// <summary>
/// The amount of tiles that the player has killed in the last second. /// The amount of tiles that the player has killed in the last second.
/// </summary> /// </summary>
@ -1420,6 +1458,43 @@ namespace TShockAPI
SendDataFromPlayer(PacketTypes.SmartTextMessage, ply, msg, red, green, blue, -1); SendDataFromPlayer(PacketTypes.SmartTextMessage, ply, msg, red, green, blue, -1);
} }
/// <summary>
/// Sends the text of a given file to the player. Replacement of %map% and %players% if in the file.
/// </summary>
/// <param name="file">Filename relative to <see cref="TShock.SavePath"></see></param>
public void SendFileTextAsMessage(string file)
{
string foo = "";
bool containsOldFormat = false;
using (var tr = new StreamReader(file))
{
Color lineColor;
while ((foo = tr.ReadLine()) != null)
{
lineColor = Color.White;
if (string.IsNullOrWhiteSpace(foo))
{
continue;
}
var players = new List<string>();
foreach (TSPlayer ply in TShock.Players)
{
if (ply != null && ply.Active)
{
players.Add(ply.Name);
}
}
foo = foo.Replace("%map%", (TShock.Config.UseServerName ? TShock.Config.ServerName : Main.worldName));
foo = foo.Replace("%players%", String.Join(",", players));
SendMessage(foo, lineColor);
}
}
}
/// <summary> /// <summary>
/// Wounds the player with the given damage. /// Wounds the player with the given damage.
/// </summary> /// </summary>
@ -1505,6 +1580,79 @@ namespace TShockAPI
LogStackFrame(); LogStackFrame();
} }
/// <summary>
/// Disconnects this player from the server with a reason.
/// </summary>
/// <param name="reason">The reason to display to the user and to the server on kick.</param>
/// <param name="force">If the kick should happen regardless of immunity to kick permissions.</param>
/// <param name="silent">If no message should be broadcasted to the server.</param>
/// <param name="adminUserName">The originator of the kick, for display purposes.</param>
/// <param name="saveSSI">If the player's server side character should be saved on kick.</param>
public bool Kick(string reason, bool force = false, bool silent = false, string adminUserName = null, bool saveSSI = false)
{
if (!ConnectionAlive)
return true;
if (force || !HasPermission(Permissions.immunetokick))
{
SilentKickInProgress = silent;
if (IsLoggedIn && saveSSI)
SaveServerCharacter();
Disconnect(string.Format("Kicked: {0}", reason));
TShock.Log.ConsoleInfo(string.Format("Kicked {0} for : '{1}'", Name, reason));
string verb = force ? "force " : "";
if (!silent)
{
if (string.IsNullOrWhiteSpace(adminUserName))
TShock.Utils.Broadcast(string.Format("{0} was {1}kicked for '{2}'", Name, verb, reason.ToLower()), Color.Green);
else
TShock.Utils.Broadcast(string.Format("{0} {1}kicked {2} for '{3}'", adminUserName, verb, Name, reason.ToLower()), Color.Green);
}
return true;
}
return false;
}
/// <summary>
/// Bans and disconnects the player from the server.
/// </summary>
/// <param name="reason">The reason to be displayed to the server.</param>
/// <param name="force">If the ban should bypass immunity to ban checks.</param>
/// <param name="adminUserName">The player who initiated the ban.</param>
public bool Ban(string reason, bool force = false, string adminUserName = null)
{
if (!ConnectionAlive)
return true;
if (force || !HasPermission(Permissions.immunetoban))
{
string ip = IP;
string uuid = UUID;
TShock.Bans.AddBan(ip, Name, uuid, "", reason, false, adminUserName);
Disconnect(string.Format("Banned: {0}", reason));
string verb = force ? "force " : "";
if (string.IsNullOrWhiteSpace(adminUserName))
TSPlayer.All.SendInfoMessage("{0} was {1}banned for '{2}'.", Name, verb, reason);
else
TSPlayer.All.SendInfoMessage("{0} {1}banned {2} for '{3}'.", adminUserName, verb, Name, reason);
return true;
}
return false;
}
/// <summary>
/// Sends the player an error message stating that more than one match was found
/// appending a csv list of the matches.
/// </summary>
/// <param name="matches">An enumerable list with the matches</param>
public void SendMultipleMatchError(IEnumerable<object> matches)
{
SendErrorMessage("More than one match found: ");
var lines = PaginationTools.BuildLinesFromTerms(matches.ToArray());
lines.ForEach(SendInfoMessage);
SendErrorMessage("Use \"my query\" for items with spaces.");
}
[Conditional("DEBUG")] [Conditional("DEBUG")]
private void LogStackFrame() private void LogStackFrame()
{ {

View file

@ -481,13 +481,13 @@ namespace TShockAPI
// And then get rid of them. // And then get rid of them.
if (potentialBan.Expiration == "") if (potentialBan.Expiration == "")
{ {
Utils.ForceKick(args.Player, String.Format("Permanently banned by {0} for {1}", potentialBan.BanningUser args.Player.Kick(String.Format("Permanently banned by {0} for {1}", potentialBan.BanningUser
,potentialBan.Reason), false, false); ,potentialBan.Reason), true, true);
} }
else else
{ {
Utils.ForceKick(args.Player, String.Format("Still banned by {0} for {1}", potentialBan.BanningUser, args.Player.Kick(String.Format("Still banned by {0} for {1}", potentialBan.BanningUser,
potentialBan.Reason), false, false); potentialBan.Reason), true, true);
} }
} }
} }
@ -1241,16 +1241,16 @@ namespace TShockAPI
var player = new TSPlayer(args.Who); var player = new TSPlayer(args.Who);
if (Utils.ActivePlayers() + 1 > Config.MaxSlots + Config.ReservedSlots) if (Utils.GetActivePlayerCount() + 1 > Config.MaxSlots + Config.ReservedSlots)
{ {
Utils.ForceKick(player, Config.ServerFullNoReservedReason, true, false); player.Kick(Config.ServerFullNoReservedReason, true, true, null, false);
args.Handled = true; args.Handled = true;
return; return;
} }
if (!FileTools.OnWhitelist(player.IP)) if (!FileTools.OnWhitelist(player.IP))
{ {
Utils.ForceKick(player, Config.WhitelistKickReason, true, false); player.Kick(Config.WhitelistKickReason, true, true, null, false);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1263,7 +1263,7 @@ namespace TShockAPI
{ {
if (Config.KickProxyUsers) if (Config.KickProxyUsers)
{ {
Utils.ForceKick(player, "Proxies are not allowed.", true, false); player.Kick("Connecting via a proxy is not allowed.", true, true, null, false);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1285,7 +1285,7 @@ namespace TShockAPI
if (Config.KickEmptyUUID && String.IsNullOrWhiteSpace(player.UUID)) if (Config.KickEmptyUUID && String.IsNullOrWhiteSpace(player.UUID))
{ {
Utils.ForceKick(player, "Your client did not send a UUID, this server is not configured to accept such a client.", true); player.Kick("Your client sent a blank UUID. Configure it to send one or use a different client.", true, true, null, false);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1310,7 +1310,7 @@ namespace TShockAPI
if (ban != null) if (ban != null)
{ {
if (!Utils.HasBanExpired(ban)) if (!Bans.RemoveBanIfExpired(ban))
{ {
DateTime exp; DateTime exp;
if (!DateTime.TryParse(ban.Expiration, out exp)) if (!DateTime.TryParse(ban.Expiration, out exp))
@ -1400,7 +1400,7 @@ namespace TShockAPI
} }
// The last player will leave after this hook is executed. // The last player will leave after this hook is executed.
if (Utils.ActivePlayers() == 1) if (Utils.GetActivePlayerCount() == 1)
{ {
if (Config.SaveWorldOnLastPlayerExit) if (Config.SaveWorldOnLastPlayerExit)
SaveManager.Instance.SaveWorld(); SaveManager.Instance.SaveWorld();
@ -1424,7 +1424,7 @@ namespace TShockAPI
if (args.Text.Length > 500) if (args.Text.Length > 500)
{ {
Utils.Kick(tsplr, "Crash attempt via long chat packet.", true); tsplr.Kick("Crash attempt via long chat packet.", true);
args.Handled = true; args.Handled = true;
return; return;
} }
@ -1621,7 +1621,7 @@ namespace TShockAPI
if (Config.EnableGeoIP && TShock.Geo != null) if (Config.EnableGeoIP && TShock.Geo != null)
{ {
Log.Info("{0} ({1}) from '{2}' group from '{3}' joined. ({4}/{5})", player.Name, player.IP, Log.Info("{0} ({1}) from '{2}' group from '{3}' joined. ({4}/{5})", player.Name, player.IP,
player.Group.Name, player.Country, TShock.Utils.ActivePlayers(), player.Group.Name, player.Country, TShock.Utils.GetActivePlayerCount(),
TShock.Config.MaxSlots); TShock.Config.MaxSlots);
if (!player.SilentJoinInProgress) if (!player.SilentJoinInProgress)
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);
@ -1629,7 +1629,7 @@ namespace TShockAPI
else else
{ {
Log.Info("{0} ({1}) from '{2}' group joined. ({3}/{4})", player.Name, player.IP, Log.Info("{0} ({1}) from '{2}' group joined. ({3}/{4})", player.Name, player.IP,
player.Group.Name, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots); player.Group.Name, TShock.Utils.GetActivePlayerCount(), TShock.Config.MaxSlots);
if (!player.SilentJoinInProgress) if (!player.SilentJoinInProgress)
Utils.Broadcast(player.Name + " has joined.", Color.Yellow); Utils.Broadcast(player.Name + " has joined.", Color.Yellow);
} }
@ -1637,7 +1637,7 @@ namespace TShockAPI
if (Config.DisplayIPToAdmins) if (Config.DisplayIPToAdmins)
Utils.SendLogs(string.Format("{0} has joined. IP: {1}", player.Name, player.IP), Color.Blue); Utils.SendLogs(string.Format("{0} has joined. IP: {1}", player.Name, player.IP), Color.Blue);
Utils.ShowFileToUser(player, FileTools.MotdPath); player.SendFileTextAsMessage(FileTools.MotdPath);
string pvpMode = Config.PvPMode.ToLowerInvariant(); string pvpMode = Config.PvPMode.ToLowerInvariant();
if (pvpMode == "always") if (pvpMode == "always")

View file

@ -69,52 +69,6 @@ namespace TShockAPI
return mess.Split(':')[0]; return mess.Split(':')[0];
} }
/// <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(String.Format("{0} (IX: {1}{2})", ply.Name, ply.Index, ply.Account != null ? ", ID: " + ply.Account.ID : ""));
}
else
{
players.Add(ply.Name);
}
}
}
return players;
}
/// <summary>
/// Finds a player and gets IP as string
/// </summary>
/// <param name="playername">string playername</param>
public string GetPlayerIP(string playername)
{
foreach (TSPlayer player in TShock.Players)
{
if (player != null && player.Active)
{
if (playername.ToLower() == player.Name.ToLower())
{
return player.IP;
}
}
}
return null;
}
/// <summary> /// <summary>
/// It's a clamp function /// It's a clamp function
/// </summary> /// </summary>
@ -199,48 +153,11 @@ namespace TShockAPI
/// Gets the number of active players on the server. /// Gets the number of active players on the server.
/// </summary> /// </summary>
/// <returns>The number of active players on the server.</returns> /// <returns>The number of active players on the server.</returns>
public int ActivePlayers() public int GetActivePlayerCount()
{ {
return Main.player.Where(p => null != p && p.active).Count(); return Main.player.Where(p => null != p && p.active).Count();
} }
/// <summary>
/// Finds a TSPlayer based on name or ID
/// </summary>
/// <param name="plr">Player name or ID</param>
/// <returns>A list of matching players</returns>
public List<TSPlayer> FindPlayer(string plr)
{
var found = new List<TSPlayer>();
// Avoid errors caused by null search
if (plr == null)
return found;
byte plrID;
if (byte.TryParse(plr, out plrID) && plrID < Main.maxPlayers)
{
TSPlayer player = TShock.Players[plrID];
if (player != null && player.Active)
{
return new List<TSPlayer> { player };
}
}
string plrLower = plr.ToLower();
foreach (TSPlayer player in TShock.Players)
{
if (player != null)
{
// Must be an EXACT match
if (player.Name == plr)
return new List<TSPlayer> { player };
if (player.Name.ToLower().StartsWith(plrLower))
found.Add(player);
}
}
return found;
}
//Random should not be generated in a method //Random should not be generated in a method
Random r = new Random(); Random r = new Random();
@ -536,21 +453,6 @@ namespace TShockAPI
return GetPrefixByName(idOrName); return GetPrefixByName(idOrName);
} }
/// <summary>
/// Kicks all player from the server without checking for immunetokick permission.
/// </summary>
/// <param name="reason">string reason</param>
public void ForceKickAll(string reason)
{
foreach (TSPlayer player in TShock.Players)
{
if (player != null && player.Active)
{
ForceKick(player, reason, false, true);
}
}
}
/// <summary> /// <summary>
/// Stops the server after kicking all players with a reason message, and optionally saving the world /// Stops the server after kicking all players with a reason message, and optionally saving the world
/// </summary> /// </summary>
@ -560,12 +462,10 @@ namespace TShockAPI
{ {
TShock.ShuttingDown = true; TShock.ShuttingDown = true;
ForceKickAll(reason);
if (save) if (save)
SaveManager.Instance.SaveWorld(); SaveManager.Instance.SaveWorld();
// Save takes a while so kick again TSPlayer.All.Kick(reason, true, true, null, true);
ForceKickAll(reason);
// Broadcast so console can see we are shutting down as well // Broadcast so console can see we are shutting down as well
TShock.Utils.Broadcast(reason, Color.Red); TShock.Utils.Broadcast(reason, Color.Red);
@ -577,7 +477,7 @@ namespace TShockAPI
/// <summary> /// <summary>
/// Reloads all configuration settings, groups, regions and raises the reload event. /// Reloads all configuration settings, groups, regions and raises the reload event.
/// </summary> /// </summary>
public void Reload(TSPlayer player) public void Reload()
{ {
FileTools.SetupConfig(); FileTools.SetupConfig();
TShock.HandleCommandLinePostConfigLoad(Environment.GetCommandLineArgs()); TShock.HandleCommandLinePostConfigLoad(Environment.GetCommandLineArgs());
@ -586,156 +486,13 @@ namespace TShockAPI
TShock.Itembans.UpdateItemBans(); TShock.Itembans.UpdateItemBans();
TShock.ProjectileBans.UpdateBans(); TShock.ProjectileBans.UpdateBans();
TShock.TileBans.UpdateBans(); TShock.TileBans.UpdateBans();
Hooks.GeneralHooks.OnReloadEvent(player);
}
/// <summary>
/// Kicks a player from the server without checking for immunetokick permission.
/// </summary>
/// <param name="player">TSPlayer player</param>
/// <param name="reason">string reason</param>
/// <param name="silent">bool silent (default: false)</param>
/// <param name="saveSSI">bool saveSSI (default: false)</param>
public void ForceKick(TSPlayer player, string reason, bool silent = false, bool saveSSI = false)
{
Kick(player, reason, true, silent, null, saveSSI);
}
/// <summary>
/// Kicks a player from the server..
/// </summary>
/// <param name="player">TSPlayer player</param>
/// <param name="reason">string reason</param>
/// <param name="force">bool force (default: false)</param>
/// <param name="silent">bool silent (default: false)</param>
/// <param name="adminUserName">string adminUserName (default: null)</param>
/// <param name="saveSSI">bool saveSSI (default: false)</param>
public bool Kick(TSPlayer player, string reason, bool force = false, bool silent = false, string adminUserName = null, bool saveSSI = false)
{
if (!player.ConnectionAlive)
return true;
if (force || !player.HasPermission(Permissions.immunetokick))
{
string playerName = player.Name;
player.SilentKickInProgress = silent;
if (player.IsLoggedIn && saveSSI)
player.SaveServerCharacter();
player.Disconnect(string.Format("Kicked: {0}", 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
Broadcast(string.Format("{0} {1}kicked {2} for '{3}'", adminUserName, verb, playerName, reason.ToLower()), Color.Green);
}
return true;
}
return false;
}
/// <summary>
/// Bans and kicks a player from the server.
/// </summary>
/// <param name="player">TSPlayer player</param>
/// <param name="reason">string reason</param>
/// <param name="force">bool force (default: false)</param>
/// <param name="adminUserName">string adminUserName (default: null)</param>
public bool Ban(TSPlayer player, string reason, bool force = false, string adminUserName = null)
{
if (!player.ConnectionAlive)
return true;
if (force || !player.HasPermission(Permissions.immunetoban))
{
string ip = player.IP;
string uuid = player.UUID;
string playerName = player.Name;
TShock.Bans.AddBan(ip, playerName, uuid, "", reason, false, adminUserName);
player.Disconnect(string.Format("Banned: {0}", reason));
string verb = force ? "force " : "";
if (string.IsNullOrWhiteSpace(adminUserName))
TSPlayer.All.SendInfoMessage("{0} was {1}banned for '{2}'.", playerName, verb, reason);
else
TSPlayer.All.SendInfoMessage("{0} {1}banned {2} for '{3}'.", adminUserName, verb, playerName, reason);
return true;
}
return false;
}
/// <summary>HasBanExpired - Returns whether or not a ban has expired or not.</summary>
/// <param name="ban">ban - The ban object to check.</param>
/// <param name="byName">byName - Defines whether or not the ban should be checked by name.</param>
/// <returns>bool - True if the ban has expired.</returns>
public bool HasBanExpired(Ban ban, bool byName = false)
{
if (!string.IsNullOrWhiteSpace(ban.Expiration) && (ban.ExpirationDateTime != null) && (DateTime.UtcNow >= ban.ExpirationDateTime))
{
if (byName)
{
TShock.Bans.RemoveBan(ban.Name, true, true, false);
}
else
{
TShock.Bans.RemoveBan(ban.IP, false, false, false);
}
return true;
}
return false;
}
/// <summary>
/// Shows a file to the user.
/// </summary>
/// <param name="player">Player the file contents will be sent to</param>
/// <param name="file">Filename relative to <see cref="TShock.SavePath"></see></param>
public void ShowFileToUser(TSPlayer player, string file)
{
string foo = "";
bool containsOldFormat = false;
using (var tr = new StreamReader(file))
{
Color lineColor;
while ((foo = tr.ReadLine()) != null)
{
lineColor = Color.White;
if (string.IsNullOrWhiteSpace(foo))
{
continue;
}
foo = foo.Replace("%map%", (TShock.Config.UseServerName ? TShock.Config.ServerName : Main.worldName));
foo = foo.Replace("%players%", String.Join(",", GetPlayers(false)));
player.SendMessage(foo, lineColor);
}
}
}
/// <summary>
/// Returns a Group from the name of the group
/// </summary>
/// <param name="groupName">string groupName</param>
public Group GetGroup(string groupName)
{
//first attempt on cached groups
for (int i = 0; i < TShock.Groups.groups.Count; i++)
{
if (TShock.Groups.groups[i].Name.Equals(groupName))
{
return TShock.Groups.groups[i];
}
}
return Group.DefaultGroup;
} }
/// <summary> /// <summary>
/// Returns an IPv4 address from a DNS query /// Returns an IPv4 address from a DNS query
/// </summary> /// </summary>
/// <param name="hostname">string ip</param> /// <param name="hostname">string ip</param>
public string GetIPv4Address(string hostname) public string GetIPv4AddressFromHostname(string hostname)
{ {
try try
{ {
@ -750,28 +507,11 @@ namespace TShockAPI
return ""; return "";
} }
/// <summary>
/// Sends the player an error message stating that more than one match was found
/// appending a csv list of the matches.
/// </summary>
/// <param name="ply">Player to send the message to</param>
/// <param name="matches">An enumerable list with the matches</param>
public void SendMultipleMatchError(TSPlayer ply, IEnumerable<object> matches)
{
ply.SendErrorMessage("More than one match found: ");
var lines = PaginationTools.BuildLinesFromTerms(matches.ToArray());
lines.ForEach(ply.SendInfoMessage);
ply.SendErrorMessage("Use \"my query\" for items with spaces.");
}
/// <summary> /// <summary>
/// Checks if world has hit the max number of chests /// Checks if world has hit the max number of chests
/// </summary> /// </summary>
/// <returns>True if the entire chest array is used</returns> /// <returns>True if the entire chest array is used</returns>
public bool MaxChests() public bool HasWorldReachedMaxChests()
{ {
for (int i = 0; i < Main.chest.Length; i++) for (int i = 0; i < Main.chest.Length; i++)
{ {
@ -1377,7 +1117,7 @@ namespace TShockAPI
} }
else else
{ {
invasionSize = 100 + (TShock.Config.InvasionMultiplier * ActivePlayers()); invasionSize = 100 + (TShock.Config.InvasionMultiplier * GetActivePlayerCount());
} }
// Order matters // Order matters
@ -1411,12 +1151,12 @@ namespace TShockAPI
} }
/// <summary>Updates the console title with some pertinent information.</summary> /// <summary>Updates the console title with some pertinent information.</summary>
/// <param name="empty">If the server is empty; determines if we should use Utils.ActivePlayers() for player count or 0.</param> /// <param name="empty">If the server is empty; determines if we should use Utils.GetActivePlayerCount() for player count or 0.</param>
internal void SetConsoleTitle(bool empty) internal void SetConsoleTitle(bool empty)
{ {
Console.Title = string.Format("{0}{1}/{2} on {3} @ {4}:{5} (TShock for Terraria v{6})", Console.Title = string.Format("{0}{1}/{2} on {3} @ {4}:{5} (TShock for Terraria v{6})",
!string.IsNullOrWhiteSpace(TShock.Config.ServerName) ? TShock.Config.ServerName + " - " : "", !string.IsNullOrWhiteSpace(TShock.Config.ServerName) ? TShock.Config.ServerName + " - " : "",
empty ? 0 : ActivePlayers(), empty ? 0 : GetActivePlayerCount(),
TShock.Config.MaxSlots, Main.worldName, Netplay.ServerIP.ToString(), Netplay.ListenPort, TShock.VersionNum); TShock.Config.MaxSlots, Main.worldName, Netplay.ServerIP.ToString(), Netplay.ListenPort, TShock.VersionNum);
} }