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)
* 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)
* 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
* 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))
{
TShock.Utils.ForceKick(args.Player, "Blank name.", true);
args.Player.Kick("Your client sent a blank character name.", true, true);
args.Handled = true;
return;
}
@ -256,7 +256,7 @@ namespace TShockAPI
{
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;
return;
}
@ -313,7 +313,7 @@ namespace TShockAPI
{
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;
return;
}
@ -627,7 +627,7 @@ namespace TShockAPI
&& Main.tile[tileX, tileY].type != TileID.Containers
&& Main.tile[tileX, tileY].type != TileID.Dressers
&& 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.Handled = true;
@ -925,7 +925,7 @@ namespace TShockAPI
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);
args.Handled = true;
return;
@ -942,7 +942,7 @@ namespace TShockAPI
{
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;
return;
}
@ -1409,7 +1409,7 @@ namespace TShockAPI
}
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.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.",
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;
}
@ -842,7 +842,7 @@ namespace TShockAPI
{
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.tempGroup = null;
@ -1195,11 +1195,11 @@ namespace TShockAPI
return;
}
var players = TShock.Utils.FindPlayer(args.Parameters[0]);
var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count < 1)
args.Player.SendErrorMessage("Invalid player.");
else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else
{
var message = new StringBuilder();
@ -1265,21 +1265,21 @@ namespace TShockAPI
}
string plStr = args.Parameters[0];
var players = TShock.Utils.FindPlayer(plStr);
var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
}
else if (players.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
}
else
{
string reason = args.Parameters.Count > 1
? String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1))
: "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!");
}
@ -1308,7 +1308,7 @@ namespace TShockAPI
string targetGeneralizedName = "";
// 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]);
// 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
if (players.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
return;
}
@ -1658,7 +1658,7 @@ namespace TShockAPI
}
string playerNameToMatch = string.Join(" ", args.Parameters);
var matchedPlayers = TShock.Utils.FindPlayer(playerNameToMatch);
var matchedPlayers = TSPlayer.FindByNameOrID(playerNameToMatch);
if (matchedPlayers.Count < 1)
{
args.Player.SendErrorMessage("No players matched \"{0}\".", playerNameToMatch);
@ -1666,7 +1666,7 @@ namespace TShockAPI
}
else if (matchedPlayers.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, matchedPlayers.Select(p => p.Name));
args.Player.SendMultipleMatchError(matchedPlayers.Select(p => p.Name));
return;
}
@ -1696,10 +1696,10 @@ namespace TShockAPI
TSPlayer targetPlayer = args.Player;
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)
{
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
return;
}
else if (players.Count == 0)
@ -1777,7 +1777,7 @@ namespace TShockAPI
return;
}
List<TSPlayer> ply = TShock.Utils.FindPlayer(args.Parameters[0]);
List<TSPlayer> ply = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (ply.Count < 1)
{
args.Player.SendErrorMessage("Could not find player {0}.", args.Parameters[0]);
@ -1786,7 +1786,7 @@ namespace TShockAPI
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]))
@ -1810,7 +1810,7 @@ namespace TShockAPI
ply[0].tempGroupTimer.Start();
}
Group g = TShock.Utils.GetGroup(args.Parameters[1]);
Group g = TShock.Groups.GetGroupByName(args.Parameters[1]);
ply[0].tempGroup = g;
@ -2326,7 +2326,7 @@ namespace TShockAPI
}
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
{
@ -2396,11 +2396,11 @@ namespace TShockAPI
if (args.Parameters.Count == 1)
{
var players = TShock.Utils.FindPlayer(args.Parameters[0]);
var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else
{
var target = players[0];
@ -2425,13 +2425,13 @@ namespace TShockAPI
return;
}
var players1 = TShock.Utils.FindPlayer(args.Parameters[0]);
var players2 = TShock.Utils.FindPlayer(args.Parameters[1]);
var players1 = TSPlayer.FindByNameOrID(args.Parameters[0]);
var players2 = TSPlayer.FindByNameOrID(args.Parameters[1]);
if (players2.Count == 0)
args.Player.SendErrorMessage("Invalid player!");
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)
{
if (args.Parameters[0] == "*")
@ -2471,7 +2471,7 @@ namespace TShockAPI
args.Player.SendErrorMessage("Invalid player!");
}
else if (players1.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players1.Select(p => p.Name));
args.Player.SendMultipleMatchError(players1.Select(p => p.Name));
else
{
var source = players1[0];
@ -2520,7 +2520,7 @@ namespace TShockAPI
}
string playerName = String.Join(" ", args.Parameters);
var players = TShock.Utils.FindPlayer(playerName);
var players = TSPlayer.FindByNameOrID(playerName);
if (players.Count == 0)
{
if (playerName == "*")
@ -2544,7 +2544,7 @@ namespace TShockAPI
args.Player.SendErrorMessage("Invalid player!");
}
else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else
{
var plr = players[0];
@ -2583,7 +2583,7 @@ namespace TShockAPI
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;
}
if (matches.Count == 0)
@ -2605,14 +2605,14 @@ namespace TShockAPI
player = String.Join(" ", args.Parameters);
}
var players = TShock.Utils.FindPlayer(player);
var players = TSPlayer.FindByNameOrID(player);
if (players.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
}
else if (players.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
}
else
{
@ -2766,7 +2766,7 @@ namespace TShockAPI
return;
}
var foundplr = TShock.Utils.FindPlayer(args.Parameters[1]);
var foundplr = TSPlayer.FindByNameOrID(args.Parameters[1]);
if (foundplr.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
@ -2774,7 +2774,7 @@ namespace TShockAPI
}
else if (foundplr.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, foundplr.Select(p => p.Name));
args.Player.SendMultipleMatchError(foundplr.Select(p => p.Name));
return;
}
@ -3225,7 +3225,7 @@ namespace TShockAPI
args.Player.SendErrorMessage("Invalid group.");
return;
}
Group grp = TShock.Utils.GetGroup(args.Parameters[1]);
Group grp = TShock.Groups.GetGroupByName(args.Parameters[1]);
List<string> permissions = grp.TotalPermissions;
PaginationTools.SendPage(args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(permissions),
@ -3265,7 +3265,7 @@ namespace TShockAPI
}
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
{
@ -3291,7 +3291,7 @@ namespace TShockAPI
}
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
{
@ -3336,7 +3336,7 @@ namespace TShockAPI
}
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
{
@ -3362,7 +3362,7 @@ namespace TShockAPI
}
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
{
@ -3798,7 +3798,8 @@ namespace TShockAPI
private static void Reload(CommandArgs args)
{
TShock.Utils.Reload(args.Player);
TShock.Utils.Reload();
Hooks.GeneralHooks.OnReloadEvent(args.Player);
args.Player.SendSuccessMessage(
"Configuration, permissions, and regions reload complete. Some changes may require a server restart.");
@ -4075,14 +4076,14 @@ namespace TShockAPI
}
string plStr = args.Parameters[0];
var players = TShock.Utils.FindPlayer(plStr);
var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
}
else if (players.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
}
else
{
@ -4818,9 +4819,27 @@ namespace TShockAPI
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(
args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(TShock.Utils.GetPlayers(displayIdsRequested)),
args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(players),
new PaginationTools.Settings
{
IncludeHeader = false,
@ -4838,7 +4857,6 @@ namespace TShockAPI
else
{
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);
return;
}
@ -4929,14 +4947,14 @@ namespace TShockAPI
return;
}
var players = TShock.Utils.FindPlayer(args.Parameters[0]);
var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
}
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))
{
@ -4961,12 +4979,12 @@ namespace TShockAPI
private static void Motd(CommandArgs args)
{
TShock.Utils.ShowFileToUser(args.Player, FileTools.MotdPath);
args.Player.SendFileTextAsMessage(FileTools.MotdPath);
}
private static void Rules(CommandArgs args)
{
TShock.Utils.ShowFileToUser(args.Player, FileTools.RulesPath);
args.Player.SendFileTextAsMessage(FileTools.RulesPath);
}
private static void Whisper(CommandArgs args)
@ -4977,14 +4995,14 @@ namespace TShockAPI
return;
}
var players = TShock.Utils.FindPlayer(args.Parameters[0]);
var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
}
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)
{
@ -5029,11 +5047,11 @@ namespace TShockAPI
int annoy = 5;
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)
args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else
{
var ply = players[0];
@ -5049,11 +5067,11 @@ namespace TShockAPI
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}confuse <player>", Specifier);
return;
}
var players = TShock.Utils.FindPlayer(args.Parameters[0]);
var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else
{
var ply = players[0];
@ -5069,11 +5087,11 @@ namespace TShockAPI
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}rocket <player>", Specifier);
return;
}
var players = TShock.Utils.FindPlayer(args.Parameters[0]);
var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else
{
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);
return;
}
var players = TShock.Utils.FindPlayer(args.Parameters[0]);
var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
else
{
int type = 167;
@ -5266,14 +5284,14 @@ namespace TShockAPI
}
string plStr = String.Join(" ", args.Parameters);
var players = TShock.Utils.FindPlayer(plStr);
var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
}
else if (players.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
}
else
{
@ -5304,7 +5322,7 @@ namespace TShockAPI
}
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;
}
else
@ -5359,7 +5377,7 @@ namespace TShockAPI
}
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;
}
else
@ -5389,7 +5407,7 @@ namespace TShockAPI
if (prefixIds.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, prefixIds.Select(p => p.ToString()));
args.Player.SendMultipleMatchError(prefixIds.Select(p => p.ToString()));
return;
}
else if (prefixIds.Count == 0)
@ -5442,7 +5460,7 @@ namespace TShockAPI
}
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;
}
else if (args.Parameters[1].Length > 200)
@ -5507,7 +5525,7 @@ namespace TShockAPI
}
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
{
@ -5531,14 +5549,14 @@ namespace TShockAPI
if (item.type >= 1 && item.type < Main.maxItemTypes)
{
var players = TShock.Utils.FindPlayer(plStr);
var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
}
else if (players.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
}
else
{
@ -5577,7 +5595,7 @@ namespace TShockAPI
if (args.Parameters.Count > 0)
{
string plStr = String.Join(" ", args.Parameters);
var players = TShock.Utils.FindPlayer(plStr);
var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
@ -5585,7 +5603,7 @@ namespace TShockAPI
}
else if (players.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
return;
}
else
@ -5634,7 +5652,7 @@ namespace TShockAPI
}
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;
}
id = found[0];
@ -5662,7 +5680,7 @@ namespace TShockAPI
}
int id = 0;
int time = 60;
var foundplr = TShock.Utils.FindPlayer(args.Parameters[0]);
var foundplr = TSPlayer.FindByNameOrID(args.Parameters[0]);
if (foundplr.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
@ -5670,7 +5688,7 @@ namespace TShockAPI
}
else if (foundplr.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, foundplr.Select(p => p.Name));
args.Player.SendMultipleMatchError(foundplr.Select(p => p.Name));
return;
}
else
@ -5685,7 +5703,7 @@ namespace TShockAPI
}
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;
}
id = found[0];
@ -5794,7 +5812,7 @@ namespace TShockAPI
return;
}
string plStr = String.Join(" ", args.Parameters);
var players = TShock.Utils.FindPlayer(plStr);
var players = TSPlayer.FindByNameOrID(plStr);
if (players.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
@ -5802,7 +5820,7 @@ namespace TShockAPI
}
else if (players.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
args.Player.SendMultipleMatchError(players.Select(p => p.Name));
return;
}
else

