Merge pull request #1560 from Pryaxis/fragments
Fragments Part 1: Implement Bouncer infrastructure
This commit is contained in:
commit
4fa0f888ea
11 changed files with 2437 additions and 1971 deletions
23
CHANGELOG.md
23
CHANGELOG.md
|
|
@ -34,6 +34,29 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
|
|||
* Removed `Permissions.updateplugins` permission. (@hakusaro)
|
||||
* Removed REST `/v3/server/restart/` route and `/server/restart/` route. (@hakusaro)
|
||||
* The "auth system" is now referred to as the initial setup system (what it actually is). This is better verbiage for basically all situations. Who really wants to turn off the "authentication system?" In addition, the system now makes it more clear what the point of it is, rather than that it grants permissions. (@hakusaro)
|
||||
* `GetDataHandlers.SendTileSquare` hook now sends a `TSPlayer` and a `MemoryStream` of raw data. (@hakusaro)
|
||||
* Added `GetDataHandlers.HealOtherPlayer` hook. (@hakusaro)
|
||||
* Added `GetDataHandlers.PlaceObject` hook. (@hakusaro)
|
||||
* `GetDataHandlers.KillMe` now sends a `TSPlayer` and a `PlayerDeathReason`. (@hakusaro)
|
||||
* Added `GetDataHandlers.ProjectileKill` hook. (@hakusaro)
|
||||
* Removed `TShock.CheckProjectilePermission` and replaced it with `TSPlayer.HasProjectilePermission` and `TSPlayer.LacksProjectilePermission` respectively. (@hakusaro)
|
||||
* Added `TSPlayer` object to `GetDataHandlers.LiquidSetEventArgs`. (@hakusaro)
|
||||
* Removed `TShock.StartInvasion` for public use (moved to Utils and marked internal). (@hakusaro)
|
||||
* Fixed invasions started by TShock not reporting size correctly and probably not working at all. (@hakusaro)
|
||||
* Removed `GetDataHandlers.TileKill` and replaced it with `GetDataHandlers.PlaceChest` as the packet originally designated as tile kill is now only used for chests. (@hakusaro)
|
||||
* Added `TSPlayer` to `GetDataHandlers.NPCHome`. (@hakusaro)
|
||||
* Added `TSPlayer` to `GetDataHandlers.ChestItemChanged`. (@hakusaro)
|
||||
* Fixed chest item changes not triggering any range checks, tile checks, or correct chest checks. (@hakusaro)
|
||||
* Added `TSPlayer` to `GetDataHandlers.PlayerBuff`. (@hakusaro)
|
||||
* Added `TSPlayer` and `PlayerDeathReason` to `GetDataHandlers.PlayerDamage`. (@hakusaro)
|
||||
* Added `TSPlayer` to `GetDataHandlers.NPCStrike`. (@hakusaro)
|
||||
* Added `TSPlayer` to `GetDataHandlers.PlayerAnimation`. (@hakusaro)
|
||||
* Added `GetDataHandlers.MassWireOperation` hook and related arguments. (@hakusaro)
|
||||
* Added `GetDataHandlers.PlaceTileEntity` hook and related arguments. (@hakusaro)
|
||||
* Added `TSPlayer` to `GetDataHandlers.GemLockToggle`. (@hakusaro)
|
||||
* Added `GetDataHandlers.PlaceItemFrame` hook and related arguments. (@hakusaro)
|
||||
* Added `TSPlayer.IsBouncerThrottled()`. (@hakusaro)
|
||||
* Added `TSPlayer.CheckIgnores()` and removed `TShock.CheckIgnores(TSPlayer)`. (@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.
|
||||
|
|
|
|||
1827
TShockAPI/Bouncer.cs
Normal file
1827
TShockAPI/Bouncer.cs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -2044,19 +2044,19 @@ namespace TShockAPI
|
|||
case "goblin":
|
||||
case "goblins":
|
||||
TSPlayer.All.SendInfoMessage("{0} has started a goblin army invasion.", args.Player.Name);
|
||||
TShock.StartInvasion(1);
|
||||
TShock.Utils.StartInvasion(1);
|
||||
break;
|
||||
|
||||
case "snowman":
|
||||
case "snowmen":
|
||||
TSPlayer.All.SendInfoMessage("{0} has started a snow legion invasion.", args.Player.Name);
|
||||
TShock.StartInvasion(2);
|
||||
TShock.Utils.StartInvasion(2);
|
||||
break;
|
||||
|
||||
case "pirate":
|
||||
case "pirates":
|
||||
TSPlayer.All.SendInfoMessage("{0} has started a pirate invasion.", args.Player.Name);
|
||||
TShock.StartInvasion(3);
|
||||
TShock.Utils.StartInvasion(3);
|
||||
break;
|
||||
|
||||
case "pumpkin":
|
||||
|
|
@ -2098,7 +2098,7 @@ namespace TShockAPI
|
|||
case "martian":
|
||||
case "martians":
|
||||
TSPlayer.All.SendInfoMessage("{0} has started a martian invasion.", args.Player.Name);
|
||||
TShock.StartInvasion(4);
|
||||
TShock.Utils.StartInvasion(4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -285,6 +285,21 @@ namespace TShockAPI
|
|||
|
||||
public bool IgnoreActionsForClearingTrashCan;
|
||||
|
||||
/// <summary>Checks to see if active throttling is happening on events by Bouncer. Rejects repeated events by malicious clients in a short window.</summary>
|
||||
/// <returns>If the player is currently being throttled by Bouncer, or not.</returns>
|
||||
public bool IsBouncerThrottled()
|
||||
{
|
||||
return (DateTime.UtcNow - LastThreat).TotalMilliseconds < 5000;
|
||||
}
|
||||
|
||||
/// <summary>CheckIgnores - Checks a players ignores...?</summary>
|
||||
/// <param name="player">player - The TSPlayer object.</param>
|
||||
/// <returns>bool - True if any ignore is not none, false, or login state differs from the required state.</returns>
|
||||
public bool CheckIgnores()
|
||||
{
|
||||
return IgnoreActionsForInventory != "none" || IgnoreActionsForCheating != "none" || IgnoreActionsForDisabledArmor != "none" || IgnoreActionsForClearingTrashCan || !IsLoggedIn && TShock.Config.RequireLogin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The player's server side inventory data.
|
||||
/// </summary>
|
||||
|
|
@ -789,6 +804,48 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Checks to see if this player object has access rights to a given projectile. Used by projectile bans.</summary>
|
||||
/// <param name="index">The projectile index from Main.projectiles (NOT from a packet directly).</param>
|
||||
/// <param name="type">The type of projectile, from Main.projectiles.</param>
|
||||
/// <returns>If the player has access rights to the projectile.</returns>
|
||||
public bool HasProjectilePermission(int index, int type)
|
||||
{
|
||||
// Players never have the rights to tombstones.
|
||||
if (type == ProjectileID.Tombstone)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Dirt balls are the projectiles from dirt rods.
|
||||
// If the dirt rod item is banned, they probably shouldn't have this projectile.
|
||||
if (type == ProjectileID.DirtBall && TShock.Itembans.ItemIsBanned("Dirt Rod", this))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the sandgun is banned, block sand bullets.
|
||||
if (TShock.Itembans.ItemIsBanned("Sandgun", this))
|
||||
{
|
||||
if (type == ProjectileID.SandBallGun
|
||||
|| type == ProjectileID.EbonsandBallGun
|
||||
|| type == ProjectileID.PearlSandBallGun)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If the projectile is hostile, block it?
|
||||
Projectile tempProjectile = new Projectile();
|
||||
tempProjectile.SetDefaults(type);
|
||||
|
||||
if (Main.projHostile[type])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the projectile with the given index and owner.
|
||||
/// </summary>
|
||||
|
|
@ -808,6 +865,15 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Sends a tile square at a location with a given size.
|
||||
/// Typically used to revert changes by Bouncer through sending the
|
||||
/// "old" version of modified data back to a client.
|
||||
/// Prevents desync issues.
|
||||
/// </summary>
|
||||
/// <param name="x">The x coordinate to send.</param>
|
||||
/// <param name="y">The y coordinate to send.</param>
|
||||
/// <param name="size">The size square set of tiles to send.</param>
|
||||
/// <returns>Status if the tile square was sent successfully (i.e. no exceptions).</returns>
|
||||
public virtual bool SendTileSquare(int x, int y, int size = 10)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
public static Dictionary<string, SecureRest.TokenData> RESTStartupTokens = new Dictionary<string, SecureRest.TokenData>();
|
||||
|
||||
/// <summary>The TShock anti-cheat/anti-exploit system.</summary>
|
||||
internal Bouncer Bouncer;
|
||||
|
||||
/// <summary>
|
||||
/// Called after TShock is initialized. Useful for plugins that needs hooks before tshock but also depend on tshock being loaded.
|
||||
/// </summary>
|
||||
|
|
@ -322,6 +325,7 @@ namespace TShockAPI
|
|||
RestApi = new SecureRest(Netplay.ServerIP, Config.RestApiPort);
|
||||
RestManager = new RestManager(RestApi);
|
||||
RestManager.RegisterRestfulCommands();
|
||||
Bouncer = new Bouncer();
|
||||
|
||||
var geoippath = "GeoIP.dat";
|
||||
if (Config.EnableGeoIP && File.Exists(geoippath))
|
||||
|
|
@ -378,6 +382,7 @@ namespace TShockAPI
|
|||
Log.ConsoleInfo("Welcome to TShock for Terraria!");
|
||||
Log.ConsoleInfo("TShock comes with no warranty & is free software.");
|
||||
Log.ConsoleInfo("You can modify & distribute it under the terms of the GNU GPLv3.");
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -849,7 +854,7 @@ namespace TShockAPI
|
|||
/// <param name="args">args - The EventArgs object.</param>
|
||||
private void OnPostInit(EventArgs args)
|
||||
{
|
||||
SetConsoleTitle(false);
|
||||
Utils.SetConsoleTitle(false);
|
||||
|
||||
//This is to prevent a bug where a CLI-defined password causes packets to be
|
||||
//sent in an unexpected order, resulting in clients being unable to connect
|
||||
|
|
@ -902,8 +907,8 @@ namespace TShockAPI
|
|||
Regions.Reload();
|
||||
Warps.ReloadWarps();
|
||||
|
||||
ComputeMaxStyles();
|
||||
FixChestStacks();
|
||||
Utils.ComputeMaxStyles();
|
||||
Utils.FixChestStacks();
|
||||
|
||||
Utils.UpgradeMotD();
|
||||
|
||||
|
|
@ -916,45 +921,6 @@ namespace TShockAPI
|
|||
StatTracker.Start();
|
||||
}
|
||||
|
||||
/// <summary>ComputeMaxStyles - Computes the max styles...</summary>
|
||||
private void ComputeMaxStyles()
|
||||
{
|
||||
var item = new Item();
|
||||
for (int i = 0; i < Main.maxItemTypes; i++)
|
||||
{
|
||||
item.netDefaults(i);
|
||||
if (item.placeStyle > 0)
|
||||
{
|
||||
if (GetDataHandlers.MaxPlaceStyles.ContainsKey(item.createTile))
|
||||
{
|
||||
if (item.placeStyle > GetDataHandlers.MaxPlaceStyles[item.createTile])
|
||||
GetDataHandlers.MaxPlaceStyles[item.createTile] = item.placeStyle;
|
||||
}
|
||||
else
|
||||
GetDataHandlers.MaxPlaceStyles.Add(item.createTile, item.placeStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>FixChestStacks - Verifies that each stack in each chest is valid and not over the max stack count.</summary>
|
||||
private void FixChestStacks()
|
||||
{
|
||||
if (Config.IgnoreChestStacksOnLoad)
|
||||
return;
|
||||
|
||||
foreach (Chest chest in Main.chest)
|
||||
{
|
||||
if (chest != null)
|
||||
{
|
||||
foreach (Item item in chest.item)
|
||||
{
|
||||
if (item != null && item.stack > item.maxStack)
|
||||
item.stack = item.maxStack;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>LastCheck - Used to keep track of the last check for basically all time based checks.</summary>
|
||||
private DateTime LastCheck = DateTime.UtcNow;
|
||||
|
||||
|
|
@ -1117,7 +1083,7 @@ namespace TShockAPI
|
|||
|
||||
if (Main.ServerSideCharacter && !player.IsLoggedIn)
|
||||
{
|
||||
if (CheckIgnores(player))
|
||||
if (player.CheckIgnores())
|
||||
{
|
||||
player.Disable(flags: flags);
|
||||
}
|
||||
|
|
@ -1197,7 +1163,7 @@ namespace TShockAPI
|
|||
}
|
||||
player.IgnoreActionsForDisabledArmor = check;
|
||||
|
||||
if (CheckIgnores(player))
|
||||
if (player.CheckIgnores())
|
||||
{
|
||||
player.Disable(flags: flags);
|
||||
}
|
||||
|
|
@ -1225,17 +1191,7 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
}
|
||||
SetConsoleTitle(false);
|
||||
}
|
||||
|
||||
/// <summary>SetConsoleTitle - Updates the console title with some pertinent information.</summary>
|
||||
/// <param name="empty">empty - True/false if the server is empty; determines if we should use Utils.ActivePlayers() for player count or 0.</param>
|
||||
private void SetConsoleTitle(bool empty)
|
||||
{
|
||||
Console.Title = string.Format("{0}{1}/{2} on {3} @ {4}:{5} (TShock for Terraria v{6})",
|
||||
!string.IsNullOrWhiteSpace(Config.ServerName) ? Config.ServerName + " - " : "",
|
||||
empty ? 0 : Utils.ActivePlayers(),
|
||||
Config.MaxSlots, Main.worldName, Netplay.ServerIP.ToString(), Netplay.ListenPort, Version);
|
||||
Utils.SetConsoleTitle(false);
|
||||
}
|
||||
|
||||
/// <summary>OnHardUpdate - Fired when a hardmode tile update event happens.</summary>
|
||||
|
|
@ -1481,7 +1437,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (Config.SaveWorldOnLastPlayerExit)
|
||||
SaveManager.Instance.SaveWorld();
|
||||
SetConsoleTitle(true);
|
||||
Utils.SetConsoleTitle(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1802,62 +1758,7 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
|
||||
/// <summary>StartInvasion - Starts an invasion on the server.</summary>
|
||||
/// <param name="type">type - The invasion type id.</param>
|
||||
//TODO: Why is this in TShock's main class?
|
||||
public static void StartInvasion(int type)
|
||||
{
|
||||
int invasionSize = 0;
|
||||
|
||||
if (Config.InfiniteInvasion)
|
||||
{
|
||||
invasionSize = 20000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
invasionSize = 100 + (Config.InvasionMultiplier * Utils.ActivePlayers());
|
||||
}
|
||||
|
||||
// Note: This is a workaround to previously providing the size as a parameter in StartInvasion
|
||||
Main.invasionSize = invasionSize;
|
||||
|
||||
Main.StartInvasion(type);
|
||||
}
|
||||
|
||||
/// <summary>CheckProjectilePermission - Checks if a projectile is banned.</summary>
|
||||
/// <param name="player">player - The TSPlayer object that created the projectile.</param>
|
||||
/// <param name="index">index - The projectile index.</param>
|
||||
/// <param name="type">type - The projectile type.</param>
|
||||
/// <returns>bool - True if the player does not have permission to use a projectile.</returns>
|
||||
public static bool CheckProjectilePermission(TSPlayer player, int index, int type)
|
||||
{
|
||||
if (type == 43)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type == 17 && Itembans.ItemIsBanned("Dirt Rod", player))
|
||||
//Dirt Rod Projectile
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((type == 42 || type == 65 || type == 68) && Itembans.ItemIsBanned("Sandgun", player)) //Sandgun Projectiles
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Projectile proj = new Projectile();
|
||||
proj.SetDefaults(type);
|
||||
|
||||
if (Main.projHostile[type])
|
||||
{
|
||||
//player.SendMessage( proj.name, Color.Yellow);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>CheckRangePermission - Checks if a player has permission to modify a tile dependent on range checks.</summary>
|
||||
/// <param name="player">player - The TSPlayer object.</param>
|
||||
|
|
@ -2034,19 +1935,17 @@ namespace TShockAPI
|
|||
{
|
||||
Vector2 tile = new Vector2(x, y);
|
||||
Vector2 spawn = new Vector2(Main.spawnTileX, Main.spawnTileY);
|
||||
return Distance(spawn, tile) <= Config.SpawnProtectionRadius;
|
||||
return Utils.Distance(spawn, tile) <= Config.SpawnProtectionRadius;
|
||||
}
|
||||
|
||||
/// <summary>Distance - Determines the distance between two vectors.</summary>
|
||||
/// <param name="value1">value1 - The first vector location.</param>
|
||||
/// <param name="value2">value2 - The second vector location.</param>
|
||||
/// <returns>float - The distance between the two vectors.</returns>
|
||||
[Obsolete("Use TShock.Utils.Distance(Vector2, Vector2) instead.", true)]
|
||||
public static float Distance(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
float num2 = value1.X - value2.X;
|
||||
float num = value1.Y - value2.Y;
|
||||
float num3 = (num2 * num2) + (num * num);
|
||||
return (float)Math.Sqrt(num3);
|
||||
return Utils.Distance(value1, value2);
|
||||
}
|
||||
|
||||
/// <summary>HackedInventory - Checks to see if a user has a hacked inventory. In addition, messages players the result.</summary>
|
||||
|
|
@ -2246,14 +2145,6 @@ namespace TShockAPI
|
|||
return check;
|
||||
}
|
||||
|
||||
/// <summary>CheckIgnores - Checks a players ignores...?</summary>
|
||||
/// <param name="player">player - The TSPlayer object.</param>
|
||||
/// <returns>bool - True if any ignore is not none, false, or login state differs from the required state.</returns>
|
||||
public static bool CheckIgnores(TSPlayer player)
|
||||
{
|
||||
return player.IgnoreActionsForInventory != "none" || player.IgnoreActionsForCheating != "none" || player.IgnoreActionsForDisabledArmor != "none" || player.IgnoreActionsForClearingTrashCan || !player.IsLoggedIn && Config.RequireLogin;
|
||||
}
|
||||
|
||||
/// <summary>OnConfigRead - Fired when the config file has been read.</summary>
|
||||
/// <param name="file">file - The config file object.</param>
|
||||
public void OnConfigRead(ConfigFile file)
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@
|
|||
<Compile Include="Net\WorldInfoMsg.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="DB\RememberedPosManager.cs" />
|
||||
<Compile Include="Bouncer.cs" />
|
||||
<Compile Include="Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
|
|
|
|||
|
|
@ -925,7 +925,7 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
/// <param name="identity">identity</param>
|
||||
/// <param name="owner">owner</param>
|
||||
/// <returns>projectile ID</returns>
|
||||
/// <returns>projectile ID or -1 if not found</returns>
|
||||
public int SearchProjectile(short identity, int owner)
|
||||
{
|
||||
for (int i = 0; i < Main.maxProjectiles; i++)
|
||||
|
|
@ -933,7 +933,7 @@ namespace TShockAPI
|
|||
if (Main.projectile[i].identity == identity && Main.projectile[i].owner == owner)
|
||||
return i;
|
||||
}
|
||||
return 1000;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -1456,5 +1456,93 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Starts an invasion on the server.</summary>
|
||||
/// <param name="type">The invasion type id.</param>
|
||||
internal void StartInvasion(int type)
|
||||
{
|
||||
int invasionSize = 0;
|
||||
|
||||
if (TShock.Config.InfiniteInvasion)
|
||||
{
|
||||
// Not really an infinite size
|
||||
invasionSize = 20000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
invasionSize = 100 + (TShock.Config.InvasionMultiplier * ActivePlayers());
|
||||
}
|
||||
|
||||
// Order matters
|
||||
// StartInvasion will reset the invasion size
|
||||
|
||||
Main.StartInvasion(type);
|
||||
|
||||
// Note: This is a workaround to previously providing the size as a parameter in StartInvasion
|
||||
// Have to set start size to report progress correctly
|
||||
Main.invasionSizeStart = invasionSize;
|
||||
Main.invasionSize = invasionSize;
|
||||
}
|
||||
|
||||
/// <summary>Verifies that each stack in each chest is valid and not over the max stack count.</summary>
|
||||
internal void FixChestStacks()
|
||||
{
|
||||
if (TShock.Config.IgnoreChestStacksOnLoad)
|
||||
return;
|
||||
|
||||
foreach (Chest chest in Main.chest)
|
||||
{
|
||||
if (chest != null)
|
||||
{
|
||||
foreach (Item item in chest.item)
|
||||
{
|
||||
if (item != null && item.stack > item.maxStack)
|
||||
item.stack = item.maxStack;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <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>
|
||||
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(),
|
||||
TShock.Config.MaxSlots, Main.worldName, Netplay.ServerIP.ToString(), Netplay.ListenPort, TShock.VersionNum);
|
||||
}
|
||||
|
||||
/// <summary>Determines the distance between two vectors.</summary>
|
||||
/// <param name="value1">The first vector location.</param>
|
||||
/// <param name="value2">The second vector location.</param>
|
||||
/// <returns>The distance between the two vectors.</returns>
|
||||
public static float Distance(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
float num2 = value1.X - value2.X;
|
||||
float num = value1.Y - value2.Y;
|
||||
float num3 = (num2 * num2) + (num * num);
|
||||
return (float)Math.Sqrt(num3);
|
||||
}
|
||||
|
||||
/// <summary>Computes the max styles...</summary>
|
||||
internal void ComputeMaxStyles()
|
||||
{
|
||||
var item = new Item();
|
||||
for (int i = 0; i < Main.maxItemTypes; i++)
|
||||
{
|
||||
item.netDefaults(i);
|
||||
if (item.placeStyle > 0)
|
||||
{
|
||||
if (GetDataHandlers.MaxPlaceStyles.ContainsKey(item.createTile))
|
||||
{
|
||||
if (item.placeStyle > GetDataHandlers.MaxPlaceStyles[item.createTile])
|
||||
GetDataHandlers.MaxPlaceStyles[item.createTile] = item.placeStyle;
|
||||
}
|
||||
else
|
||||
GetDataHandlers.MaxPlaceStyles.Add(item.createTile, item.placeStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2016 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ClassLibrary1")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Multiplay")]
|
||||
[assembly: AssemblyProduct("ClassLibrary1")]
|
||||
[assembly: AssemblyCopyright("Copyright © Multiplay 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("c6aed7ee-6282-49a2-8177-b79cad20d6d3")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2016 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.VisualStudio.TestTools.WebTesting;
|
||||
using Microsoft.VisualStudio.TestTools.WebTesting.Rules;
|
||||
using Rests;
|
||||
|
||||
namespace TshockRestTestPlugin
|
||||
{
|
||||
[DisplayName("JSON Status")]
|
||||
[Description("Checks to see the that the JSON response has the specified status response")]
|
||||
public class JsonValidateStatus : JsonValidate
|
||||
{
|
||||
public override void Validate(object sender, ValidationEventArgs e)
|
||||
{
|
||||
if (null != ValidateJson(sender, e))
|
||||
e.IsValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
[DisplayName("JSON Regexp Property")]
|
||||
[Description("Checks to see the that the JSON response contains the specified property and is matches the specified regexp")]
|
||||
public class JsonValidateRegexpProperty : JsonValidateProperty
|
||||
{
|
||||
// The name of the desired JSON property
|
||||
[DisplayName("Regexp")]
|
||||
[DefaultValue(true)]
|
||||
public new bool UseRegularExpression { get { return base.UseRegularExpression; } set { base.UseRegularExpression = value; } }
|
||||
}
|
||||
|
||||
[DisplayName("JSON Error")]
|
||||
[Description("Checks to see the that the JSON response contains the specified error")]
|
||||
public class JsonValidateError : JsonValidateProperty
|
||||
{
|
||||
// The status of the JSON request
|
||||
[DisplayName("JSON Status")]
|
||||
[DefaultValue("400")]
|
||||
public new string JSonStatus { get { return base.JSonStatus; } set { base.JSonStatus = value; } }
|
||||
|
||||
// The name of the desired JSON property
|
||||
[DisplayName("Property")]
|
||||
[DefaultValue("error")]
|
||||
public new string PropertyName { get { return base.PropertyName; } set { base.PropertyName = value; } }
|
||||
}
|
||||
|
||||
[DisplayName("JSON Missing Parameter")]
|
||||
[Description("Checks to see the that the JSON response indicates a missing or invalid parameter")]
|
||||
public class JsonValidateMissingParameter : JsonValidateError
|
||||
{
|
||||
// The value of the desired JSON property
|
||||
[DisplayName("Missing Value")]
|
||||
public new string PropertyValue { get { return base.PropertyValue; } set { base.PropertyValue = String.Format("Missing or empty {0} parameter", value); } }
|
||||
}
|
||||
|
||||
[DisplayName("JSON Invalid Parameter")]
|
||||
[Description("Checks to see the that the JSON response indicates a missing or invalid parameter")]
|
||||
public class JsonValidateInvalidParameter : JsonValidateError
|
||||
{
|
||||
// The value of the desired JSON property
|
||||
[DisplayName("Invalid Value")]
|
||||
public new string PropertyValue { get { return base.PropertyValue; } set { base.PropertyValue = String.Format("Missing or invalid {0} parameter", value); } }
|
||||
}
|
||||
|
||||
[DisplayName("JSON Response")]
|
||||
[Description("Checks to see the that the JSON response contains the specified message")]
|
||||
public class JsonValidateResponse : JsonValidateProperty
|
||||
{
|
||||
// The name of the desired JSON property
|
||||
[DisplayName("Response")]
|
||||
[DefaultValue("response")]
|
||||
public new string PropertyName { get { return base.PropertyName; } set { base.PropertyName = value; } }
|
||||
}
|
||||
|
||||
[DisplayName("JSON Property")]
|
||||
[Description("Checks to see the that the JSON response contains the specified property and is set to the specified value")]
|
||||
public class JsonValidateProperty : JsonValidate
|
||||
{
|
||||
// The name of the desired JSON property
|
||||
[DisplayName("Property")]
|
||||
public string PropertyName { get; set; }
|
||||
|
||||
// The value of the desired JSON property
|
||||
[DisplayName("Value")]
|
||||
public string PropertyValue { get; set; }
|
||||
|
||||
// Is the value a regexp of the desired JSON property
|
||||
[DisplayName("Regexp")]
|
||||
[DefaultValue(false)]
|
||||
public bool UseRegularExpression { get; set; }
|
||||
|
||||
public override void Validate(object sender, ValidationEventArgs e)
|
||||
{
|
||||
RestObject response = ValidateJson(sender, e);
|
||||
if (null == response)
|
||||
return;
|
||||
|
||||
if (null == response[PropertyName])
|
||||
{
|
||||
e.Message = String.Format("{0} Not Found", PropertyName);
|
||||
e.IsValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (UseRegularExpression)
|
||||
{
|
||||
var re = new Regex(PropertyValue);
|
||||
if (!re.IsMatch((string)response[PropertyName]))
|
||||
{
|
||||
e.Message = String.Format("{0} => '{1}' !~ '{2}'", PropertyName, response[PropertyName], PropertyValue);
|
||||
e.IsValid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PropertyValue != (string)response[PropertyName])
|
||||
{
|
||||
e.Message = String.Format("{0} => '{1}' != '{2}'", PropertyName, response[PropertyName], PropertyValue);
|
||||
e.IsValid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
e.IsValid = true;
|
||||
//e.WebTest.Context.Add(ContextParameterName, propertyValue);
|
||||
}
|
||||
}
|
||||
|
||||
[DisplayName("JSON Has Properties")]
|
||||
[Description("Checks to see the that the JSON response contains the specified properties (comma seperated)")]
|
||||
public class JsonHasProperties : JsonValidate
|
||||
{
|
||||
// The name of the desired JSON properties to check
|
||||
[DisplayName("Properties")]
|
||||
[Description("A comma seperated list of property names to check exist")]
|
||||
public string PropertyNames { get; set; }
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
public override void Validate(object sender, ValidationEventArgs e)
|
||||
{
|
||||
RestObject response = ValidateJson(sender, e);
|
||||
if (null == response)
|
||||
return;
|
||||
foreach (var p in PropertyNames.Split(','))
|
||||
{
|
||||
if (null == response[p])
|
||||
{
|
||||
e.Message = String.Format("'{0}' Not Found", p);
|
||||
e.IsValid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
e.IsValid = true;
|
||||
|
||||
//e.WebTest.Context.Add(ContextParameterName, propertyValue);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class JsonValidate : ValidationRule
|
||||
{
|
||||
// The status of the JSON request
|
||||
[DisplayName("JSON Status")]
|
||||
[DefaultValue("200")]
|
||||
public string JSonStatus { get; set; }
|
||||
|
||||
public RestObject ValidateJson(object sender, ValidationEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.Response.BodyString))
|
||||
{
|
||||
e.IsValid = false;
|
||||
e.Message = String.Format("Empty or null response {0}", e.Response.StatusCode);
|
||||
return null;
|
||||
}
|
||||
JavaScriptSerializer serialiser = new JavaScriptSerializer();
|
||||
//dynamic data = serialiser.Deserialize<dynamic>(e.Response.BodyString);
|
||||
RestObject response = serialiser.Deserialize<RestObject>(e.Response.BodyString);
|
||||
|
||||
if (JSonStatus != response.Status)
|
||||
{
|
||||
e.IsValid = false;
|
||||
e.Message = String.Format("Response Status '{0}' not '{1}'", response.Status, JSonStatus);
|
||||
return null;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{F2FEDAFB-58DE-4611-9168-A86112C346C7}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>TshockRestTestPlugin</RootNamespace>
|
||||
<AssemblyName>TshockRestTestPlugin</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.WebTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="TShockRestTestPlugin.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\TShockAPI\TShockAPI.csproj">
|
||||
<Project>{49606449-072B-4CF5-8088-AA49DA586694}</Project>
|
||||
<Name>TShockAPI</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
Loading…
Add table
Add a link
Reference in a new issue