New config to disable dungeon guardian and instead send players to spawn (stops hack abuse)

Changed AlwaysPvp to support new features better.
Now checking ItemAnimation for stuff.
Initial data structures for Server Side Inventory handling support.
This commit is contained in:
Zidonuke 2011-12-20 13:12:27 -05:00
parent 7263ff3a9b
commit ad22a379d9
6 changed files with 228 additions and 16 deletions

View file

@ -177,6 +177,12 @@ namespace TShockAPI
[Description("Disables hardmode, can't never be activated. Overrides /starthardmode")]
public bool DisableHardmode = false;
[Description("Disables Dungeon Guardian from being spawned by player packets, this will instead force a respawn")]
public bool DisableDungeonGuardian = false;
[Description("Enable Server Side Inventory checks, EXPERIMENTAL")]
public bool ServerSideInventory = false;
public static ConfigFile Read(string path)
{
if (!File.Exists(path))

View file

@ -0,0 +1,100 @@
/*
TShock, a server mod for Terraria
Copyright (C) 2011 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.Data;
using MySql.Data.MySqlClient;
using Terraria;
namespace TShockAPI.DB
{
public class InventoryManager
{
public IDbConnection database;
public InventoryManager(IDbConnection db)
{
database = db;
var table = new SqlTable("Inventory",
new SqlColumn("AccountName", MySqlDbType.VarChar, 32) { Primary = true },
new SqlColumn("CharacterName", MySqlDbType.VarChar, 50),
new SqlColumn("MaxHealth", MySqlDbType.Int32),
new SqlColumn("MaxMana", MySqlDbType.Int32),
new SqlColumn("Inventory", MySqlDbType.Text)
);
var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator());
creator.EnsureExists(table);
}
public PlayerData GetPlayerData(TSPlayer player)
{
PlayerData playerData = new PlayerData(player);
try
{
using (var reader = database.QueryReader("SELECT * FROM Inventory WHERE AccountName=@0 AND CharacterName=@1", player.UserAccountName, player.Name))
{
if (reader.Read())
{
playerData.exists = true;
playerData.maxHealth = reader.Get<int>("MaxHealth");
playerData.maxMana = reader.Get<int>("MaxMana");
playerData.inventory = NetItem.Parse(reader.Get<string>("Inventory"));
return playerData;
}
}
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
return playerData;
}
public void InsertPlayerData(TSPlayer player)
{
PlayerData playerData = player.PlayerData;
if (!GetPlayerData(player).exists)
{
try
{
database.Query("INSERT INTO Inventory (AccountName, CharacterName, MaxHealth, MaxMana, Inventory) VALUES (@0, @1, @2, @3, @4);", playerData.accountName, playerData.characterName, playerData.maxHealth, playerData.maxMana, NetItem.ToString(playerData.inventory));
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
else
{
try
{
database.Query("UPDATE Inventory SET MaxHealth = @0, MaxMana = @1, Inventory = @3 WHERE AccountName = @4 AND CharacterName = @5;", playerData.maxHealth, playerData.maxMana, NetItem.ToString(playerData.inventory), playerData.accountName, playerData.characterName);
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
}
}
}

View file

@ -90,6 +90,7 @@ namespace TShockAPI
{PacketTypes.PlayerDamage, HandlePlayerDamage},
{PacketTypes.NpcStrike, HandleNpcStrike},
{PacketTypes.NpcSpecial, HandleSpecial},
{PacketTypes.PlayerAnimation, HandlePlayerAnimation},
};
}
@ -254,7 +255,7 @@ namespace TShockAPI
return true;
}
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendTileSquare(tileX, tileY);
return true;
@ -470,7 +471,7 @@ namespace TShockAPI
}
}
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendTileSquare(tileX, tileY);
return true;
@ -520,6 +521,12 @@ namespace TShockAPI
}
args.TPlayer.hostile = pvp;
if (pvp == true && TShock.Config.AlwaysPvP)
args.Player.IgnoreActionsForPvP = false;
else
args.Player.IgnoreActionsForPvP = true;
NetMessage.SendData((int)PacketTypes.TogglePvp, -1, -1, "", args.Player.Index);
return true;
@ -551,9 +558,12 @@ namespace TShockAPI
if (!pos.Equals(args.Player.LastNetPosition))
{
float distance = Vector2.Distance(new Vector2((pos.X / 16f), (pos.Y / 16f)), new Vector2(Main.spawnTileX, Main.spawnTileY));
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile && distance > 6f)
if (TShock.CheckIgnores(args.Player) && distance > 6f)
{
args.Player.SendMessage("PvP is forced! Enable PvP else you can't do anything!", Color.Red);
if (TShock.Config.AlwaysPvP)
{
args.Player.SendMessage("PvP is forced! Enable PvP else you can't move or do anything!", Color.Red);
}
args.Player.Spawn();
return true;
}
@ -599,7 +609,7 @@ namespace TShockAPI
return true;
}
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendData(PacketTypes.ProjectileNew, "", index);
return true;
@ -640,7 +650,7 @@ namespace TShockAPI
return true;
}
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendData(PacketTypes.ProjectileNew, "", index);
return true;
@ -696,7 +706,7 @@ namespace TShockAPI
if (tileX < 0 || tileX >= Main.maxTilesX || tileY < 0 || tileY >= Main.maxTilesY)
return false;
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendTileSquare(tileX, tileY);
return true;
@ -751,7 +761,7 @@ namespace TShockAPI
if (tileX < 0 || tileX >= Main.maxTilesX || tileY < 0 || tileY >= Main.maxTilesY)
return false;
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendTileSquare(tileX, tileY);
return true;
@ -808,7 +818,7 @@ namespace TShockAPI
var x = args.Data.ReadInt32();
var y = args.Data.ReadInt32();
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
return true;
}
@ -833,7 +843,7 @@ namespace TShockAPI
return false;
}
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendData(PacketTypes.ChestItem, "", id, slot);
return true;
@ -907,7 +917,7 @@ namespace TShockAPI
var type = args.Data.ReadInt8();
var time = args.Data.ReadInt16();
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendData(PacketTypes.PlayerBuff, "", id);
return true;
@ -964,7 +974,7 @@ namespace TShockAPI
return true;
}
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendData(PacketTypes.ItemDrop, "", id);
return true;
@ -1009,7 +1019,7 @@ namespace TShockAPI
return true;
}
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendData(PacketTypes.PlayerHp, "", id);
args.Player.SendData(PacketTypes.PlayerUpdate, "", id);
@ -1050,7 +1060,7 @@ namespace TShockAPI
return true;
}
if (TShock.Config.AlwaysPvP && !args.TPlayer.hostile)
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendData(PacketTypes.NpcUpdate, "", id);
return true;
@ -1082,6 +1092,30 @@ namespace TShockAPI
var id = args.Data.ReadInt8();
var type = args.Data.ReadInt8();
if (type == 1 && TShock.Config.DisableDungeonGuardian)
{
args.Player.SendMessage("The Dungeon Guardian returned you to your spawn point", Color.Purple);
args.Player.Spawn();
return true;
}
return false;
}
private static bool HandlePlayerAnimation(GetDataHandlerArgs args)
{
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendData(PacketTypes.PlayerAnimation, "", args.Player.Index);
return true;
}
if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000)
{
args.Player.SendData(PacketTypes.PlayerAnimation, "", args.Player.Index);
return true;
}
return false;
}
}

View file

@ -64,6 +64,9 @@ namespace TShockAPI
public string Country = "??";
public int Difficulty;
private string CacheIP;
public bool IgnoreActionsForPvP = false;
public bool IgnoreActionsForInventory = false;
public PlayerData PlayerData;
public bool RealPlayer
{
@ -429,4 +432,52 @@ namespace TShockAPI
}
}
}
public class PlayerData
{
public NetItem[] inventory = new NetItem[NetItem.maxNetInventory];
public int maxHealth = 100;
public int maxMana = 100;
public string accountName;
public string characterName;
public bool exists = false;
public PlayerData(TSPlayer player)
{
this.accountName = player.UserAccountName;
this.characterName = player.Name;
this.inventory[0].netID = -15;
this.inventory[0].stack = 1;
if(player.TPlayer.inventory[0].netID == -15)
this.inventory[0].prefix = player.TPlayer.inventory[0].prefix;
this.inventory[1].netID = -13;
this.inventory[1].stack = 1;
if (player.TPlayer.inventory[1].netID == -13)
this.inventory[1].prefix = player.TPlayer.inventory[1].prefix;
this.inventory[2].netID = -16;
this.inventory[2].stack = 1;
if (player.TPlayer.inventory[2].netID == -16)
this.inventory[2].prefix = player.TPlayer.inventory[2].prefix;
}
}
public class NetItem
{
public static int maxNetInventory = 59;
public int netID = 0;
public int stack = 0;
public int prefix = 0;
public static string ToString(NetItem[] inventory)
{
string inventoryString = "";
return inventoryString;
}
public static NetItem[] Parse(string data)
{
NetItem[] inventory = new NetItem[NetItem.maxNetInventory];
return inventory;
}
}
}

View file

@ -62,6 +62,7 @@ namespace TShockAPI
public static UserManager Users;
public static ItemManager Itembans;
public static RemeberedPosManager RememberedPos;
public static InventoryManager Inventory;
public static ConfigFile Config { get; set; }
public static IDbConnection DB;
public static bool OverridePort;
@ -177,6 +178,7 @@ namespace TShockAPI
Regions = new RegionManager(DB);
Itembans = new ItemManager(DB);
RememberedPos = new RemeberedPosManager(DB);
Inventory = new InventoryManager(DB);
RestApi = new SecureRest(Netplay.serverListenIP, 8080);
RestApi.Verify += RestApi_Verify;
RestApi.Port = Config.RestApiPort;
@ -721,10 +723,12 @@ namespace TShockAPI
TShock.Utils.HandleCheater(player, "Health/Mana cheat detected. Please use a different character.");
}
NetMessage.syncPlayers();
if (Config.AlwaysPvP)
if (Config.AlwaysPvP && !player.TPlayer.hostile)
{
player.IgnoreActionsForPvP = true;
player.SendMessage("PvP is forced! Enable PvP else you can't move or do anything!", Color.Red);
}
if (player.Group.HasPermission(Permissions.causeevents) && Config.InfiniteInvasion)
@ -999,6 +1003,22 @@ namespace TShockAPI
(player.TPlayer.statLife > 400);
}
public static bool CheckInventory(TSPlayer player)
{
return false;
}
public static bool CheckIgnores(TSPlayer player)
{
bool check = false;
if (player.IgnoreActionsForPvP)
check = true;
if (player.IgnoreActionsForInventory)
check = true;
return check;
}
public static bool CheckPlayerCollision(int x, int y)
{
if (x + 1 <= Main.maxTilesX && y + 3 <= Main.maxTilesY

View file

@ -84,6 +84,7 @@
<ItemGroup>
<Compile Include="BackupManager.cs" />
<Compile Include="DB\BanManager.cs" />
<Compile Include="DB\InventoryManager.cs" />
<Compile Include="DB\IQueryBuilder.cs" />
<Compile Include="DB\ItemManager.cs" />
<Compile Include="DB\SqlColumn.cs" />
@ -180,7 +181,7 @@
</PropertyGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties BuildVersion_IncrementBeforeBuild="False" BuildVersion_StartDate="2011/6/17" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_BuildAction="Both" BuildVersion_UpdateFileVersion="True" BuildVersion_UpdateAssemblyVersion="True" />
<UserProperties BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" BuildVersion_BuildAction="Both" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_StartDate="2011/6/17" BuildVersion_IncrementBeforeBuild="False" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.