View file

@ -294,6 +294,20 @@ namespace TShockAPI.DB
}
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>

View file

@ -434,7 +434,7 @@ namespace TShockAPI.DB
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.";
}
@ -454,7 +454,7 @@ namespace TShockAPI.DB
if (!GroupExists(name))
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
permissions.ForEach(p => group.AddPermission(p));
@ -477,7 +477,7 @@ namespace TShockAPI.DB
if (!GroupExists(name))
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
permissions.ForEach(p => group.RemovePermission(p));

View file

@ -26,7 +26,7 @@ namespace TShockAPI
public class FileTools
{
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>
/// Path to the file containing the rules.
/// </summary>
@ -154,7 +154,7 @@ namespace TShockAPI
{
if (string.IsNullOrWhiteSpace(line))
continue;
contains = TShock.Utils.GetIPv4Address(line).Equals(ip);
contains = TShock.Utils.GetIPv4AddressFromHostname(line).Equals(ip);
if (contains)
return true;
}

View file

@ -349,7 +349,7 @@ namespace TShockAPI
}
/// <summary>
/// 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>
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))
{
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;
}
if (name.Trim().Length == 0)
{
TShock.Utils.ForceKick(args.Player, "Empty Name.", true);
args.Player.Kick("You have been Bounced.", true, true);
return true;
}
if (args.Player.ReceivedInfo)
@ -1694,12 +1694,12 @@ namespace TShockAPI
}
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;
}
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;
}
args.Player.Difficulty = difficulty;
@ -1725,7 +1725,7 @@ namespace TShockAPI
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.tempGroup = null;
@ -1797,7 +1797,7 @@ namespace TShockAPI
args.Player.State = 2;
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.tempGroup = null;
@ -1829,9 +1829,10 @@ namespace TShockAPI
Hooks.PlayerHooks.OnPlayerPostLogin(args.Player);
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;
}
if (!string.IsNullOrEmpty(TShock.Config.ServerPassword))
{
if (TShock.Config.ServerPassword == password)
@ -1842,11 +1843,11 @@ namespace TShockAPI
NetMessage.SendData((int)PacketTypes.WorldInfo, args.Player.Index);
return true;
}
TShock.Utils.ForceKick(args.Player, "Incorrect server password", true);
args.Player.Kick("Invalid server password.", true, true);
return true;
}
TShock.Utils.ForceKick(args.Player, "Bad password attempt", true);
args.Player.Kick("You have been Bounced.", true, true);
return true;
}
@ -1891,10 +1892,10 @@ namespace TShockAPI
if (OnGetSection(args.Player, args.Data, args.Data.ReadInt32(), args.Data.ReadInt32()))
return true;
if (TShock.Utils.ActivePlayers() + 1 > TShock.Config.MaxSlots &&
if (TShock.Utils.GetActivePlayerCount() + 1 > TShock.Config.MaxSlots &&
!args.Player.HasPermission(Permissions.reservedslot))
{
TShock.Utils.ForceKick(args.Player, TShock.Config.ServerFullReason, true);
args.Player.Kick(TShock.Config.ServerFullReason, true, true);
return true;
}
@ -2383,12 +2384,12 @@ namespace TShockAPI
{
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 you are immune to bans.", true);
if (!args.Player.Ban(TShock.Config.HardcoreBanReason, false, "hardcore-death"))
args.Player.Kick("You died! Normally, you'd be banned.", true, true);
}
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.Utils.Ban(args.Player, TShock.Config.MediumcoreBanReason, false, "mediumcore-death"))
TShock.Utils.ForceKick(args.Player, "Death results in a ban, but you are immune to bans.", true);
if (!args.Player.Ban(TShock.Config.MediumcoreBanReason, false, "mediumcore-death"))
args.Player.Kick("You died! Normally, you'd be banned.", true, true);
}
else
{
TShock.Utils.ForceKick(args.Player, TShock.Config.MediumcoreKickReason, true, false);
args.Player.Kick(TShock.Config.MediumcoreKickReason, true, true, null, false);
}
return true;
}

View file

@ -339,7 +339,8 @@ namespace TShockAPI
[Token]
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.");
}
@ -410,7 +411,7 @@ namespace TShockAPI
var players = new ArrayList();
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)
players.Add(p);
}
@ -982,7 +983,7 @@ namespace TShockAPI
return 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");
}
@ -1002,7 +1003,7 @@ namespace TShockAPI
TSPlayer player = (TSPlayer)ret;
var reason = null == args.Parameters["reason"] ? "Banned via web" : args.Parameters["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");
}
@ -1244,7 +1245,7 @@ namespace TShockAPI
if (string.IsNullOrWhiteSpace(name))
return RestMissingParam("player");
var found = TShock.Utils.FindPlayer(name);
var found = TSPlayer.FindByNameOrID(name);
switch(found.Count)
{
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." };
}
Group userGroup = TShock.Utils.GetGroup(userAccount.Group);
Group userGroup = TShock.Groups.GetGroupByName(userAccount.Group);
if (!userGroup.HasPermission(RestPermissions.restapi) && userAccount.Group != "superadmin")
{
AddTokenToBucket(context.RemoteEndPoint.Address.ToString());

View file

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

View file

@ -34,6 +34,7 @@ using TShockAPI.DB;
using TShockAPI.Hooks;
using TShockAPI.Net;
using Timer = System.Timers.Timer;
using System.Linq;
namespace TShockAPI
{
@ -73,6 +74,43 @@ namespace TShockAPI
/// </summary>
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>
/// The amount of tiles that the player has killed in the last second.
/// </summary>
@ -1420,6 +1458,43 @@ namespace TShockAPI
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>
/// Wounds the player with the given damage.
/// </summary>
@ -1505,6 +1580,79 @@ namespace TShockAPI
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")]
private void LogStackFrame()
{

View file

@ -481,13 +481,13 @@ namespace TShockAPI
// And then get rid of them.
if (potentialBan.Expiration == "")
{
Utils.ForceKick(args.Player, String.Format("Permanently banned by {0} for {1}", potentialBan.BanningUser
,potentialBan.Reason), false, false);
args.Player.Kick(String.Format("Permanently banned by {0} for {1}", potentialBan.BanningUser
,potentialBan.Reason), true, true);
}
else
{
Utils.ForceKick(args.Player, String.Format("Still banned by {0} for {1}", potentialBan.BanningUser,
potentialBan.Reason), false, false);
args.Player.Kick(String.Format("Still banned by {0} for {1}", potentialBan.BanningUser,
potentialBan.Reason), true, true);
}
}
}
@ -1241,16 +1241,16 @@ namespace TShockAPI
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;
return;
}
if (!FileTools.OnWhitelist(player.IP))
{
Utils.ForceKick(player, Config.WhitelistKickReason, true, false);
player.Kick(Config.WhitelistKickReason, true, true, null, false);
args.Handled = true;
return;
}
@ -1263,7 +1263,7 @@ namespace TShockAPI
{
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;
return;
}
@ -1285,7 +1285,7 @@ namespace TShockAPI
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;
return;
}
@ -1310,7 +1310,7 @@ namespace TShockAPI
if (ban != null)
{
if (!Utils.HasBanExpired(ban))
if (!Bans.RemoveBanIfExpired(ban))
{
DateTime exp;
if (!DateTime.TryParse(ban.Expiration, out exp))
@ -1400,7 +1400,7 @@ namespace TShockAPI
}
// The last player will leave after this hook is executed.
if (Utils.ActivePlayers() == 1)
if (Utils.GetActivePlayerCount() == 1)
{
if (Config.SaveWorldOnLastPlayerExit)
SaveManager.Instance.SaveWorld();
@ -1424,7 +1424,7 @@ namespace TShockAPI
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;
return;
}
@ -1621,7 +1621,7 @@ namespace TShockAPI
if (Config.EnableGeoIP && TShock.Geo != null)
{
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);
if (!player.SilentJoinInProgress)
Utils.Broadcast(string.Format("{0} ({1}) has joined.", player.Name, player.Country), Color.Yellow);
@ -1629,7 +1629,7 @@ namespace TShockAPI
else
{
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)
Utils.Broadcast(player.Name + " has joined.", Color.Yellow);
}
@ -1637,7 +1637,7 @@ namespace TShockAPI
if (Config.DisplayIPToAdmins)
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();
if (pvpMode == "always")

View file

@ -69,52 +69,6 @@ namespace TShockAPI
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>
/// It's a clamp function
/// </summary>
@ -199,48 +153,11 @@ namespace TShockAPI
/// Gets the number of active players on the server.
/// </summary>
/// <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();
}
/// <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 r = new Random();
@ -536,21 +453,6 @@ namespace TShockAPI
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>
/// Stops the server after kicking all players with a reason message, and optionally saving the world
/// </summary>
@ -560,12 +462,10 @@ namespace TShockAPI
{
TShock.ShuttingDown = true;
ForceKickAll(reason);
if (save)
SaveManager.Instance.SaveWorld();
// Save takes a while so kick again
ForceKickAll(reason);
TSPlayer.All.Kick(reason, true, true, null, true);
// Broadcast so console can see we are shutting down as well
TShock.Utils.Broadcast(reason, Color.Red);
@ -577,7 +477,7 @@ namespace TShockAPI
/// <summary>
/// Reloads all configuration settings, groups, regions and raises the reload event.
/// </summary>
public void Reload(TSPlayer player)
public void Reload()
{
FileTools.SetupConfig();
TShock.HandleCommandLinePostConfigLoad(Environment.GetCommandLineArgs());
@ -586,156 +486,13 @@ namespace TShockAPI
TShock.Itembans.UpdateItemBans();
TShock.ProjectileBans.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>
/// Returns an IPv4 address from a DNS query
/// </summary>
/// <param name="hostname">string ip</param>
public string GetIPv4Address(string hostname)
public string GetIPv4AddressFromHostname(string hostname)
{
try
{
@ -750,28 +507,11 @@ namespace TShockAPI
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>
/// Checks if world has hit the max number of chests
/// </summary>
/// <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++)
{
@ -1377,7 +1117,7 @@ namespace TShockAPI
}
else
{
invasionSize = 100 + (TShock.Config.InvasionMultiplier * ActivePlayers());
invasionSize = 100 + (TShock.Config.InvasionMultiplier * GetActivePlayerCount());
}
// Order matters
@ -1411,12 +1151,12 @@ namespace TShockAPI
}
/// <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)
{
Console.Title = string.Format("{0}{1}/{2} on {3} @ {4}:{5} (TShock for Terraria v{6})",
!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);
}