Merge branch 'general-devel'

This commit is contained in:
Lucas Nicodemus 2015-02-21 15:29:18 -07:00
commit 31f0804a4e
78 changed files with 3462 additions and 4274 deletions

1
.gitmodules vendored
View file

@ -1,3 +1,4 @@
[submodule "TerrariaServerAPI"] [submodule "TerrariaServerAPI"]
path = TerrariaServerAPI path = TerrariaServerAPI
url = https://github.com/Deathmax/TerrariaAPI-Server.git url = https://github.com/Deathmax/TerrariaAPI-Server.git
ignore = dirty

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<TestSettings name="Local" id="943ada2e-478e-45be-b4b8-6f7d6d949602" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Description>These are default test settings for a local test run.</Description>
<Deployment enabled="false" />
<Execution>
<TestTypeSpecific />
<AgentRule name="Execution Agents">
</AgentRule>
</Execution>
</TestSettings>

View file

@ -1,3 +1,8 @@
# Current Status
This project is in maintenance mode. This means that the core team of developers' time is very limited, and only extremely game breaking bugs will be fixed. Improvements, new features, and minor issues will not be resolved by direct development until this time restriction has passed. Issues created reflecting these requests will not be worked on until this notice is removed.
Thanks for your continued support of TShock for Terraria.
# TShock [![Build Status](https://travis-ci.org/NyxStudios/TShock.png?branch=general-devel)](https://travis-ci.org/NyxStudios/TShock) # TShock [![Build Status](https://travis-ci.org/NyxStudios/TShock.png?branch=general-devel)](https://travis-ci.org/NyxStudios/TShock)
TShock is a server modification for Terraria, written in C#, and based upon the [Terraria Server API](https://github.com/Deathmax/TerrariaAPI-Server). It uses JSON for configuration management, and offers several features not present in the Terraria Server normally. TShock is a server modification for Terraria, written in C#, and based upon the [Terraria Server API](https://github.com/Deathmax/TerrariaAPI-Server). It uses JSON for configuration management, and offers several features not present in the Terraria Server normally.

View file

@ -2,15 +2,9 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2010 # Visual Studio 2010
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{755F5B05-0924-47E9-9563-26EB20FE3F67}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{755F5B05-0924-47E9-9563-26EB20FE3F67}"
ProjectSection(SolutionItems) = preProject
Local.testsettings = Local.testsettings
Terraria.vsmdi = Terraria.vsmdi
EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TShockAPI", "TShockAPI\TShockAPI.csproj", "{49606449-072B-4CF5-8088-AA49DA586694}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TShockAPI", "TShockAPI\TShockAPI.csproj", "{49606449-072B-4CF5-8088-AA49DA586694}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{F3742F51-D7BF-4754-A68A-CD944D2A21FF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TShockRestTestPlugin", "TShockRestTestPlugin\TShockRestTestPlugin.csproj", "{F2FEDAFB-58DE-4611-9168-A86112C346C7}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TShockRestTestPlugin", "TShockRestTestPlugin\TShockRestTestPlugin.csproj", "{F2FEDAFB-58DE-4611-9168-A86112C346C7}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TerrariaAPI-Server", "TerrariaServerAPI\TerrariaAPI-Server.csproj", "{549A7941-D9C9-4544-BAC8-D9EEEAB4D777}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TerrariaAPI-Server", "TerrariaServerAPI\TerrariaAPI-Server.csproj", "{549A7941-D9C9-4544-BAC8-D9EEEAB4D777}"
@ -38,12 +32,6 @@ Global
{49606449-072B-4CF5-8088-AA49DA586694}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {49606449-072B-4CF5-8088-AA49DA586694}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{49606449-072B-4CF5-8088-AA49DA586694}.Release|Mixed Platforms.Build.0 = Release|Any CPU {49606449-072B-4CF5-8088-AA49DA586694}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{49606449-072B-4CF5-8088-AA49DA586694}.Release|x86.ActiveCfg = Release|Any CPU {49606449-072B-4CF5-8088-AA49DA586694}.Release|x86.ActiveCfg = Release|Any CPU
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Debug|x86.ActiveCfg = Debug|Any CPU
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Release|x86.ActiveCfg = Release|Any CPU
{F2FEDAFB-58DE-4611-9168-A86112C346C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F2FEDAFB-58DE-4611-9168-A86112C346C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F2FEDAFB-58DE-4611-9168-A86112C346C7}.Debug|Any CPU.Build.0 = Debug|Any CPU {F2FEDAFB-58DE-4611-9168-A86112C346C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2FEDAFB-58DE-4611-9168-A86112C346C7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {F2FEDAFB-58DE-4611-9168-A86112C346C7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -31,255 +31,365 @@ namespace TShockAPI
{ {
[Description( [Description(
"The equation for calculating invasion size is 100 + (multiplier * (number of active players with greater than 200 health))." "The equation for calculating invasion size is 100 + (multiplier * (number of active players with greater than 200 health))."
)] public int InvasionMultiplier = 1; )]
public int InvasionMultiplier = 1;
[Description("The default maximum mobs that will spawn per wave. Higher means more mobs in that wave.")] public int [Description("The default maximum mobs that will spawn per wave. Higher means more mobs in that wave.")]
DefaultMaximumSpawns = 5; public int DefaultMaximumSpawns = 5;
[Description("The delay between waves. Lower values lead to more mobs.")] public int DefaultSpawnRate = 600; [Description("The delay between waves. Lower values lead to more mobs.")]
[Description("The port the server runs on.")] public int ServerPort = 7777; public int DefaultSpawnRate = 600;
[Description("Enable or disable the whitelist based on IP addresses in whitelist.txt")] public bool EnableWhitelist; [Description("The port the server runs on.")]
public int ServerPort = 7777;
[Description("Enable or disable the whitelist based on IP addresses in whitelist.txt")]
public bool EnableWhitelist;
[Description( [Description(
"Enable the ability for invasion size to never decrease. Make sure to run /invade, and note that this adds 2 million+ goblins to the spawn queue for the map." "Enable the ability for invasion size to never decrease. Make sure to run /invade, and note that this adds 2 million+ goblins to the spawn queue for the map."
)] public bool InfiniteInvasion; )]
public bool InfiniteInvasion;
[Description("Set the server pvp mode. Valid types are, \"normal\", \"always\", and \"disabled.\"")] public string PvPMode [Description("Set the server pvp mode. Valid types are, \"normal\", \"always\", and \"disabled.\"")]
public string PvPMode
= "normal"; = "normal";
[Description("Prevents tiles from being placed within SpawnProtectionRadius of the default spawn.")] public bool [Description("Prevents tiles from being placed within SpawnProtectionRadius of the default spawn.")]
SpawnProtection = true; public bool SpawnProtection = true;
[Description("Radius from spawn tile for SpawnProtection.")] public int SpawnProtectionRadius = 10; [Description("Radius from spawn tile for SpawnProtection.")]
public int SpawnProtectionRadius = 10;
[Description( [Description(
"Max slots for the server. If you want people to be kicked with \"Server is full\" set this to how many players you want max and then set Terraria max players to 2 higher." "Max slots for the server. If you want people to be kicked with \"Server is full\" set this to how many players you want max and then set Terraria max players to 2 higher."
)] public int MaxSlots = 8; )]
public int MaxSlots = 8;
[Description("Global protection agent for any block distance based anti-grief check.")] public bool RangeChecks = true; [Description("Global protection agent for any block distance based anti-grief check.")]
[Description("Disables any building; placing of blocks")] public bool DisableBuild; public bool RangeChecks = true;
[Description("Disables any building; placing of blocks")]
public bool DisableBuild;
[Description("#.#.#. = Red/Blue/Green - RGB Colors for the Admin Chat Color. Max value: 255")] public float[] [Description("#.#.#. = Red/Blue/Green - RGB Colors for the Admin Chat Color. Max value: 255")]
SuperAdminChatRGB = {255, 0, 0}; public float[] SuperAdminChatRGB = { 255, 0, 0 };
[Description("Super admin group chat prefix")] public string SuperAdminChatPrefix = "(Admin) "; [Description("Super admin group chat prefix")]
[Description("Super admin group chat suffix")] public string SuperAdminChatSuffix = ""; public string SuperAdminChatPrefix = "(Admin) ";
[Description("Super admin group chat suffix")]
public string SuperAdminChatSuffix = "";
[Description( [Description(
"Backup frequency in minutes. So, a value of 60 = 60 minutes. Backups are stored in the \\tshock\\backups folder.")] public int BackupInterval; "Backup frequency in minutes. So, a value of 60 = 60 minutes. Backups are stored in the \\tshock\\backups folder.")]
public int BackupInterval;
[Description("How long backups are kept in minutes. 2880 = 2 days.")] public int BackupKeepFor = 60; [Description("How long backups are kept in minutes. 2880 = 2 days.")]
public int BackupKeepFor = 60;
[Description( [Description(
"Remembers where a player left off. It works by remembering the IP, NOT the character. \neg. When you try to disconnect, and reconnect to be automatically placed at spawn, you'll be at your last location. Note: Won't save after server restarts." "Remembers where a player left off. It works by remembering the IP, NOT the character. \neg. When you try to disconnect, and reconnect to be automatically placed at spawn, you'll be at your last location. Note: Won't save after server restarts."
)] public bool RememberLeavePos; )]
public bool RememberLeavePos;
[Description("Hardcore players ONLY. This means softcore players cannot join.")] public bool HardcoreOnly; [Description("Hardcore players ONLY. This means softcore players cannot join.")]
[Description("Mediumcore players ONLY. This means softcore players cannot join.")] public bool MediumcoreOnly; public bool HardcoreOnly;
[Description("Kicks a hardcore player on death.")] public bool KickOnMediumcoreDeath; [Description("Mediumcore players ONLY. This means softcore players cannot join.")]
[Description("Bans a hardcore player on death.")] public bool BanOnMediumcoreDeath; public bool MediumcoreOnly;
[Description("Kicks a mediumcore player on death.")]
public bool KickOnMediumcoreDeath;
[Description("Bans a mediumcore player on death.")]
public bool BanOnMediumcoreDeath;
[Description("Enable/disable Terraria's built in auto save.")] public bool AutoSave = true; [Description("Enable/disable Terraria's built in auto save.")]
[Description("Enable/disable save announcements.")] public bool AnnounceSave = true; public bool AutoSave = true;
[Description("Enable/disable save announcements.")]
public bool AnnounceSave = true;
[Description("Number of failed login attempts before kicking the player.")] public int MaximumLoginAttempts = 3; [Description("Number of failed login attempts before kicking the player.")]
public int MaximumLoginAttempts = 3;
[Description("Not implemented.")] public string RconPassword = ""; [Description("Not implemented.")]
[Description("Not implemented.")] public int RconPort = 7777; public string RconPassword = "";
[Description("Not implemented.")]
public int RconPort = 7777;
[Description("Used when replying to a rest /status request or sent to the client when UseServerName is true.")] public string ServerName = ""; [Description("Used when replying to a rest /status request or sent to the client when UseServerName is true.")]
[Description("Sends ServerName in place of the world name to clients.")] public bool UseServerName = false; public string ServerName = "";
[Description("Not implemented.")] public string MasterServer = "127.0.0.1"; [Description("Sends ServerName in place of the world name to clients.")]
public bool UseServerName = false;
[Description("Not implemented.")]
public string MasterServer = "127.0.0.1";
[Description("Valid types are \"sqlite\" and \"mysql\"")] public string StorageType = "sqlite"; [Description("Valid types are \"sqlite\" and \"mysql\"")]
public string StorageType = "sqlite";
[Description("The MySQL hostname and port to direct connections to")] public string MySqlHost = "localhost:3306"; [Description("The MySQL hostname and port to direct connections to")]
[Description("Database name to connect to")] public string MySqlDbName = ""; public string MySqlHost = "localhost:3306";
[Description("Database username to connect with")] public string MySqlUsername = ""; [Description("Database name to connect to")]
[Description("Database password to connect with")] public string MySqlPassword = ""; public string MySqlDbName = "";
[Description("Database username to connect with")]
public string MySqlUsername = "";
[Description("Database password to connect with")]
public string MySqlPassword = "";
[Description("Bans a mediumcore player on death.")] public string MediumcoreBanReason = "Death results in a ban"; [Description("Bans a mediumcore player on death.")]
[Description("Kicks a mediumcore player on death.")] public string MediumcoreKickReason = "Death results in a kick"; public string MediumcoreBanReason = "Death results in a ban";
[Description("Kicks a mediumcore player on death.")]
public string MediumcoreKickReason = "Death results in a kick";
[Description("Enables DNS resolution of incoming connections with GetGroupForIPExpensive.")] public bool [Description("Enables DNS resolution of incoming connections with GetGroupForIPExpensive.")]
EnableDNSHostResolution; public bool EnableDNSHostResolution;
[Description("Enables kicking of banned users by matching their IP Address.")] public bool EnableIPBans = true; [Description("Enables kicking of banned users by matching their IP Address.")]
public bool EnableIPBans = true;
[Description("Enables kicking of banned users by matching their client UUID.")] public bool EnableUUIDBans = true; [Description("Enables kicking of banned users by matching their client UUID.")]
public bool EnableUUIDBans = true;
[Description("Enables kicking of banned users by matching their Character Name.")] public bool EnableBanOnUsernames; [Description("Enables kicking of banned users by matching their Character Name.")]
public bool EnableBanOnUsernames;
[Description("Selects the default group name to place new registrants under.")] public string [Description("Selects the default group name to place new registrants under.")]
DefaultRegistrationGroupName = "default"; public string DefaultRegistrationGroupName = "default";
[Description("Selects the default group name to place non registered users under")] public string [Description("Selects the default group name to place non registered users under")]
DefaultGuestGroupName = "guest"; public string DefaultGuestGroupName = "guest";
[Description("Force-disable printing logs to players with the log permission.")] public bool DisableSpewLogs = true; [Description("Force-disable printing logs to players with the log permission.")]
public bool DisableSpewLogs = true;
[Description("Valid types are \"sha512\", \"sha256\", \"md5\", append with \"-xp\" for the xp supported algorithms.")] public string HashAlgorithm = "sha512"; [Description("Valid types are \"sha512\", \"sha256\", \"md5\", append with \"-xp\" for the xp supported algorithms.")]
public string HashAlgorithm = "sha512";
[Description("Buffers up the packets and sends them out at the end of each frame.")] public bool BufferPackets = true; [Description("Buffers up the packets and sends them out at the end of each frame.")]
public bool BufferPackets = true;
[Description("String that is used when kicking people when the server is full.")] public string ServerFullReason = [Description("String that is used when kicking people when the server is full.")]
"Server is full"; public string ServerFullReason = "Server is full";
[Description("String that is used when a user is kicked due to not being on the whitelist.")] public string WhitelistKickReason = "You are not on the whitelist."; [Description("String that is used when a user is kicked due to not being on the whitelist.")]
public string WhitelistKickReason = "You are not on the whitelist.";
[Description("String that is used when kicking people when the server is full with no reserved slots.")] public string [Description("String that is used when kicking people when the server is full with no reserved slots.")]
ServerFullNoReservedReason = "Server is full. No reserved slots open."; public string ServerFullNoReservedReason = "Server is full. No reserved slots open.";
[Description("This will save the world if Terraria crashes from an unhandled exception.")] public bool [Description("This will save the world if Terraria crashes from an unhandled exception.")]
SaveWorldOnCrash = true; public bool SaveWorldOnCrash = true;
[Description("This will announce a player's location on join")] public bool EnableGeoIP; [Description("This will announce a player's location on join")]
public bool EnableGeoIP;
[Description("This will turn on token requirement for the public REST API endpoints.")] public bool [Description("This will turn on token requirement for the public REST API endpoints.")]
EnableTokenEndpointAuthentication; public bool EnableTokenEndpointAuthentication;
[Description("Enable/disable the rest api.")] public bool RestApiEnabled; [Description("Enable/disable the rest api.")]
public bool RestApiEnabled;
[Description("This is the port which the rest api will listen on.")] public int RestApiPort = 7878; [Description("This is the port which the rest api will listen on.")]
public int RestApiPort = 7878;
[Description("Disable tombstones for all players.")] public bool DisableTombstones = true; [Description("Disable tombstones for all players.")]
public bool DisableTombstones = true;
[Description("Displays a player's IP on join to everyone who has the log permission.")] public bool DisplayIPToAdmins; [Description("Displays a player's IP on join to everyone who has the log permission.")]
public bool DisplayIPToAdmins;
[Description("Kicks users using a proxy as identified with the GeoIP database.")] public bool KickProxyUsers = true; [Description("Kicks users using a proxy as identified with the GeoIP database.")]
public bool KickProxyUsers = true;
[Description("Disables hardmode, can't never be activated. Overrides /starthardmode.")] public bool DisableHardmode; [Description("Disables hardmode, can't never be activated. Overrides /starthardmode.")]
public bool DisableHardmode;
[Description("Disables the dungeon guardian from being spawned by player packets, this will instead force a respawn.")] public bool DisableDungeonGuardian; [Description("Disables the dungeon guardian from being spawned by player packets, this will instead force a respawn.")]
public bool DisableDungeonGuardian;
[Description("Enable server side characters, This stops the client from saving character data! EXPERIMENTAL!!!!!")] public bool ServerSideCharacter; [Description("Disables clown bomb projectiles from spawning.")]
public bool DisableClownBombs;
[Description("How often SSC should save, in minutes.")] public int ServerSideCharacterSave = 5; [Description("Disables snow ball projectiles from spawning.")]
public bool DisableSnowBalls;
[Description("Time, in milliseconds, to disallow discarding items after logging in when ServerSideInventory is ON.")] public int LogonDiscardThreshold=250;
[Description("Disables clown bomb projectiles from spawning.")] public bool DisableClownBombs;
[Description("Disables snow ball projectiles from spawning.")] public bool DisableSnowBalls;
[Description( [Description(
"Changes ingame chat format: {0} = Group Name, {1} = Group Prefix, {2} = Player Name, {3} = Group Suffix, {4} = Chat Message" "Changes ingame chat format: {0} = Group Name, {1} = Group Prefix, {2} = Player Name, {3} = Group Suffix, {4} = Chat Message"
)] public string ChatFormat = "{1}{2}{3}: {4}"; )]
public string ChatFormat = "{1}{2}{3}: {4}";
[Description("Change the player name when using chat above heads. This begins with a player name wrapped in brackets, as per Terraria's formatting. Same formatting as ChatFormat(minus the text aka {4}).")] public string ChatAboveHeadsFormat = "{2}"; [Description("Change the player name when using chat above heads. This begins with a player name wrapped in brackets, as per Terraria's formatting. Same formatting as ChatFormat(minus the text aka {4}).")]
public string ChatAboveHeadsFormat = "{2}";
[Description("Force the world time to be normal, day, or night.")] public string ForceTime = "normal"; [Description("Force the world time to be normal, day, or night.")]
public string ForceTime = "normal";
[Description("Disables/reverts a player if this number of tile kills is exceeded within 1 second.")] public int [Description("Disables/reverts a player if this number of tile kills is exceeded within 1 second.")]
TileKillThreshold = 60; public int TileKillThreshold = 60;
[Description("Disables/reverts a player if this number of tile places is exceeded within 1 second.")] [Description("Disables/reverts a player if this number of tile places is exceeded within 1 second.")]
public int public int TilePlaceThreshold = 20;
TilePlaceThreshold = 20;
[Description("Disables a player if this number of liquid sets is exceeded within 1 second.")] public int [Description("Disables a player if this number of liquid sets is exceeded within 1 second.")]
TileLiquidThreshold = 15; public int TileLiquidThreshold = 15;
[Description("Disable a player if this number of projectiles is created within 1 second.")] [Description("Disable a player if this number of projectiles is created within 1 second.")]
public int public int ProjectileThreshold = 50;
ProjectileThreshold = 50;
[Description("Ignore shrapnel from crystal bullets for projectile threshold.")] public bool [Description("Ignore shrapnel from crystal bullets for projectile threshold.")]
ProjIgnoreShrapnel = true; public bool ProjIgnoreShrapnel = true;
[Description("Requires all players to register or login before being allowed to play.")] public bool RequireLogin; [Description("Requires all players to register or login before being allowed to play.")]
public bool RequireLogin;
[Description( [Description(
"Disables invisibility potions from being used in PvP (Note, can be used in the client, but the effect isn't sent to the rest of the server)." "Disables invisibility potions from being used in PvP (Note, can be used in the client, but the effect isn't sent to the rest of the server)."
)] public bool DisableInvisPvP; )]
public bool DisableInvisPvP;
[Description("The maximum distance players disabled for various reasons can move from.")] public int [Description("The maximum distance players disabled for various reasons can move from.")]
MaxRangeForDisabled = 10; public int MaxRangeForDisabled = 10;
[Description("Server password required to join the server.")] public string ServerPassword = ""; [Description("Server password required to join the server.")]
public string ServerPassword = "";
[Description("Protect chests with region and build permissions.")] public bool RegionProtectChests; [Description("Protect chests with region and build permissions.")]
public bool RegionProtectChests;
[Description("Disable users from being able to login with account password when joining.")] public bool [Description("Disable users from being able to login with account password when joining.")]
DisableLoginBeforeJoin; public bool DisableLoginBeforeJoin;
[Description("Disable users from being able to login with their client UUID.")] public bool DisableUUIDLogin; [Description("Disable users from being able to login with their client UUID.")]
public bool DisableUUIDLogin;
[Description("Kick clients that don't send a UUID to the server.")] public bool KickEmptyUUID; [Description("Kick clients that don't send a UUID to the server.")]
public bool KickEmptyUUID;
[Description("Allows users to register any username with /register.")] public bool AllowRegisterAnyUsername; [Description("Allows users to register any username with /register.")]
public bool AllowRegisterAnyUsername;
[Description("Allows users to login with any username with /login.")] public bool AllowLoginAnyUsername = true; [Description("Allows users to login with any username with /login.")]
public bool AllowLoginAnyUsername = true;
[Description("The maximum damage a player/npc can inflict.")] public int MaxDamage = 175; [Description("The maximum damage a player/npc can inflict.")]
public int MaxDamage = 175;
[Description("The maximum damage a projectile can inflict.")] public int MaxProjDamage = 175; [Description("The maximum damage a projectile can inflict.")]
public int MaxProjDamage = 175;
[Description("Ignores checking to see if player 'can' update a projectile.")] public bool IgnoreProjUpdate = false; [Description("Kicks a user if set to true, if they inflict more damage then the max damage.")]
public bool KickOnDamageThresholdBroken = false;
[Description("Ignores checking to see if player 'can' kill a projectile.")] public bool IgnoreProjKill = false; [Description("Ignores checking to see if player 'can' update a projectile.")]
public bool IgnoreProjUpdate = false;
[Description("Ignores all no clip checks for players.")] public bool IgnoreNoClip = false; [Description("Ignores checking to see if player 'can' kill a projectile.")]
public bool IgnoreProjKill = false;
[Description("Allow ice placement even when user does not have canbuild.")] public bool AllowIce = false; [Description("Ignores all no clip checks for players.")]
public bool IgnoreNoClip = false;
[Description("Allow ice placement even when user does not have canbuild.")]
public bool AllowIce = false;
[Description("Allows crimson to spread when a world is hardmode.")] [Description("Allows crimson to spread when a world is hardmode.")]
public bool AllowCrimsonCreep = true; public bool AllowCrimsonCreep = true;
[Description("Allows corruption to spread when a world is hardmode.")] public bool AllowCorruptionCreep = true; [Description("Allows corruption to spread when a world is hardmode.")]
public bool AllowCorruptionCreep = true;
[Description("Allows hallow to spread when a world is hardmode.")] public bool AllowHallowCreep = true; [Description("Allows hallow to spread when a world is hardmode.")]
public bool AllowHallowCreep = true;
[Description("How many things a statue can spawn within 200 pixels(?) before it stops spawning. Default = 3")] public int StatueSpawn200 = 3; [Description("How many things a statue can spawn within 200 pixels(?) before it stops spawning. Default = 3")]
public int StatueSpawn200 = 3;
[Description("How many things a statue can spawn within 600 pixels(?) before it stops spawning. Default = 6")] public int StatueSpawn600 = 6; [Description("How many things a statue can spawn within 600 pixels(?) before it stops spawning. Default = 6")]
public int StatueSpawn600 = 6;
[Description("How many things a statue spawns can exist in the world before it stops spawning. Default = 10")] public int StatueSpawnWorld = 10; [Description("How many things a statue spawns can exist in the world before it stops spawning. Default = 10")]
public int StatueSpawnWorld = 10;
[Description("Prevent banned items from being /i or /give.")] public bool PreventBannedItemSpawn = false; [Description("Prevent banned items from being /i or /give.")]
public bool PreventBannedItemSpawn = false;
[Description("Prevent players from interacting with the world if dead.")] public bool PreventDeadModification = [Description("Prevent players from interacting with the world if dead.")]
true; public bool PreventDeadModification = true;
[Description("Displays chat messages above players' heads, but will disable chat prefixes to compensate.")] public [Description("Displays chat messages above players' heads, but will disable chat prefixes to compensate.")]
bool EnableChatAboveHeads = false; public bool EnableChatAboveHeads = false;
[Description("Force Christmas only events to occur all year.")] public bool ForceXmas = false; [Description("Force Christmas-only events to occur all year.")]
public bool ForceXmas = false;
[Description("Allows groups on the banned item allowed list to spawn banned items.")] public bool AllowAllowedGroupsToSpawnBannedItems = false; [Description("Allows groups on the banned item allowed list to spawn banned items.")]
public bool AllowAllowedGroupsToSpawnBannedItems = false;
[Description("Allows stacks in chests to be beyond the stack limit")] public bool IgnoreChestStacksOnLoad = false; [Description("Allows stacks in chests to be beyond the stack limit")]
public bool IgnoreChestStacksOnLoad = false;
[Description("The path of the directory where logs should be written into.")] public string LogPath = "tshock"; [Description("The path of the directory where logs should be written into.")]
public string LogPath = "tshock";
[Description("Prevents players from placing tiles with an invalid style.")] public bool PreventInvalidPlaceStyle = true; [Description("Prevents players from placing tiles with an invalid style.")]
public bool PreventInvalidPlaceStyle = true;
[Description("#.#.#. = Red/Blue/Green - RGB Colors for broadcasts. Max value: 255.")] public float[] BroadcastRGB = [Description("#.#.#. = Red/Blue/Green - RGB Colors for broadcasts. Max value: 255.")]
{127,255,212}; public float[] BroadcastRGB = { 127, 255, 212 };
// TODO: Get rid of this when the old REST permission model is removed. // TODO: Get rid of this when the old REST permission model is removed.
[Description( [Description(
"Whether the REST API should use the new permission model. Note: The old permission model will become depracted in the future." "Whether the REST API should use the new permission model. Note: The old permission model will become depracted in the future."
)] public bool RestUseNewPermissionModel = true; )]
public bool RestUseNewPermissionModel = true;
[Description("A dictionary of REST tokens that external applications may use to make queries to your server.")] [Description("A dictionary of REST tokens that external applications may use to make queries to your server.")]
public Dictionary<string, SecureRest.TokenData> ApplicationRestTokens = new Dictionary<string, SecureRest.TokenData>(); public Dictionary<string, SecureRest.TokenData> ApplicationRestTokens = new Dictionary<string, SecureRest.TokenData>();
[Description("The number of reserved slots past your max server slot that can be joined by reserved players")] public int ReservedSlots = 20; [Description("The number of reserved slots past your max server slot that can be joined by reserved players")]
public int ReservedSlots = 20;
[Description("The number of reserved slots past your max server slot that can be joined by reserved players")] public bool LogRest = false; [Description("The number of reserved slots past your max server slot that can be joined by reserved players")]
public bool LogRest = false;
[Description("The number of seconds a player must wait before being respawned.")] public int RespawnSeconds = 3; [Description("The number of seconds a player must wait before being respawned.")]
public int RespawnSeconds = 5;
[Description("Disables a player if this number of tiles is painted within 1 second.")] public int TilePaintThreshold = 15; [Description("The number of seconds a player must wait before being respawned if there is a boss nearby.")]
public int RespawnBossSeconds = 10;
[Description("Enables max packet bufferer size.")] public bool EnableMaxBytesInBuffer = false; [Description("Disables a player if this number of tiles is painted within 1 second.")]
public int TilePaintThreshold = 15;
[Description("Number of bytes in the packet buffer before we disconnect the player.")] public int MaxBytesInBuffer = 5242880; [Description("Enables max packet bufferer size.")]
public bool EnableMaxBytesInBuffer = false;
[Description("Forces your world to be in Halloween mode regardless of the data.")] public bool ForceHalloween = false; [Description("Number of bytes in the packet buffer before we disconnect the player.")]
public int MaxBytesInBuffer = 5242880;
[Description("Allows anyone to break grass, pots, etc.")] public bool AllowCutTilesAndBreakables = false; [Description("Forces your world to be in Halloween mode regardless of the data.")]
public bool ForceHalloween = false;
[Description("Allows anyone to break grass, pots, etc.")]
public bool AllowCutTilesAndBreakables = false;
[Description("Specifies which string starts a command")]
public string CommandSpecifier = "/";
[Description("Kicks a hardcore player on death.")]
public bool KickOnHardcoreDeath;
[Description("Bans a hardcore player on death.")]
public bool BanOnHardcoreDeath;
[Description("Bans a hardcore player on death.")]
public string HardcoreBanReason = "Death results in a ban";
[Description("Kicks a hardcore player on death.")]
public string HardcoreKickReason = "Death results in a kick";
[Description("Whether bosses or invasions should be anonymously spawned.")]
public bool AnonymousBossInvasions = true;
[Description("The maximum allowable HP, before equipment buffs.")]
public int MaxHP = 500;
[Description("The maximum allowable MP, before equipment buffs.")]
public int MaxMP = 200;
/// <summary> /// <summary>
/// Reads a configuration file from a given path /// Reads a configuration file from a given path

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -232,7 +232,7 @@ namespace TShockAPI.DB
{ {
IP = ip; IP = ip;
Name = name; Name = name;
UUID = UUID; UUID = uuid;
Reason = reason; Reason = reason;
BanningUser = banner; BanningUser = banner;
Date = date; Date = date;

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -18,7 +18,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
using System; using System;
using System.Data; using System.Data;
using System.Text;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using Terraria;
namespace TShockAPI.DB namespace TShockAPI.DB
{ {
@ -38,7 +40,18 @@ namespace TShockAPI.DB
new SqlColumn("MaxMana", MySqlDbType.Int32), new SqlColumn("MaxMana", MySqlDbType.Int32),
new SqlColumn("Inventory", MySqlDbType.Text), new SqlColumn("Inventory", MySqlDbType.Text),
new SqlColumn("spawnX", MySqlDbType.Int32), new SqlColumn("spawnX", MySqlDbType.Int32),
new SqlColumn("spawnY", MySqlDbType.Int32) new SqlColumn("spawnY", MySqlDbType.Int32),
new SqlColumn("hair", MySqlDbType.Int32),
new SqlColumn("hairDye", MySqlDbType.Int32),
new SqlColumn("hairColor", MySqlDbType.Int32),
new SqlColumn("pantsColor", MySqlDbType.Int32),
new SqlColumn("shirtColor", MySqlDbType.Int32),
new SqlColumn("underShirtColor", MySqlDbType.Int32),
new SqlColumn("shoeColor", MySqlDbType.Int32),
new SqlColumn("hideVisuals", MySqlDbType.Int32),
new SqlColumn("skinColor", MySqlDbType.Int32),
new SqlColumn("eyeColor", MySqlDbType.Int32),
new SqlColumn("questsCompleted", MySqlDbType.Int32)
); );
var creator = new SqlTableCreator(db, var creator = new SqlTableCreator(db,
db.GetSqlType() == SqlType.Sqlite db.GetSqlType() == SqlType.Sqlite
@ -65,6 +78,17 @@ namespace TShockAPI.DB
playerData.inventory = NetItem.Parse(reader.Get<string>("Inventory")); playerData.inventory = NetItem.Parse(reader.Get<string>("Inventory"));
playerData.spawnX = reader.Get<int>("spawnX"); playerData.spawnX = reader.Get<int>("spawnX");
playerData.spawnY = reader.Get<int>("spawnY"); playerData.spawnY = reader.Get<int>("spawnY");
playerData.hair = reader.Get<int?>("hair");
playerData.hairDye = (byte)reader.Get<int>("hairDye");
playerData.hairColor = TShock.Utils.DecodeColor(reader.Get<int?>("hairColor"));
playerData.pantsColor = TShock.Utils.DecodeColor(reader.Get<int?>("pantsColor"));
playerData.shirtColor = TShock.Utils.DecodeColor(reader.Get<int?>("shirtColor"));
playerData.underShirtColor = TShock.Utils.DecodeColor(reader.Get<int?>("underShirtColor"));
playerData.shoeColor = TShock.Utils.DecodeColor(reader.Get<int?>("shoeColor"));
playerData.hideVisuals = TShock.Utils.DecodeBitsByte(reader.Get<int?>("hideVisuals"));
playerData.skinColor = TShock.Utils.DecodeColor(reader.Get<int?>("skinColor"));
playerData.eyeColor = TShock.Utils.DecodeColor(reader.Get<int?>("eyeColor"));
playerData.questsCompleted = reader.Get<int>("questsCompleted");
return playerData; return playerData;
} }
} }
@ -79,11 +103,36 @@ namespace TShockAPI.DB
public bool SeedInitialData(User user) public bool SeedInitialData(User user)
{ {
string initialItems = "-15,1,0~-13,1,0~-16,1,45~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0~0,0,0"; var inventory = new StringBuilder();
for (int i = 0; i < Terraria.Main.maxInventory; i++)
{
if (i > 0)
{
inventory.Append("~");
}
if (i < TShock.ServerSideCharacterConfig.StartingInventory.Count)
{
var item = TShock.ServerSideCharacterConfig.StartingInventory[i];
inventory.Append(item.netID).Append(',').Append(item.stack).Append(',').Append(item.prefix);
}
else
{
inventory.Append("0,0,0");
}
}
string initialItems = inventory.ToString();
try try
{ {
database.Query("INSERT INTO tsCharacter (Account, Health, MaxHealth, Mana, MaxMana, Inventory, spawnX, spawnY) VALUES (@0, @1, @2, @3, @4, @5, @6, @7);", user.ID, database.Query("INSERT INTO tsCharacter (Account, Health, MaxHealth, Mana, MaxMana, Inventory, spawnX, spawnY, questsCompleted) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8);",
100, 100, 20, 20, initialItems, -1, -1); user.ID,
TShock.ServerSideCharacterConfig.StartingHealth,
TShock.ServerSideCharacterConfig.StartingHealth,
TShock.ServerSideCharacterConfig.StartingMana,
TShock.ServerSideCharacterConfig.StartingMana,
initialItems,
-1,
-1,
0);
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
@ -106,8 +155,9 @@ namespace TShockAPI.DB
{ {
try try
{ {
database.Query("INSERT INTO tsCharacter (Account, Health, MaxHealth, Mana, MaxMana, Inventory, spawnX, spawnY) VALUES (@0, @1, @2, @3, @4, @5, @6, @7);", player.UserID, database.Query(
playerData.health, playerData.maxHealth, playerData.mana, playerData.maxMana, NetItem.ToString(playerData.inventory), player.TPlayer.SpawnX, player.TPlayer.SpawnY); "INSERT INTO tsCharacter (Account, Health, MaxHealth, Mana, MaxMana, Inventory, spawnX, spawnY, hair, hairDye, hairColor, pantsColor, shirtColor, underShirtColor, shoeColor, hideVisuals, skinColor, eyeColor, questsCompleted) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18);",
player.UserID, playerData.health, playerData.maxHealth, playerData.mana, playerData.maxMana, NetItem.ToString(playerData.inventory), player.TPlayer.SpawnX, player.TPlayer.SpawnY, player.TPlayer.hair, player.TPlayer.hairDye, TShock.Utils.EncodeColor(player.TPlayer.hairColor), TShock.Utils.EncodeColor(player.TPlayer.pantsColor),TShock.Utils.EncodeColor(player.TPlayer.shirtColor), TShock.Utils.EncodeColor(player.TPlayer.underShirtColor), TShock.Utils.EncodeColor(player.TPlayer.shoeColor), TShock.Utils.EncodeBitsByte(player.TPlayer.hideVisual), TShock.Utils.EncodeColor(player.TPlayer.skinColor),TShock.Utils.EncodeColor(player.TPlayer.eyeColor), player.TPlayer.anglerQuestsFinished);
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
@ -119,8 +169,9 @@ namespace TShockAPI.DB
{ {
try try
{ {
database.Query("UPDATE tsCharacter SET Health = @0, MaxHealth = @1, Mana = @2, MaxMana = @3, Inventory = @4, spawnX = @6, spawnY = @7 WHERE Account = @5;", playerData.health, playerData.maxHealth, database.Query(
playerData.mana, playerData.maxMana, NetItem.ToString(playerData.inventory), player.UserID, player.TPlayer.SpawnX, player.TPlayer.SpawnY); "UPDATE tsCharacter SET Health = @0, MaxHealth = @1, Mana = @2, MaxMana = @3, Inventory = @4, spawnX = @6, spawnY = @7, hair = @8, hairDye = @9, hairColor = @10, pantsColor = @11, shirtColor = @12, underShirtColor = @13, shoeColor = @14, hideVisuals = @15, skinColor = @16, eyeColor = @17, questsCompleted = @18 WHERE Account = @5;",
playerData.health, playerData.maxHealth, playerData.mana, playerData.maxMana, NetItem.ToString(playerData.inventory), player.UserID, player.TPlayer.SpawnX, player.TPlayer.SpawnY, player.TPlayer.hair, player.TPlayer.hairDye, TShock.Utils.EncodeColor(player.TPlayer.hairColor), TShock.Utils.EncodeColor(player.TPlayer.pantsColor), TShock.Utils.EncodeColor(player.TPlayer.shirtColor), TShock.Utils.EncodeColor(player.TPlayer.underShirtColor), TShock.Utils.EncodeColor(player.TPlayer.shoeColor), TShock.Utils.EncodeBitsByte(player.TPlayer.hideVisual), TShock.Utils.EncodeColor(player.TPlayer.skinColor), TShock.Utils.EncodeColor(player.TPlayer.eyeColor), player.TPlayer.anglerQuestsFinished);
return true; return true;
} }
catch (Exception ex) catch (Exception ex)

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -67,7 +67,7 @@ namespace TShockAPI.DB
string.Join(",", Permissions.ban, Permissions.whitelist, "tshock.world.time.*", Permissions.spawnboss, string.Join(",", Permissions.ban, Permissions.whitelist, "tshock.world.time.*", Permissions.spawnboss,
Permissions.spawnmob, Permissions.managewarp, Permissions.time, Permissions.tp, Permissions.slap, Permissions.spawnmob, Permissions.managewarp, Permissions.time, Permissions.tp, Permissions.slap,
Permissions.kill, Permissions.logs, Permissions.kill, Permissions.logs,
Permissions.immunetokick, Permissions.tphere)); Permissions.immunetokick, Permissions.tpothers));
AddDefaultGroup("trustedadmin", "admin", AddDefaultGroup("trustedadmin", "admin",
string.Join(",", Permissions.maintenance, "tshock.cfg.*", "tshock.world.*", Permissions.butcher, Permissions.item, string.Join(",", Permissions.maintenance, "tshock.cfg.*", "tshock.world.*", Permissions.butcher, Permissions.item,

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -44,10 +44,15 @@ namespace TShockAPI.DB
var columns = var columns =
table.Columns.Select( table.Columns.Select(
c => c =>
"'{0}' {1} {2} {3} {4} {5}".SFormat(c.Name, DbTypeToString(c.Type, c.Length), c.Primary ? "PRIMARY KEY" : "", "'{0}' {1} {2} {3} {4}".SFormat(c.Name,
c.AutoIncrement ? "AUTOINCREMENT" : "", c.NotNull ? "NOT NULL" : "", DbTypeToString(c.Type, c.Length),
c.Unique ? "UNIQUE" : "")); c.Primary ? "PRIMARY KEY" : "",
return "CREATE TABLE {0} ({1})".SFormat(EscapeTableName(table.Name), string.Join(", ", columns)); c.AutoIncrement ? "AUTOINCREMENT" : "",
c.NotNull ? "NOT NULL" : ""));
var uniques = table.Columns.Where(c => c.Unique).Select(c => c.Name);
return "CREATE TABLE {0} ({1} {2})".SFormat(EscapeTableName(table.Name),
string.Join(", ", columns),
uniques.Count() > 0 ? ", UNIQUE({0})".SFormat(string.Join(", ", uniques)) : "");
} }
public override string RenameTable(string from, string to) public override string RenameTable(string from, string to)
@ -67,6 +72,7 @@ namespace TShockAPI.DB
{ MySqlDbType.Double, "REAL" }, { MySqlDbType.Double, "REAL" },
{ MySqlDbType.Int32, "INTEGER" }, { MySqlDbType.Int32, "INTEGER" },
{ MySqlDbType.Blob, "BLOB" }, { MySqlDbType.Blob, "BLOB" },
{ MySqlDbType.Int64, "BIGINT"},
}; };
public string DbTypeToString(MySqlDbType type, int? length) public string DbTypeToString(MySqlDbType type, int? length)
@ -115,6 +121,7 @@ namespace TShockAPI.DB
{ MySqlDbType.Float, "FLOAT" }, { MySqlDbType.Float, "FLOAT" },
{ MySqlDbType.Double, "DOUBLE" }, { MySqlDbType.Double, "DOUBLE" },
{ MySqlDbType.Int32, "INT" }, { MySqlDbType.Int32, "INT" },
{ MySqlDbType.Int64, "BIGINT"},
}; };
public string DbTypeToString(MySqlDbType type, int? length) public string DbTypeToString(MySqlDbType type, int? length)

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -100,13 +100,9 @@ namespace TShockAPI.DB
} }
public bool ItemIsBanned(string name, TSPlayer ply) public bool ItemIsBanned(string name, TSPlayer ply)
{
if (ItemBans.Contains(new ItemBan(name)))
{ {
ItemBan b = GetItemBanByName(name); ItemBan b = GetItemBanByName(name);
return !b.HasPermissionToUseItem(ply); return b != null &&!b.HasPermissionToUseItem(ply);
}
return false;
} }
public bool AllowGroup(string item, string name) public bool AllowGroup(string item, string name)
@ -162,11 +158,11 @@ namespace TShockAPI.DB
public ItemBan GetItemBanByName(String name) public ItemBan GetItemBanByName(String name)
{ {
foreach (ItemBan b in ItemBans) for (int i = 0; i < ItemBans.Count; i++)
{ {
if (b.Name == name) if (ItemBans[i].Name == name)
{ {
return b; return ItemBans[i];
} }
} }
return null; return null;

View file

@ -0,0 +1,253 @@
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using MySql.Data.MySqlClient;
namespace TShockAPI.DB
{
public class ProjectileManagager
{
private IDbConnection database;
public List<ProjectileBan> ProjectileBans = new List<ProjectileBan>();
public ProjectileManagager(IDbConnection db)
{
database = db;
var table = new SqlTable("ProjectileBans",
new SqlColumn("ProjectileID", MySqlDbType.Int32) {Primary = true},
new SqlColumn("AllowedGroups", MySqlDbType.Text)
);
var creator = new SqlTableCreator(db,
db.GetSqlType() == SqlType.Sqlite
? (IQueryBuilder) new SqliteQueryCreator()
: new MysqlQueryCreator());
creator.EnsureExists(table);
UpdateBans();
}
public void UpdateBans()
{
ProjectileBans.Clear();
using (var reader = database.QueryReader("SELECT * FROM ProjectileBans"))
{
while (reader != null && reader.Read())
{
ProjectileBan ban = new ProjectileBan((short) reader.Get<Int32>("ProjectileID"));
ban.SetAllowedGroups(reader.Get<string>("AllowedGroups"));
ProjectileBans.Add(ban);
}
}
}
public void AddNewBan(short id = 0)
{
try
{
database.Query("INSERT INTO ProjectileBans (ProjectileID, AllowedGroups) VALUES (@0, @1);",
id, "");
if (!ProjectileIsBanned(id, null))
ProjectileBans.Add(new ProjectileBan(id));
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
public void RemoveBan(short id)
{
if (!ProjectileIsBanned(id, null))
return;
try
{
database.Query("DELETE FROM ProjectileBans WHERE ProjectileId=@0;", id);
ProjectileBans.Remove(new ProjectileBan(id));
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
public bool ProjectileIsBanned(short id)
{
if (ProjectileBans.Contains(new ProjectileBan(id)))
{
return true;
}
return false;
}
public bool ProjectileIsBanned(short id, TSPlayer ply)
{
if (ProjectileBans.Contains(new ProjectileBan(id)))
{
ProjectileBan b = GetBanById(id);
return !b.HasPermissionToCreateProjectile(ply);
}
return false;
}
public bool AllowGroup(short id, string name)
{
string groupsNew = "";
ProjectileBan b = GetBanById(id);
if (b != null)
{
try
{
groupsNew = String.Join(",", b.AllowedGroups);
if (groupsNew.Length > 0)
groupsNew += ",";
groupsNew += name;
b.SetAllowedGroups(groupsNew);
int q = database.Query("UPDATE ProjectileBans SET AllowedGroups=@0 WHERE ProjectileId=@1", groupsNew,
id);
return q > 0;
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
return false;
}
public bool RemoveGroup(short id, string group)
{
ProjectileBan b = GetBanById(id);
if (b != null)
{
try
{
b.RemoveGroup(group);
string groups = string.Join(",", b.AllowedGroups);
int q = database.Query("UPDATE ProjectileBans SET AllowedGroups=@0 WHERE ProjectileId=@1", groups,
id);
if (q > 0)
return true;
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
return false;
}
public ProjectileBan GetBanById(short id)
{
foreach (ProjectileBan b in ProjectileBans)
{
if (b.ID == id)
{
return b;
}
}
return null;
}
}
public class ProjectileBan : IEquatable<ProjectileBan>
{
public short ID { get; set; }
public List<string> AllowedGroups { get; set; }
public ProjectileBan(short id)
: this()
{
ID = id;
AllowedGroups = new List<string>();
}
public ProjectileBan()
{
ID = 0;
AllowedGroups = new List<string>();
}
public bool Equals(ProjectileBan other)
{
return ID == other.ID;
}
public bool HasPermissionToCreateProjectile(TSPlayer ply)
{
if (ply == null)
return false;
if (ply.Group.HasPermission(Permissions.canusebannedprojectiles))
return true;
var cur = ply.Group;
var traversed = new List<Group>();
while (cur != null)
{
if (AllowedGroups.Contains(cur.Name))
{
return true;
}
if (traversed.Contains(cur))
{
throw new InvalidOperationException("Infinite group parenting ({0})".SFormat(cur.Name));
}
traversed.Add(cur);
cur = cur.Parent;
}
return false;
// could add in the other permissions in this class instead of a giant if switch.
}
public void SetAllowedGroups(String groups)
{
// prevent null pointer exceptions
if (!string.IsNullOrEmpty(groups))
{
List<String> groupArr = groups.Split(',').ToList();
for (int i = 0; i < groupArr.Count; i++)
{
groupArr[i] = groupArr[i].Trim();
//Console.WriteLine(groupArr[i]);
}
AllowedGroups = groupArr;
}
}
public bool RemoveGroup(string groupName)
{
return AllowedGroups.Remove(groupName);
}
public override string ToString()
{
return ID + (AllowedGroups.Count > 0 ? " (" + String.Join(",", AllowedGroups) + ")" : "");
}
}
}

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -38,12 +38,13 @@ namespace TShockAPI.DB
{ {
database = db; database = db;
var table = new SqlTable("Regions", var table = new SqlTable("Regions",
new SqlColumn("Id", MySqlDbType.Int32) {Primary = true, AutoIncrement = true},
new SqlColumn("X1", MySqlDbType.Int32), new SqlColumn("X1", MySqlDbType.Int32),
new SqlColumn("Y1", MySqlDbType.Int32), new SqlColumn("Y1", MySqlDbType.Int32),
new SqlColumn("width", MySqlDbType.Int32), new SqlColumn("width", MySqlDbType.Int32),
new SqlColumn("height", MySqlDbType.Int32), new SqlColumn("height", MySqlDbType.Int32),
new SqlColumn("RegionName", MySqlDbType.VarChar, 50) {Primary = true}, new SqlColumn("RegionName", MySqlDbType.VarChar, 50) {Unique = true},
new SqlColumn("WorldID", MySqlDbType.Text), new SqlColumn("WorldID", MySqlDbType.VarChar, 50) { Unique = true },
new SqlColumn("UserIds", MySqlDbType.Text), new SqlColumn("UserIds", MySqlDbType.Text),
new SqlColumn("Protected", MySqlDbType.Int32), new SqlColumn("Protected", MySqlDbType.Int32),
new SqlColumn("Groups", MySqlDbType.Text), new SqlColumn("Groups", MySqlDbType.Text),
@ -114,53 +115,6 @@ namespace TShockAPI.DB
} }
} }
public void ReloadForUnitTest(String n)
{
using (var reader = database.QueryReader("SELECT * FROM Regions WHERE WorldID=@0", n))
{
Regions.Clear();
while (reader.Read())
{
int X1 = reader.Get<int>("X1");
int Y1 = reader.Get<int>("Y1");
int height = reader.Get<int>("height");
int width = reader.Get<int>("width");
int Protected = reader.Get<int>("Protected");
string MergedIDs = reader.Get<string>("UserIds");
string name = reader.Get<string>("RegionName");
string[] SplitIDs = MergedIDs.Split(',');
string owner = reader.Get<string>("Owner");
string groups = reader.Get<string>("Groups");
int z = reader.Get<int>("Z");
Region r = new Region(new Rectangle(X1, Y1, width, height), name, owner, Protected != 0, Main.worldID.ToString(), z);
r.SetAllowedGroups(groups);
try
{
for (int i = 0; i < SplitIDs.Length; i++)
{
int id;
if (Int32.TryParse(SplitIDs[i], out id)) // if unparsable, it's not an int, so silently skip
r.AllowedIDs.Add(id);
else if (SplitIDs[i] == "") // Split gotcha, can return an empty string with certain conditions
// but we only want to let the user know if it's really a nonparsable integer.
Log.Warn("UnitTest: One of your UserIDs is not a usable integer: " + SplitIDs[i]);
}
}
catch (Exception e)
{
Log.Error("Your database contains invalid UserIDs (they should be ints).");
Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field.");
Log.Error(e.Message);
Log.Error(e.StackTrace);
}
Regions.Add(r);
}
}
}
public bool AddRegion(int tx, int ty, int width, int height, string regionname, string owner, string worldid, int z = 0) public bool AddRegion(int tx, int ty, int width, int height, string regionname, string owner, string worldid, int z = 0)
{ {
if (GetRegionByName(regionname) != null) if (GetRegionByName(regionname) != null)
@ -311,52 +265,43 @@ namespace TShockAPI.DB
int Y = 0; int Y = 0;
int height = 0; int height = 0;
int width = 0; int width = 0;
try try
{ {
using ( using (var reader = database.QueryReader("SELECT X1, Y1, height, width FROM Regions WHERE RegionName=@0 AND WorldID=@1",
var reader = database.QueryReader("SELECT X1, Y1, height, width FROM Regions WHERE RegionName=@0 AND WorldID=@1",
regionName, Main.worldID.ToString())) regionName, Main.worldID.ToString()))
{ {
if (reader.Read()) if (reader.Read())
{
X = reader.Get<int>("X1"); X = reader.Get<int>("X1");
width = reader.Get<int>("width"); width = reader.Get<int>("width");
Y = reader.Get<int>("Y1"); Y = reader.Get<int>("Y1");
height = reader.Get<int>("height"); height = reader.Get<int>("height");
} }
if (!(direction == 0))
{
if (!(direction == 1))
{
if (!(direction == 2))
{
if (!(direction == 3))
{
return false;
} }
else switch (direction)
{
X -= addAmount;
width += addAmount;
}
}
else
{
height += addAmount;
}
}
else
{
width += addAmount;
}
}
else
{ {
case 0:
Y -= addAmount; Y -= addAmount;
height += addAmount; height += addAmount;
break;
case 1:
width += addAmount;
break;
case 2:
height += addAmount;
break;
case 3:
X -= addAmount;
width += addAmount;
break;
default:
return false;
} }
int q =
database.Query( foreach (var region in Regions.Where(r => r.Name == regionName))
"UPDATE Regions SET X1 = @0, Y1 = @1, width = @2, height = @3 WHERE RegionName = @4 AND WorldID=@5", X, Y, width, region.Area = new Rectangle(X, Y, width, height);
int q = database.Query("UPDATE Regions SET X1 = @0, Y1 = @1, width = @2, height = @3 WHERE RegionName = @4 AND WorldID=@5", X, Y, width,
height, regionName, Main.worldID.ToString()); height, regionName, Main.worldID.ToString());
if (q > 0) if (q > 0)
return true; return true;
@ -478,16 +423,6 @@ namespace TShockAPI.DB
return Regions.FirstOrDefault(r => r.Name.Equals(name) && r.WorldID == Main.worldID.ToString()); return Regions.FirstOrDefault(r => r.Name.Equals(name) && r.WorldID == Main.worldID.ToString());
} }
public Region ZacksGetRegionByName(String name)
{
foreach (Region r in Regions)
{
if (r.Name.Equals(name))
return r;
}
return null;
}
public bool ChangeOwner(string regionName, string newOwner) public bool ChangeOwner(string regionName, string newOwner)
{ {
var region = GetRegionByName(regionName); var region = GetRegionByName(regionName);

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

253
TShockAPI/DB/TileManager.cs Normal file
View file

@ -0,0 +1,253 @@
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using MySql.Data.MySqlClient;
namespace TShockAPI.DB
{
public class TileManager
{
private IDbConnection database;
public List<TileBan> TileBans = new List<TileBan>();
public TileManager(IDbConnection db)
{
database = db;
var table = new SqlTable("TileBans",
new SqlColumn("TileId", MySqlDbType.Int32) { Primary = true },
new SqlColumn("AllowedGroups", MySqlDbType.Text)
);
var creator = new SqlTableCreator(db,
db.GetSqlType() == SqlType.Sqlite
? (IQueryBuilder)new SqliteQueryCreator()
: new MysqlQueryCreator());
creator.EnsureExists(table);
UpdateBans();
}
public void UpdateBans()
{
TileBans.Clear();
using (var reader = database.QueryReader("SELECT * FROM TileBans"))
{
while (reader != null && reader.Read())
{
TileBan ban = new TileBan((short)reader.Get<Int32>("TileId"));
ban.SetAllowedGroups(reader.Get<string>("AllowedGroups"));
TileBans.Add(ban);
}
}
}
public void AddNewBan(short id = 0)
{
try
{
database.Query("INSERT INTO TileBans (TileId, AllowedGroups) VALUES (@0, @1);",
id, "");
if (!TileIsBanned(id, null))
TileBans.Add(new TileBan(id));
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
public void RemoveBan(short id)
{
if (!TileIsBanned(id, null))
return;
try
{
database.Query("DELETE FROM TileBans WHERE TileId=@0;", id);
TileBans.Remove(new TileBan(id));
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
public bool TileIsBanned(short id)
{
if (TileBans.Contains(new TileBan(id)))
{
return true;
}
return false;
}
public bool TileIsBanned(short id, TSPlayer ply)
{
if (TileBans.Contains(new TileBan(id)))
{
TileBan b = GetBanById(id);
return !b.HasPermissionToPlaceTile(ply);
}
return false;
}
public bool AllowGroup(short id, string name)
{
string groupsNew = "";
TileBan b = GetBanById(id);
if (b != null)
{
try
{
groupsNew = String.Join(",", b.AllowedGroups);
if (groupsNew.Length > 0)
groupsNew += ",";
groupsNew += name;
b.SetAllowedGroups(groupsNew);
int q = database.Query("UPDATE TileBans SET AllowedGroups=@0 WHERE TileId=@1", groupsNew,
id);
return q > 0;
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
return false;
}
public bool RemoveGroup(short id, string group)
{
TileBan b = GetBanById(id);
if (b != null)
{
try
{
b.RemoveGroup(group);
string groups = string.Join(",", b.AllowedGroups);
int q = database.Query("UPDATE TileBans SET AllowedGroups=@0 WHERE TileId=@1", groups,
id);
if (q > 0)
return true;
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
return false;
}
public TileBan GetBanById(short id)
{
foreach (TileBan b in TileBans)
{
if (b.ID == id)
{
return b;
}
}
return null;
}
}
public class TileBan : IEquatable<TileBan>
{
public short ID { get; set; }
public List<string> AllowedGroups { get; set; }
public TileBan(short id)
: this()
{
ID = id;
AllowedGroups = new List<string>();
}
public TileBan()
{
ID = 0;
AllowedGroups = new List<string>();
}
public bool Equals(TileBan other)
{
return ID == other.ID;
}
public bool HasPermissionToPlaceTile(TSPlayer ply)
{
if (ply == null)
return false;
if (ply.Group.HasPermission(Permissions.canusebannedtiles))
return true;
var cur = ply.Group;
var traversed = new List<Group>();
while (cur != null)
{
if (AllowedGroups.Contains(cur.Name))
{
return true;
}
if (traversed.Contains(cur))
{
throw new InvalidOperationException("Infinite group parenting ({0})".SFormat(cur.Name));
}
traversed.Add(cur);
cur = cur.Parent;
}
return false;
// could add in the other permissions in this class instead of a giant if switch.
}
public void SetAllowedGroups(String groups)
{
// prevent null pointer exceptions
if (!string.IsNullOrEmpty(groups))
{
List<String> groupArr = groups.Split(',').ToList();
for (int i = 0; i < groupArr.Count; i++)
{
groupArr[i] = groupArr[i].Trim();
//Console.WriteLine(groupArr[i]);
}
AllowedGroups = groupArr;
}
}
public bool RemoveGroup(string groupName)
{
return AllowedGroups.Remove(groupName);
}
public override string ToString()
{
return ID + (AllowedGroups.Count > 0 ? " (" + String.Join(",", AllowedGroups) + ")" : "");
}
}
}

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -40,10 +40,11 @@ namespace TShockAPI.DB
database = db; database = db;
var table = new SqlTable("Warps", var table = new SqlTable("Warps",
new SqlColumn("WarpName", MySqlDbType.VarChar, 50) {Primary = true}, new SqlColumn("Id", MySqlDbType.Int32){Primary = true, AutoIncrement = true},
new SqlColumn("WarpName", MySqlDbType.VarChar, 50) {Unique = true},
new SqlColumn("X", MySqlDbType.Int32), new SqlColumn("X", MySqlDbType.Int32),
new SqlColumn("Y", MySqlDbType.Int32), new SqlColumn("Y", MySqlDbType.Int32),
new SqlColumn("WorldID", MySqlDbType.Text), new SqlColumn("WorldID", MySqlDbType.VarChar, 50) { Unique = true },
new SqlColumn("Private", MySqlDbType.Text) new SqlColumn("Private", MySqlDbType.Text)
); );
var creator = new SqlTableCreator(db, var creator = new SqlTableCreator(db,

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -118,22 +118,42 @@ namespace TShockAPI.DB
typeof (bool), typeof (bool),
(s, i) => s.GetBoolean(i) (s, i) => s.GetBoolean(i)
}, },
{
typeof (bool?),
(s, i) => s.IsDBNull(i) ? null : (object)s.GetBoolean(i)
},
{ {
typeof (byte), typeof (byte),
(s, i) => s.GetByte(i) (s, i) => s.GetByte(i)
}, },
{
typeof (byte?),
(s, i) => s.IsDBNull(i) ? null : (object)s.GetByte(i)
},
{ {
typeof (Int16), typeof (Int16),
(s, i) => s.GetInt16(i) (s, i) => s.GetInt16(i)
}, },
{
typeof (Int16?),
(s, i) => s.IsDBNull(i) ? null : (object)s.GetInt16(i)
},
{ {
typeof (Int32), typeof (Int32),
(s, i) => s.GetInt32(i) (s, i) => s.GetInt32(i)
}, },
{
typeof (Int32?),
(s, i) => s.IsDBNull(i) ? null : (object)s.GetInt32(i)
},
{ {
typeof (Int64), typeof (Int64),
(s, i) => s.GetInt64(i) (s, i) => s.GetInt64(i)
}, },
{
typeof (Int64?),
(s, i) => s.IsDBNull(i) ? null : (object)s.GetInt64(i)
},
{ {
typeof (string), typeof (string),
(s, i) => s.GetString(i) (s, i) => s.GetString(i)
@ -142,14 +162,26 @@ namespace TShockAPI.DB
typeof (decimal), typeof (decimal),
(s, i) => s.GetDecimal(i) (s, i) => s.GetDecimal(i)
}, },
{
typeof (decimal?),
(s, i) => s.IsDBNull(i) ? null : (object)s.GetDecimal(i)
},
{ {
typeof (float), typeof (float),
(s, i) => s.GetFloat(i) (s, i) => s.GetFloat(i)
}, },
{
typeof (float?),
(s, i) => s.IsDBNull(i) ? null : (object)s.GetFloat(i)
},
{ {
typeof (double), typeof (double),
(s, i) => s.GetDouble(i) (s, i) => s.GetDouble(i)
}, },
{
typeof (double?),
(s, i) => s.IsDBNull(i) ? null : (object)s.GetDouble(i)
},
{ {
typeof (object), typeof (object),
(s, i) => s.GetValue(i) (s, i) => s.GetValue(i)

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
using System; using System;
using System.IO; using System.IO;
using TShockAPI.ServerSideCharacters;
namespace TShockAPI namespace TShockAPI
{ {
@ -55,6 +56,14 @@ namespace TShockAPI
get { return Path.Combine(TShock.SavePath, "config.json"); } get { return Path.Combine(TShock.SavePath, "config.json"); }
} }
/// <summary>
/// Path to the file containing the config.
/// </summary>
internal static string ServerSideCharacterConfigPath
{
get { return Path.Combine(TShock.SavePath, "sscconfig.json"); }
}
/// <summary> /// <summary>
/// Creates an empty file at the given path. /// Creates an empty file at the given path.
/// </summary> /// </summary>
@ -98,6 +107,12 @@ namespace TShockAPI
} }
TShock.Config.Write(ConfigPath); TShock.Config.Write(ConfigPath);
if (File.Exists(ServerSideCharacterConfigPath))
{
TShock.ServerSideCharacterConfig = ServerSideConfig.Read(ServerSideCharacterConfigPath);
// Add all the missing config properties in the json file
}
TShock.ServerSideCharacterConfig.Write(ServerSideCharacterConfigPath);
} }
/// <summary> /// <summary>

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -235,12 +235,6 @@ namespace TShockAPI
negatedpermissions.Add(permission); negatedpermissions.Add(permission);
permissions.Remove(permission); // Ensure we don't have conflicting definitions for a permissions permissions.Remove(permission); // Ensure we don't have conflicting definitions for a permissions
} }
for (int i = 0; i < TShock.Players.Length; i++)
{
if (TShock.Players[i] != null && TShock.Players[i].IsRaptor)
TShock.Players[i].SendRaptorPermissions();
}
} }
/// <summary> /// <summary>
@ -260,12 +254,6 @@ namespace TShockAPI
permissions.Add(permission); permissions.Add(permission);
negatedpermissions.Remove(permission); // Ensure we don't have conflicting definitions for a permissions negatedpermissions.Remove(permission); // Ensure we don't have conflicting definitions for a permissions
} }
for (int i = 0; i < TShock.Players.Length; i++)
{
if (TShock.Players[i] != null && TShock.Players[i].IsRaptor)
TShock.Players[i].SendRaptorPermissions();
}
} }
/// <summary> /// <summary>
@ -293,11 +281,6 @@ namespace TShockAPI
return; return;
} }
permissions.Remove(permission); permissions.Remove(permission);
for (int i = 0; i < TShock.Players.Length; i++)
{
if (TShock.Players[i] != null && TShock.Players[i].IsRaptor && TShock.Players[i].Group == this)
TShock.Players[i].SendRaptorPermissions();
}
} }
/// <summary> /// <summary>

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -43,6 +43,14 @@ namespace TShockAPI.Hooks
public string CommandName { get; set; } public string CommandName { get; set; }
public string CommandText { get; set; } public string CommandText { get; set; }
public List<string> Parameters { get; set; } public List<string> Parameters { get; set; }
public IEnumerable<Command> CommandList { get; set; }
}
public class PlayerChatEventArgs : HandledEventArgs
{
public TSPlayer Player { get; set; }
public string RawText { get; set; }
public string TShockFormattedText { get; set; }
} }
public static class PlayerHooks public static class PlayerHooks
@ -56,6 +64,9 @@ namespace TShockAPI.Hooks
public delegate void PlayerCommandD(PlayerCommandEventArgs e); public delegate void PlayerCommandD(PlayerCommandEventArgs e);
public static event PlayerCommandD PlayerCommand; public static event PlayerCommandD PlayerCommand;
public delegate void PlayerChatD(PlayerChatEventArgs e);
public static event PlayerChatD PlayerChat;
public static void OnPlayerPostLogin(TSPlayer ply) public static void OnPlayerPostLogin(TSPlayer ply)
{ {
if (PlayerPostLogin == null) if (PlayerPostLogin == null)
@ -67,7 +78,7 @@ namespace TShockAPI.Hooks
PlayerPostLogin(args); PlayerPostLogin(args);
} }
public static bool OnPlayerCommand(TSPlayer player, string cmdName, string cmdText, List<string> args) public static bool OnPlayerCommand(TSPlayer player, string cmdName, string cmdText, List<string> args, ref IEnumerable<Command> commands)
{ {
if (PlayerCommand == null) if (PlayerCommand == null)
{ {
@ -78,10 +89,11 @@ namespace TShockAPI.Hooks
Player = player, Player = player,
CommandName = cmdName, CommandName = cmdName,
CommandText = cmdText, CommandText = cmdText,
Parameters = args Parameters = args,
CommandList = commands
}; };
PlayerCommand(playerCommandEventArgs); PlayerCommand(playerCommandEventArgs);
commands = playerCommandEventArgs.CommandList;
return playerCommandEventArgs.Handled; return playerCommandEventArgs.Handled;
} }
@ -94,5 +106,15 @@ namespace TShockAPI.Hooks
PlayerPreLogin(args); PlayerPreLogin(args);
return args.Handled; return args.Handled;
} }
public static void OnPlayerChat(TSPlayer ply, string rawtext, ref string tshockText)
{
if (PlayerChat == null)
return;
var args = new PlayerChatEventArgs {Player = ply, RawText = rawtext, TShockFormattedText = tshockText};
PlayerChat(args);
tshockText = args.TShockFormattedText;
}
} }
} }

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -32,12 +32,12 @@ namespace TShockAPI.Net
public void PackFull(Stream stream) public void PackFull(Stream stream)
{ {
long start = stream.Position; long start = stream.Position;
stream.WriteInt32(1); stream.WriteInt16(0);
stream.WriteInt8((byte) ID); stream.WriteInt8((byte) ID);
Pack(stream); Pack(stream);
long end = stream.Position; long end = stream.Position;
stream.Position = start; stream.Position = start;
stream.WriteInt32((int) (end - start) - 4); stream.WriteInt16((short)end);
stream.Position = end; stream.Position = end;
} }

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -33,7 +33,7 @@ namespace TShockAPI.Net
public override void Pack(Stream stream) public override void Pack(Stream stream)
{ {
stream.WriteBytes(Encoding.UTF8.GetBytes(Reason)); stream.WriteString(Reason);
} }
} }
} }

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -26,7 +26,7 @@ namespace TShockAPI.Net
public class NetTile : IPackable public class NetTile : IPackable
{ {
public bool Active { get; set; } public bool Active { get; set; }
public byte Type { get; set; } public ushort Type { get; set; }
public short FrameX { get; set; } public short FrameX { get; set; }
public short FrameY { get; set; } public short FrameY { get; set; }
public bool Lighted { get; set; } public bool Lighted { get; set; }
@ -45,6 +45,7 @@ namespace TShockAPI.Net
public byte WallColor { get; set; } public byte WallColor { get; set; }
public bool Slope { get; set; } public bool Slope { get; set; }
public bool Slope2 { get; set; } public bool Slope2 { get; set; }
public bool Slope3 { get; set; }
public bool HasColor public bool HasColor
{ {
@ -100,58 +101,58 @@ namespace TShockAPI.Net
public void Pack(Stream stream) public void Pack(Stream stream)
{ {
var flags = TileFlags.None; var bits = new BitsByte();
if ((Active) && (!Inactive)) if ((Active) && (!Inactive))
flags |= TileFlags.Active; bits[0] = true;
if (Lighted)
flags |= TileFlags.Lighted;
if (HasWall) if (HasWall)
flags |= TileFlags.Wall; bits[2] = true;
if (HasLiquid) if (HasLiquid)
flags |= TileFlags.Liquid; bits[3] = true;
if (Wire) if (Wire)
flags |= TileFlags.Wire; bits[4] = true;
if (IsHalf) if (IsHalf)
flags |= TileFlags.HalfBrick; bits[5] = true;
if (IsActuator) if (IsActuator)
flags |= TileFlags.Actuator; bits[6] = true;
if (Inactive) if (Inactive)
{ {
flags |= TileFlags.Inactive; bits[7] = true;
} }
stream.WriteInt8((byte) flags); stream.WriteInt8((byte) bits);
var flags2 = TileFlags2.None; bits = new BitsByte();
if ((Wire2)) if ((Wire2))
flags2 |= TileFlags2.Wire2; bits[0] = true;
if (Wire3) if (Wire3)
flags2 |= TileFlags2.Wire3; bits[1] = true;
if (HasColor) if (HasColor)
flags2 |= TileFlags2.Color; bits[2] = true;
if (HasWallColor) if (HasWallColor)
flags2 |= TileFlags2.WallColor; bits[3] = true;
if (Slope) if (Slope)
flags2 |= TileFlags2.Slope; bits[4] = true;
if (Slope2) if (Slope2)
flags2 |= TileFlags2.Slope2; bits[5] = true;
if (Slope3)
bits[6] = true;
stream.WriteInt8((byte)flags2); stream.WriteInt8((byte)bits);
if (HasColor) if (HasColor)
{ {
@ -165,7 +166,7 @@ namespace TShockAPI.Net
if (Active) if (Active)
{ {
stream.WriteInt8(Type); stream.WriteInt16((short)Type);
if (FrameImportant) if (FrameImportant)
{ {
stream.WriteInt16(FrameX); stream.WriteInt16(FrameX);
@ -185,28 +186,29 @@ namespace TShockAPI.Net
public void Unpack(Stream stream) public void Unpack(Stream stream)
{ {
var flags = (TileFlags) stream.ReadInt8(); var flags = (BitsByte) stream.ReadInt8();
var flags2 = (TileFlags2)stream.ReadInt8(); var flags2 = (BitsByte)stream.ReadInt8();
Wire2 = flags2.HasFlag(TileFlags2.Wire2); Wire2 = flags2[0];
Wire3 = flags2.HasFlag(TileFlags2.Wire3); Wire3 = flags2[1];
Slope = flags2.HasFlag(TileFlags2.Slope); Slope = flags2[4];
Slope2 = flags2.HasFlag(TileFlags2.Slope2); Slope2 = flags2[5];
Slope3 = flags2[6];
if (flags2.HasFlag(TileFlags2.Color)) if (flags2[2])
{ {
TileColor = stream.ReadInt8(); TileColor = stream.ReadInt8();
} }
if (flags2.HasFlag(TileFlags2.WallColor)) if (flags2[3])
{ {
WallColor = stream.ReadInt8(); WallColor = stream.ReadInt8();
} }
Active = flags.HasFlag(TileFlags.Active); Active = flags[0];
if (Active) if (Active)
{ {
Type = stream.ReadInt8(); Type = stream.ReadUInt16();
if (FrameImportant) if (FrameImportant)
{ {
FrameX = stream.ReadInt16(); FrameX = stream.ReadInt16();
@ -214,62 +216,31 @@ namespace TShockAPI.Net
} }
} }
if (flags.HasFlag(TileFlags.Lighted)) if (flags[2])
{
Lighted = true;
}
if (flags.HasFlag(TileFlags.Wall))
{ {
Wall = stream.ReadInt8(); Wall = stream.ReadInt8();
} }
if (flags.HasFlag(TileFlags.Liquid)) if (flags[3])
{ {
Liquid = stream.ReadInt8(); Liquid = stream.ReadInt8();
LiquidType = stream.ReadInt8(); LiquidType = stream.ReadInt8();
} }
if (flags.HasFlag(TileFlags.Wire)) if (flags[4])
Wire = true; Wire = true;
if (flags.HasFlag(TileFlags.HalfBrick)) if (flags[5])
IsHalf = true; IsHalf = true;
if (flags.HasFlag(TileFlags.Actuator)) if (flags[6])
IsActuator = true; IsActuator = true;
if (flags.HasFlag(TileFlags.Inactive)) if (flags[7])
{ {
Inactive = true; Inactive = true;
Active = false; Active = false;
} }
} }
} }
[Flags]
public enum TileFlags : byte
{
None = 0,
Active = 1,
Lighted = 2,
Wall = 4,
Liquid = 8,
Wire = 16,
HalfBrick = 32,
Actuator = 64,
Inactive = 128
}
[Flags]
public enum TileFlags2 : byte
{
None = 0,
Wire2 = 1,
Wire3 = 2,
Color = 4,
WallColor = 8,
Slope = 16,
Slope2 = 32
}
} }

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -41,8 +41,7 @@ namespace TShockAPI.Net
stream.WriteSingle(0); stream.WriteSingle(0);
stream.WriteInt16(0); stream.WriteInt16(0);
stream.WriteByte(Owner); stream.WriteByte(Owner);
stream.WriteByte(0); stream.WriteInt16(0);
stream.WriteSingle(0);
stream.WriteSingle(0); stream.WriteSingle(0);
stream.WriteSingle(0); stream.WriteSingle(0);
} }

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -28,8 +28,8 @@ namespace TShockAPI.Net
get { return PacketTypes.PlayerSpawn; } get { return PacketTypes.PlayerSpawn; }
} }
public int TileX { get; set; } public short TileX { get; set; }
public int TileY { get; set; } public short TileY { get; set; }
public byte PlayerIndex { get; set; } public byte PlayerIndex { get; set; }
public override void Pack(Stream stream) public override void Pack(Stream stream)

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -20,6 +20,7 @@ using System;
using System.IO; using System.IO;
using System.IO.Streams; using System.IO.Streams;
using System.Text; using System.Text;
using Terraria;
namespace TShockAPI.Net namespace TShockAPI.Net
{ {
@ -33,7 +34,8 @@ namespace TShockAPI.Net
DownedBoss3 = 8, DownedBoss3 = 8,
HardMode = 16, HardMode = 16,
DownedClown = 32, DownedClown = 32,
ServerSideCharacter = 64 ServerSideCharacter = 64,
DownedPlantBoss = 128
} }
[Flags] [Flags]
@ -46,7 +48,8 @@ namespace TShockAPI.Net
DownedMechBossAny = 8, DownedMechBossAny = 8,
CloudBg = 16, CloudBg = 16,
Crimson = 32, Crimson = 32,
Pumpkin = 64 PumpkinMoon = 64,
SnowMoon = 128
} }
public class WorldInfoMsg : BaseMsg public class WorldInfoMsg : BaseMsg
@ -56,12 +59,12 @@ namespace TShockAPI.Net
public byte MoonPhase { get; set; } public byte MoonPhase { get; set; }
public bool BloodMoon { get; set; } public bool BloodMoon { get; set; }
public bool Eclipse { get; set; } public bool Eclipse { get; set; }
public int MaxTilesX { get; set; } public short MaxTilesX { get; set; }
public int MaxTilesY { get; set; } public short MaxTilesY { get; set; }
public int SpawnX { get; set; } public short SpawnX { get; set; }
public int SpawnY { get; set; } public short SpawnY { get; set; }
public int WorldSurface { get; set; } public short WorldSurface { get; set; }
public int RockLayer { get; set; } public short RockLayer { get; set; }
public int WorldID { get; set; } public int WorldID { get; set; }
public byte MoonType { get; set; } public byte MoonType { get; set; }
public int TreeX0 { get; set; } public int TreeX0 { get; set; }
@ -103,50 +106,71 @@ namespace TShockAPI.Net
public override void Pack(Stream stream) public override void Pack(Stream stream)
{ {
stream.WriteInt32(Time); BinaryWriter writer = new BinaryWriter(stream);
stream.WriteBoolean(DayTime); writer.Write(Time);
stream.WriteInt8(MoonPhase); BitsByte worldinfo = new BitsByte(DayTime, BloodMoon, Eclipse);
stream.WriteBoolean(BloodMoon); writer.Write(worldinfo);
stream.WriteBoolean(Eclipse); writer.Write(MoonPhase);
stream.WriteInt32(MaxTilesX); writer.Write(MaxTilesX);
stream.WriteInt32(MaxTilesY); writer.Write(MaxTilesY);
stream.WriteInt32(SpawnX); writer.Write(SpawnX);
stream.WriteInt32(SpawnY); writer.Write(SpawnY);
stream.WriteInt32(WorldSurface); writer.Write(WorldSurface);
stream.WriteInt32(RockLayer); writer.Write(RockLayer);
stream.WriteInt32(WorldID); writer.Write(WorldID);
stream.WriteByte(MoonType); writer.Write(WorldName);
stream.WriteInt32(TreeX0); writer.Write(MoonType);
stream.WriteInt32(TreeX1);
stream.WriteInt32(TreeX2); writer.Write(SetBG0);
stream.WriteByte(TreeStyle0); writer.Write(SetBG1);
stream.WriteByte(TreeStyle1); writer.Write(SetBG2);
stream.WriteByte(TreeStyle2); writer.Write(SetBG3);
stream.WriteByte(TreeStyle3); writer.Write(SetBG4);
stream.WriteInt32(CaveBackX0); writer.Write(SetBG5);
stream.WriteInt32(CaveBackX1); writer.Write(SetBG6);
stream.WriteInt32(CaveBackX2); writer.Write(SetBG7);
stream.WriteByte(CaveBackStyle0); writer.Write(IceBackStyle);
stream.WriteByte(CaveBackStyle1); writer.Write(JungleBackStyle);
stream.WriteByte(CaveBackStyle2); writer.Write(HellBackStyle);
stream.WriteByte(CaveBackStyle3); writer.Write(WindSpeed);
stream.WriteByte(SetBG0); writer.Write(NumberOfClouds);
stream.WriteByte(SetBG1);
stream.WriteByte(SetBG2); writer.Write(TreeX0);
stream.WriteByte(SetBG3); writer.Write(TreeX1);
stream.WriteByte(SetBG4); writer.Write(TreeX2);
stream.WriteByte(SetBG5); writer.Write(TreeStyle0);
stream.WriteByte(SetBG6); writer.Write(TreeStyle1);
stream.WriteByte(SetBG7); writer.Write(TreeStyle2);
stream.WriteByte(IceBackStyle); writer.Write(TreeStyle3);
stream.WriteByte(JungleBackStyle); writer.Write(CaveBackX0);
stream.WriteByte(HellBackStyle); writer.Write(CaveBackX1);
stream.WriteSingle(WindSpeed); writer.Write(CaveBackX2);
stream.WriteByte(NumberOfClouds); writer.Write(CaveBackStyle0);
stream.WriteInt8((byte)BossFlags); writer.Write(CaveBackStyle1);
stream.WriteInt8((byte)BossFlags2); writer.Write(CaveBackStyle2);
stream.WriteSingle(Rain); writer.Write(CaveBackStyle3);
stream.WriteBytes(Encoding.UTF8.GetBytes(WorldName));
writer.Write(Rain);
BitsByte bosses1 = new BitsByte((BossFlags & BossFlags.OrbSmashed) == BossFlags.OrbSmashed,
(BossFlags & BossFlags.DownedBoss1) == BossFlags.DownedBoss1,
(BossFlags & BossFlags.DownedBoss2) == BossFlags.DownedBoss2,
(BossFlags & BossFlags.DownedBoss3) == BossFlags.DownedBoss3,
(BossFlags & BossFlags.HardMode) == BossFlags.HardMode,
(BossFlags & BossFlags.DownedClown) == BossFlags.DownedClown,
(BossFlags & BossFlags.ServerSideCharacter) == BossFlags.ServerSideCharacter,
(BossFlags & BossFlags.DownedPlantBoss) == BossFlags.DownedPlantBoss);
writer.Write(bosses1);
BitsByte bosses2 = new BitsByte((BossFlags2 & BossFlags2.DownedMechBoss1) == BossFlags2.DownedMechBoss1,
(BossFlags2 & BossFlags2.DownedMechBoss2) == BossFlags2.DownedMechBoss2,
(BossFlags2 & BossFlags2.DownedMechBoss3) == BossFlags2.DownedMechBoss3,
(BossFlags2 & BossFlags2.DownedMechBossAny) == BossFlags2.DownedMechBossAny,
(BossFlags2 & BossFlags2.CloudBg) == BossFlags2.CloudBg,
(BossFlags2 & BossFlags2.Crimson) == BossFlags2.Crimson,
(BossFlags2 & BossFlags2.PumpkinMoon) == BossFlags2.PumpkinMoon,
(BossFlags2 & BossFlags2.SnowMoon) == BossFlags2.SnowMoon);
writer.Write(bosses2);
} }
} }
} }

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -197,10 +197,10 @@ namespace TShockAPI
{ {
if (socket.tcpClient.Client != null && socket.tcpClient.Client.Poll(0, SelectMode.SelectWrite)) if (socket.tcpClient.Client != null && socket.tcpClient.Client.Poll(0, SelectMode.SelectWrite))
{ {
if (Main.runningMono) if (ServerApi.RunningMono && !ServerApi.UseAsyncSocketsInMono)
socket.networkStream.Write(buffer, offset, count); socket.networkStream.Write(buffer, offset, count);
else else
socket.tcpClient.Client.Send(buffer, offset, count, SocketFlags.None); socket.networkStream.BeginWrite(buffer, offset, count, socket.ServerWriteCallBack, socket.networkStream);
return true; return true;
} }
} }
@ -222,6 +222,19 @@ namespace TShockAPI
} }
catch (IOException e) catch (IOException e)
{ {
if (e.InnerException is SocketException)
{
switch (((SocketException)e.InnerException).SocketErrorCode)
{
case SocketError.Shutdown:
case SocketError.ConnectionReset:
break;
default:
Log.Warn(e.ToString());
break;
}
}
else
Log.Warn(e.ToString()); Log.Warn(e.ToString());
} }
return false; return false;

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -64,6 +64,12 @@ namespace TShockAPI
[Description("User can manage item bans.")] [Description("User can manage item bans.")]
public static readonly string manageitem = "tshock.admin.itemban"; public static readonly string manageitem = "tshock.admin.itemban";
[Description("User can manage projectile bans.")]
public static readonly string manageprojectile = "tshock.admin.projectileban";
[Description("User can manage tile bans.")]
public static readonly string managetile = "tshock.admin.tileban";
[Description("User can manage groups.")] [Description("User can manage groups.")]
public static readonly string managegroup = "tshock.admin.group"; public static readonly string managegroup = "tshock.admin.group";
@ -139,8 +145,8 @@ namespace TShockAPI
[Description("Prevents your actions from being ignored if damage is too high.")] [Description("Prevents your actions from being ignored if damage is too high.")]
public static readonly string ignoredamagecap = "tshock.ignore.damage"; public static readonly string ignoredamagecap = "tshock.ignore.damage";
[Description("Bypass server side inventory checks")] [Description("Bypass server side character checks")]
public static readonly string bypassinventorychecks = "tshock.ignore.ssi"; public static readonly string bypassssc = "tshock.ignore.ssc";
[Description("Allow unrestricted SendTileSquare usage, for client side world editing.")] [Description("Allow unrestricted SendTileSquare usage, for client side world editing.")]
public static readonly string allowclientsideworldedit = "tshock.ignore.sendtilesquare"; public static readonly string allowclientsideworldedit = "tshock.ignore.sendtilesquare";
@ -148,6 +154,12 @@ namespace TShockAPI
[Description("Allow dropping banned items without the item being eaten.")] [Description("Allow dropping banned items without the item being eaten.")]
public static readonly string allowdroppingbanneditems = "tshock.ignore.dropbanneditem"; public static readonly string allowdroppingbanneditems = "tshock.ignore.dropbanneditem";
[Description("Prevents you from being disabled by abnormal HP.")]
public static readonly string ignorehp = "tshock.ignore.hp";
[Description("Prevents you from being disabled by abnormal MP.")]
public static readonly string ignoremp = "tshock.ignore.mp";
// tshock.item nodes // tshock.item nodes
[Description("User can spawn items.")] [Description("User can spawn items.")]
@ -167,9 +179,15 @@ namespace TShockAPI
[Description("User can start an invasion.")] [Description("User can start an invasion.")]
public static readonly string invade = "tshock.npc.invade"; public static readonly string invade = "tshock.npc.invade";
[Description("User can hurt town NPCs.")]
public static readonly string hurttownnpc = "tshock.npc.hurttown";
[Description("User can spawn bosses.")] [Description("User can spawn bosses.")]
public static readonly string spawnboss = "tshock.npc.spawnboss"; public static readonly string spawnboss = "tshock.npc.spawnboss";
[Description("User can rename NPCs.")]
public static readonly string renamenpc = "tshock.npc.rename";
[Description("User can spawn npcs.")] [Description("User can spawn npcs.")]
public static readonly string spawnmob = "tshock.npc.spawnmob"; public static readonly string spawnmob = "tshock.npc.spawnmob";
@ -182,6 +200,9 @@ namespace TShockAPI
[Description("User can start invasions (Goblin/Snow Legion) using items")] [Description("User can start invasions (Goblin/Snow Legion) using items")]
public static readonly string startinvasion = "tshock.npc.startinvasion"; public static readonly string startinvasion = "tshock.npc.startinvasion";
[Description("User can clear the list of users who have completed an angler quest that day.")]
public static readonly string clearangler = "tshock.npc.clearanglerquests";
// tshock.superadmin nodes // tshock.superadmin nodes
[Description("Meant for super admins only.")] [Description("Meant for super admins only.")]
@ -192,20 +213,29 @@ namespace TShockAPI
// tshock.tp nodes // tshock.tp nodes
[Description("User can teleport *everyone* to them.")]
public static readonly string tpallothers = "tshock.tp.allothers";
[Description("User can teleport to others.")] [Description("User can teleport to others.")]
public static readonly string tp = "tshock.tp.self"; public static readonly string tp = "tshock.tp.self";
[Description("User can teleport people to them.")] [Description("User can teleport other people.")]
public static readonly string tphere = "tshock.tp.others"; public static readonly string tpothers = "tshock.tp.others";
[Description("Users can stop people from teleporting to them")] [Description("User can teleport to tile positions.")]
public static readonly string tppos = "tshock.tp.pos";
[Description("User can teleport to an NPC.")]
public static readonly string tpnpc = "tshock.tp.npc";
[Description("Users can stop people from teleporting.")]
public static readonly string tpallow = "tshock.tp.block"; public static readonly string tpallow = "tshock.tp.block";
[Description("Users can tp to anyone")] [Description("Users can override teleport blocks.")]
public static readonly string tpall = "tshock.tp.toall"; public static readonly string tpoverride = "tshock.tp.override";
[Description("Users can tp to people without showing a notice")] [Description("Users can teleport to people without showing a notice")]
public static readonly string tphide = "tshock.tp.silent"; public static readonly string tpsilent = "tshock.tp.silent";
[Description("User can use /home.")] [Description("User can use /home.")]
public static readonly string home = "tshock.tp.home"; public static readonly string home = "tshock.tp.home";
@ -227,12 +257,6 @@ namespace TShockAPI
[Description("User can force a blood moon.")] [Description("User can force a blood moon.")]
public static readonly string bloodmoon = "tshock.world.time.bloodmoon"; public static readonly string bloodmoon = "tshock.world.time.bloodmoon";
[Description("User can force a pumpkin moon.")]
public static readonly string pumpkinmoon = "tshock.world.time.pumpkinmoon";
[Description("User can force a snow moon.")]
public static readonly string snowmoon = "tshock.world.time.snowmoon";
[Description("User can set the time.")] [Description("User can set the time.")]
public static readonly string time = "tshock.world.time.set"; public static readonly string time = "tshock.world.time.set";
@ -248,6 +272,9 @@ namespace TShockAPI
[Description("User can convert hallow into corruption and vice-versa")] [Description("User can convert hallow into corruption and vice-versa")]
public static readonly string converthardmode = "tshock.world.converthardmode"; public static readonly string converthardmode = "tshock.world.converthardmode";
[Description("User can force the server to Halloween mode.")]
public static readonly string halloween = "tshock.world.sethalloween";
[Description("User can force the server to Christmas mode.")] [Description("User can force the server to Christmas mode.")]
public static readonly string xmas = "tshock.world.setxmas"; public static readonly string xmas = "tshock.world.setxmas";
@ -281,6 +308,9 @@ namespace TShockAPI
[Description("User can turn on or off the rain.")] [Description("User can turn on or off the rain.")]
public static readonly string rain = "tshock.world.rain"; public static readonly string rain = "tshock.world.rain";
[Description("User can modify the wind.")]
public static readonly string wind = "tshock.world.wind";
// Non-grouped // Non-grouped
[Description("User can clear items or projectiles.")] [Description("User can clear items or projectiles.")]
@ -322,6 +352,12 @@ namespace TShockAPI
[Description("Player can chat")] [Description("Player can chat")]
public static readonly string canchat = "tshock.canchat"; public static readonly string canchat = "tshock.canchat";
[Description("Player can use banned projectiles.")]
public static readonly string canusebannedprojectiles = "tshock.projectiles.usebanned";
[Description("Player can place banned tiles.")]
public static readonly string canusebannedtiles = "tshock.tiles.usebanned";
/// <summary> /// <summary>
/// Lists all commands associated with a given permission /// Lists all commands associated with a given permission
/// </summary> /// </summary>

14
TShockAPI/Properties/AssemblyInfo.cs Normal file → Executable file
View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -28,7 +28,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Nyx Studios & TShock Contributors")] [assembly: AssemblyCompany("Nyx Studios & TShock Contributors")]
[assembly: AssemblyProduct("TShockAPI")] [assembly: AssemblyProduct("TShockAPI")]
[assembly: AssemblyCopyright("Copyright © Nyx Studios 2011-2013")] [assembly: AssemblyCopyright("Copyright © Nyx Studios 2011-2015")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
@ -47,7 +47,11 @@ using System.Runtime.InteropServices;
// Major Version // Major Version
// Minor Version // Minor Version
// Build Number // Build Number
// MMdd of the build // Starting in version 4.2.5, we are no longer including the fourth decimal
// location, which previously held the date and time.
[assembly: AssemblyVersion("4.2.2.1228")] // Also, be sure to release on github with the exact assembly version tag as below
[assembly: AssemblyFileVersion("4.2.2.1228")] // so that the update manager works correctly (via the Github releases api and mimic)
[assembly: AssemblyVersion("4.2.5")]
[assembly: AssemblyFileVersion("4.2.5")]

View file

@ -1,38 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TShockAPI
{
/// <summary>
/// Custom packet types for use with Raptor.
/// </summary>
public enum RaptorPacketTypes : byte
{
/// <summary>
/// The packet sent to the server to be acknowledged as a Raptor client.
/// </summary>
Acknowledge = 0,
/// <summary>
/// The packet sent to the client which dictates its permissions.
/// </summary>
Permissions,
/// <summary>
/// The packet sent which sets region info.
/// </summary>
Region,
/// <summary>
/// The packet sent to delete a region.
/// </summary>
RegionDelete,
/// <summary>
/// The packet sent which sets warp info.
/// </summary>
Warp,
/// <summary>
/// The packet sent to delete a warp.
/// </summary>
WarpDelete
}
}

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -37,17 +37,31 @@ namespace Rests
/// <param name="parameters">Parameters in the url</param> /// <param name="parameters">Parameters in the url</param>
/// <param name="verbs">{x} in urltemplate</param> /// <param name="verbs">{x} in urltemplate</param>
/// <returns>Response object or null to not handle request</returns> /// <returns>Response object or null to not handle request</returns>
public delegate object RestCommandD(RestVerbs verbs, IParameterCollection parameters); public delegate object RestCommandD(RestRequestArgs args);
/// <summary> public class RestRequestArgs
/// Secure Rest command delegate including token data. {
/// </summary> public RestVerbs Verbs { get; private set; }
/// <param name="parameters">Parameters in the url</param> public IParameterCollection Parameters { get; private set; }
/// <param name="verbs">{x} in urltemplate</param> public IRequest Request { get; private set; }
/// <param name="tokenData">The data of stored for the provided token.</param> public SecureRest.TokenData TokenData { get; private set; }
/// <returns>Response object or null to not handle request</returns>
public delegate object SecureRestCommandD(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData);
public RestRequestArgs(RestVerbs verbs, IParameterCollection param, IRequest request)
{
Verbs = verbs;
Parameters = param;
Request = request;
TokenData = SecureRest.TokenData.None;
}
public RestRequestArgs(RestVerbs verbs, IParameterCollection param, IRequest request, SecureRest.TokenData tokenData)
{
Verbs = verbs;
Parameters = param;
Request = request;
TokenData = tokenData;
}
}
public class Rest : IDisposable public class Rest : IDisposable
{ {
private readonly List<RestCommand> commands = new List<RestCommand>(); private readonly List<RestCommand> commands = new List<RestCommand>();
@ -173,7 +187,7 @@ namespace Rests
continue; continue;
} }
var obj = ExecuteCommand(com, verbs, e.Request.Parameters); var obj = ExecuteCommand(com, verbs, e.Request.Parameters, e.Request);
if (obj != null) if (obj != null)
return obj; return obj;
} }
@ -193,9 +207,9 @@ namespace Rests
}; };
} }
protected virtual object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms) protected virtual object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms, IRequest request)
{ {
object result = cmd.Execute(verbs, parms); object result = cmd.Execute(verbs, parms, request);
if (cmd.DoLog && TShock.Config.LogRest) if (cmd.DoLog && TShock.Config.LogRest)
{ {
Log.ConsoleInfo("Anonymous requested REST endpoint: " + BuildRequestUri(cmd, verbs, parms, false)); Log.ConsoleInfo("Anonymous requested REST endpoint: " + BuildRequestUri(cmd, verbs, parms, false));

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -65,9 +65,9 @@ namespace Rests
get { return UriVerbs.Length > 0; } get { return UriVerbs.Length > 0; }
} }
public virtual object Execute(RestVerbs verbs, IParameterCollection parameters) public virtual object Execute(RestVerbs verbs, IParameterCollection parameters, IRequest request)
{ {
return callback(verbs, parameters); return callback(new RestRequestArgs(verbs, parameters, request));
} }
} }
@ -76,31 +76,31 @@ namespace Rests
public override bool RequiresToken { get { return true; } } public override bool RequiresToken { get { return true; } }
public string[] Permissions { get; set; } public string[] Permissions { get; set; }
private SecureRestCommandD callback; private RestCommandD callback;
public SecureRestCommand(string name, string uritemplate, SecureRestCommandD callback, params string[] permissions) public SecureRestCommand(string name, string uritemplate, RestCommandD callback, params string[] permissions)
: base(name, uritemplate, null) : base(name, uritemplate, null)
{ {
this.callback = callback; this.callback = callback;
Permissions = permissions; Permissions = permissions;
} }
public SecureRestCommand(string uritemplate, SecureRestCommandD callback, params string[] permissions) public SecureRestCommand(string uritemplate, RestCommandD callback, params string[] permissions)
: this(string.Empty, uritemplate, callback, permissions) : this(string.Empty, uritemplate, callback, permissions)
{ {
} }
public override object Execute(RestVerbs verbs, IParameterCollection parameters) public override object Execute(RestVerbs verbs, IParameterCollection parameters, IRequest request)
{ {
return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." }; return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." };
} }
public object Execute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) public object Execute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData, IRequest request)
{ {
if (tokenData.Equals(SecureRest.TokenData.None)) if (tokenData.Equals(SecureRest.TokenData.None))
return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." }; return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." };
return callback(verbs, parameters, tokenData); return callback(new RestRequestArgs(verbs, parameters, request, tokenData));
} }
} }
} }

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -49,10 +49,10 @@ namespace TShockAPI
} }
else else
{ {
Rest.Register(new RestCommand("/v2/server/status", (a, b) => this.ServerStatusV2(a, b, SecureRest.TokenData.None))); Rest.Register(new RestCommand("/v2/server/status", (a) => this.ServerStatusV2(new RestRequestArgs(a.Verbs, a.Parameters, a.Request, SecureRest.TokenData.None))));
Rest.Register(new RestCommand("/status", (a, b) => this.ServerStatus(a, b, SecureRest.TokenData.None))); Rest.Register(new RestCommand("/status", (a) => this.ServerStatus(new RestRequestArgs(a.Verbs, a.Parameters, a.Request, SecureRest.TokenData.None))));
Rest.Register(new RestCommand("/v3/server/motd", (a, b) => this.ServerMotd(a, b, SecureRest.TokenData.None))); Rest.Register(new RestCommand("/v3/server/motd", (a) => this.ServerMotd(new RestRequestArgs(a.Verbs, a.Parameters, a.Request, SecureRest.TokenData.None))));
Rest.Register(new RestCommand("/v3/server/rules", (a, b) => this.ServerRules(a, b, SecureRest.TokenData.None))); Rest.Register(new RestCommand("/v3/server/rules", (a) => this.ServerRules(new RestRequestArgs(a.Verbs, a.Parameters, a.Request, SecureRest.TokenData.None))));
} }
Rest.Register(new SecureRestCommand("/v2/server/broadcast", ServerBroadcast)); Rest.Register(new SecureRestCommand("/v2/server/broadcast", ServerBroadcast));
@ -89,6 +89,7 @@ namespace TShockAPI
Rest.Register(new SecureRestCommand("/lists/players", PlayerList)); Rest.Register(new SecureRestCommand("/lists/players", PlayerList));
Rest.Register(new SecureRestCommand("/v2/players/list", PlayerListV2)); Rest.Register(new SecureRestCommand("/v2/players/list", PlayerListV2));
Rest.Register(new SecureRestCommand("/v2/players/read", PlayerReadV2, RestPermissions.restuserinfo)); Rest.Register(new SecureRestCommand("/v2/players/read", PlayerReadV2, RestPermissions.restuserinfo));
Rest.Register(new SecureRestCommand("/v3/players/read", PlayerReadV3, RestPermissions.restuserinfo));
Rest.Register(new SecureRestCommand("/v2/players/kick", PlayerKickV2, RestPermissions.restkick)); Rest.Register(new SecureRestCommand("/v2/players/kick", PlayerKickV2, RestPermissions.restkick));
Rest.Register(new SecureRestCommand("/v2/players/ban", PlayerBanV2, RestPermissions.restban, RestPermissions.restmanagebans)); Rest.Register(new SecureRestCommand("/v2/players/ban", PlayerBanV2, RestPermissions.restban, RestPermissions.restmanagebans));
Rest.Register(new SecureRestCommand("/v2/players/kill", PlayerKill, RestPermissions.restkill)); Rest.Register(new SecureRestCommand("/v2/players/kill", PlayerKill, RestPermissions.restkill));
@ -105,84 +106,84 @@ namespace TShockAPI
#region RestServerMethods #region RestServerMethods
private object ServerCommand(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object ServerCommand(RestRequestArgs args)
{ {
if (string.IsNullOrWhiteSpace(parameters["cmd"])) if (string.IsNullOrWhiteSpace(args.Parameters["cmd"]))
return RestMissingParam("cmd"); return RestMissingParam("cmd");
Group restPlayerGroup; Group restPlayerGroup;
// TODO: Get rid of this when the old REST permission model is removed. // TODO: Get rid of this when the old REST permission model is removed.
if (TShock.Config.RestUseNewPermissionModel) if (TShock.Config.RestUseNewPermissionModel)
restPlayerGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName); restPlayerGroup = TShock.Groups.GetGroupByName(args.TokenData.UserGroupName);
else else
restPlayerGroup = new SuperAdminGroup(); restPlayerGroup = new SuperAdminGroup();
TSRestPlayer tr = new TSRestPlayer(tokenData.Username, restPlayerGroup); TSRestPlayer tr = new TSRestPlayer(args.TokenData.Username, restPlayerGroup);
Commands.HandleCommand(tr, parameters["cmd"]); Commands.HandleCommand(tr, args.Parameters["cmd"]);
return RestResponse(string.Join("\n", tr.GetCommandOutput())); return RestResponse(string.Join("\n", tr.GetCommandOutput()));
} }
private object ServerCommandV3(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object ServerCommandV3(RestRequestArgs args)
{ {
if (string.IsNullOrWhiteSpace(parameters["cmd"])) if (string.IsNullOrWhiteSpace(args.Parameters["cmd"]))
return RestMissingParam("cmd"); return RestMissingParam("cmd");
Group restPlayerGroup; Group restPlayerGroup;
// TODO: Get rid of this when the old REST permission model is removed. // TODO: Get rid of this when the old REST permission model is removed.
if (TShock.Config.RestUseNewPermissionModel) if (TShock.Config.RestUseNewPermissionModel)
restPlayerGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName); restPlayerGroup = TShock.Groups.GetGroupByName(args.TokenData.UserGroupName);
else else
restPlayerGroup = new SuperAdminGroup(); restPlayerGroup = new SuperAdminGroup();
TSRestPlayer tr = new TSRestPlayer(tokenData.Username, restPlayerGroup); TSRestPlayer tr = new TSRestPlayer(args.TokenData.Username, restPlayerGroup);
Commands.HandleCommand(tr, parameters["cmd"]); Commands.HandleCommand(tr, args.Parameters["cmd"]);
return new RestObject() return new RestObject()
{ {
{"response", tr.GetCommandOutput()} {"response", tr.GetCommandOutput()}
}; };
} }
private object ServerOff(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object ServerOff(RestRequestArgs args)
{ {
if (!GetBool(parameters["confirm"], false)) if (!GetBool(args.Parameters["confirm"], false))
return RestInvalidParam("confirm"); return RestInvalidParam("confirm");
// Inform players the server is shutting down // Inform players the server is shutting down
var reason = string.IsNullOrWhiteSpace(parameters["message"]) ? "Server is shutting down" : parameters["message"]; var reason = string.IsNullOrWhiteSpace(args.Parameters["message"]) ? "Server is shutting down" : args.Parameters["message"];
TShock.Utils.StopServer(!GetBool(parameters["nosave"], false), reason); TShock.Utils.StopServer(!GetBool(args.Parameters["nosave"], false), reason);
return RestResponse("The server is shutting down"); return RestResponse("The server is shutting down");
} }
private object ServerRestart(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object ServerRestart(RestRequestArgs args)
{ {
if (!GetBool(parameters["confirm"], false)) if (!GetBool(args.Parameters["confirm"], false))
return RestInvalidParam("confirm"); return RestInvalidParam("confirm");
// Inform players the server is shutting down // Inform players the server is shutting down
var reason = string.IsNullOrWhiteSpace(parameters["message"]) ? "Server is restarting" : parameters["message"]; var reason = string.IsNullOrWhiteSpace(args.Parameters["message"]) ? "Server is restarting" : args.Parameters["message"];
TShock.Utils.RestartServer(!GetBool(parameters["nosave"], false), reason); TShock.Utils.RestartServer(!GetBool(args.Parameters["nosave"], false), reason);
return RestResponse("The server is shutting down and will attempt to restart"); return RestResponse("The server is shutting down and will attempt to restart");
} }
private object ServerReload(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object ServerReload(RestRequestArgs args)
{ {
TShock.Utils.Reload(new TSRestPlayer(tokenData.Username, TShock.Groups.GetGroupByName(tokenData.UserGroupName))); TShock.Utils.Reload(new TSRestPlayer(args.TokenData.Username, TShock.Groups.GetGroupByName(args.TokenData.UserGroupName)));
return RestResponse("Configuration, permissions, and regions reload complete. Some changes may require a server restart."); return RestResponse("Configuration, permissions, and regions reload complete. Some changes may require a server restart.");
} }
private object ServerBroadcast(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object ServerBroadcast(RestRequestArgs args)
{ {
var msg = parameters["msg"]; var msg = args.Parameters["msg"];
if (string.IsNullOrWhiteSpace(msg)) if (string.IsNullOrWhiteSpace(msg))
return RestMissingParam("msg"); return RestMissingParam("msg");
TShock.Utils.Broadcast(msg); TShock.Utils.Broadcast(msg);
return RestResponse("The message was broadcasted successfully"); return RestResponse("The message was broadcasted successfully");
} }
private object ServerMotd(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object ServerMotd(RestRequestArgs args)
{ {
string motdFilePath = Path.Combine(TShock.SavePath, "motd.txt"); string motdFilePath = Path.Combine(TShock.SavePath, "motd.txt");
if (!File.Exists(motdFilePath)) if (!File.Exists(motdFilePath))
@ -194,7 +195,7 @@ namespace TShockAPI
}; };
} }
private object ServerRules(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object ServerRules(RestRequestArgs args)
{ {
string rulesFilePath = Path.Combine(TShock.SavePath, "rules.txt"); string rulesFilePath = Path.Combine(TShock.SavePath, "rules.txt");
if (!File.Exists(rulesFilePath)) if (!File.Exists(rulesFilePath))
@ -206,7 +207,7 @@ namespace TShockAPI
}; };
} }
private object ServerStatus(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object ServerStatus(RestRequestArgs args)
{ {
var activeplayers = Main.player.Where(p => null != p && p.active).ToList(); var activeplayers = Main.player.Where(p => null != p && p.active).ToList();
return new RestObject() return new RestObject()
@ -218,11 +219,13 @@ namespace TShockAPI
}; };
} }
private object ServerStatusV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object ServerStatusV2(RestRequestArgs args)
{ {
var ret = new RestObject() var ret = new RestObject()
{ {
{"name", TShock.Config.ServerName}, {"name", TShock.Config.ServerName},
{"serverversion", Main.versionNumber},
{"tshockversion", TShock.VersionNum},
{"port", TShock.Config.ServerPort}, {"port", TShock.Config.ServerPort},
{"playercount", Main.player.Where(p => null != p && p.active).Count()}, {"playercount", Main.player.Where(p => null != p && p.active).Count()},
{"maxplayers", TShock.Config.MaxSlots}, {"maxplayers", TShock.Config.MaxSlots},
@ -231,19 +234,19 @@ namespace TShockAPI
{"serverpassword", !string.IsNullOrEmpty(TShock.Config.ServerPassword)} {"serverpassword", !string.IsNullOrEmpty(TShock.Config.ServerPassword)}
}; };
if (GetBool(parameters["players"], false)) if (GetBool(args.Parameters["players"], false))
{ {
var players = new ArrayList(); var players = new ArrayList();
foreach (TSPlayer tsPlayer in TShock.Players.Where(p => null != p)) foreach (TSPlayer tsPlayer in TShock.Players.Where(p => null != p))
{ {
var p = PlayerFilter(tsPlayer, parameters, ((tokenData.UserGroupName) != "" && TShock.Utils.GetGroup(tokenData.UserGroupName).HasPermission(RestPermissions.viewips))); var p = PlayerFilter(tsPlayer, args.Parameters, ((args.TokenData.UserGroupName) != "" && TShock.Utils.GetGroup(args.TokenData.UserGroupName).HasPermission(RestPermissions.viewips)));
if (null != p) if (null != p)
players.Add(p); players.Add(p);
} }
ret.Add("players", players); ret.Add("players", players);
} }
if (GetBool(parameters["rules"], false)) if (GetBool(args.Parameters["rules"], false))
{ {
var rules = new Dictionary<string,object>(); var rules = new Dictionary<string,object>();
rules.Add("AutoSave", TShock.Config.AutoSave); rules.Add("AutoSave", TShock.Config.AutoSave);
@ -258,19 +261,19 @@ namespace TShockAPI
rules.Add("PvPMode", TShock.Config.PvPMode); rules.Add("PvPMode", TShock.Config.PvPMode);
rules.Add("SpawnProtection", TShock.Config.SpawnProtection); rules.Add("SpawnProtection", TShock.Config.SpawnProtection);
rules.Add("SpawnProtectionRadius", TShock.Config.SpawnProtectionRadius); rules.Add("SpawnProtectionRadius", TShock.Config.SpawnProtectionRadius);
rules.Add("ServerSideInventory", TShock.Config.ServerSideCharacter); rules.Add("ServerSideInventory", Main.ServerSideCharacter);
ret.Add("rules", rules); ret.Add("rules", rules);
} }
return ret; return ret;
} }
private object ServerTokenTest(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object ServerTokenTest(RestRequestArgs args)
{ {
return new RestObject() return new RestObject()
{ {
{"response", "Token is valid and was passed through correctly."}, {"response", "Token is valid and was passed through correctly."},
{"associateduser", tokenData.Username} {"associateduser", args.TokenData.Username}
}; };
} }
@ -278,12 +281,12 @@ namespace TShockAPI
#region RestUserMethods #region RestUserMethods
private object UserActiveListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object UserActiveListV2(RestRequestArgs args)
{ {
return new RestObject() { { "activeusers", string.Join("\t", TShock.Players.Where(p => null != p && null != p.UserAccountName && p.Active).Select(p => p.UserAccountName)) } }; return new RestObject() { { "activeusers", string.Join("\t", TShock.Players.Where(p => null != p && null != p.UserAccountName && p.Active).Select(p => p.UserAccountName)) } };
} }
private object UserListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object UserListV2(RestRequestArgs args)
{ {
return new RestObject() { { "users", TShock.Users.GetUsers().Select(p => new Dictionary<string,object>(){ return new RestObject() { { "users", TShock.Users.GetUsers().Select(p => new Dictionary<string,object>(){
{"name", p.Name}, {"name", p.Name},
@ -292,17 +295,17 @@ namespace TShockAPI
}) } }; }) } };
} }
private object UserCreateV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object UserCreateV2(RestRequestArgs args)
{ {
var username = parameters["user"]; var username = args.Parameters["user"];
if (string.IsNullOrWhiteSpace(username)) if (string.IsNullOrWhiteSpace(username))
return RestMissingParam("user"); return RestMissingParam("user");
var group = parameters["group"]; var group = args.Parameters["group"];
if (string.IsNullOrWhiteSpace(group)) if (string.IsNullOrWhiteSpace(group))
group = TShock.Config.DefaultRegistrationGroupName; group = TShock.Config.DefaultRegistrationGroupName;
var password = parameters["password"]; var password = args.Parameters["password"];
if (string.IsNullOrWhiteSpace(password)) if (string.IsNullOrWhiteSpace(password))
return RestMissingParam("password"); return RestMissingParam("password");
@ -320,14 +323,14 @@ namespace TShockAPI
return RestResponse("User was successfully created"); return RestResponse("User was successfully created");
} }
private object UserUpdateV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object UserUpdateV2(RestRequestArgs args)
{ {
var ret = UserFind(parameters); var ret = UserFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
var password = parameters["password"]; var password = args.Parameters["password"];
var group = parameters["group"]; var group = args.Parameters["group"];
if (string.IsNullOrWhiteSpace(group) && string.IsNullOrWhiteSpace(password)) if (string.IsNullOrWhiteSpace(group) && string.IsNullOrWhiteSpace(password))
return RestMissingParam("group", "password"); return RestMissingParam("group", "password");
@ -362,9 +365,9 @@ namespace TShockAPI
return response; return response;
} }
private object UserDestroyV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object UserDestroyV2(RestRequestArgs args)
{ {
var ret = UserFind(parameters); var ret = UserFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
@ -380,9 +383,9 @@ namespace TShockAPI
return RestResponse("User deleted successfully"); return RestResponse("User deleted successfully");
} }
private object UserInfoV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object UserInfoV2(RestRequestArgs args)
{ {
var ret = UserFind(parameters); var ret = UserFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
@ -394,17 +397,17 @@ namespace TShockAPI
#region RestBanMethods #region RestBanMethods
private object BanCreate(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object BanCreate(RestRequestArgs args)
{ {
var ip = parameters["ip"]; var ip = args.Parameters["ip"];
var name = parameters["name"]; var name = args.Parameters["name"];
if (string.IsNullOrWhiteSpace(ip) && string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(ip) && string.IsNullOrWhiteSpace(name))
return RestMissingParam("ip", "name"); return RestMissingParam("ip", "name");
try try
{ {
TShock.Bans.AddBan(ip, name, "", parameters["reason"], true, tokenData.Username); TShock.Bans.AddBan(ip, name, "", args.Parameters["reason"], true, args.TokenData.Username);
} }
catch (Exception e) catch (Exception e)
{ {
@ -413,27 +416,27 @@ namespace TShockAPI
return RestResponse("Ban created successfully"); return RestResponse("Ban created successfully");
} }
private object BanDestroyV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object BanDestroyV2(RestRequestArgs args)
{ {
var ret = BanFind(parameters); var ret = BanFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
try try
{ {
Ban ban = (Ban)ret; Ban ban = (Ban)ret;
switch (parameters["type"]) switch (args.Parameters["type"])
{ {
case "ip": case "ip":
if (!TShock.Bans.RemoveBan(ban.IP, false, false, true)) if (!TShock.Bans.RemoveBan(ban.IP, false, false, true))
return RestResponse("Failed to delete ban (already deleted?)"); return RestResponse("Failed to delete ban (already deleted?)");
break; break;
case "name": case "name":
if (!TShock.Bans.RemoveBan(ban.Name, true, GetBool(parameters["caseinsensitive"], true))) if (!TShock.Bans.RemoveBan(ban.Name, true, GetBool(args.Parameters["caseinsensitive"], true)))
return RestResponse("Failed to delete ban (already deleted?)"); return RestResponse("Failed to delete ban (already deleted?)");
break; break;
default: default:
return RestError("Invalid Type: '" + parameters["type"] + "'"); return RestError("Invalid Type: '" + args.Parameters["type"] + "'");
} }
} }
@ -445,9 +448,9 @@ namespace TShockAPI
return RestResponse("Ban deleted successfully"); return RestResponse("Ban deleted successfully");
} }
private object BanInfoV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object BanInfoV2(RestRequestArgs args)
{ {
var ret = BanFind(parameters); var ret = BanFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
@ -459,7 +462,7 @@ namespace TShockAPI
}; };
} }
private object BanListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object BanListV2(RestRequestArgs args)
{ {
var banList = new ArrayList(); var banList = new ArrayList();
foreach (var ban in TShock.Bans.GetBans()) foreach (var ban in TShock.Bans.GetBans())
@ -481,32 +484,29 @@ namespace TShockAPI
#region RestWorldMethods #region RestWorldMethods
private object WorldChangeSaveSettings(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object WorldChangeSaveSettings(RestRequestArgs args)
{ {
bool autoSave; bool autoSave;
if (!bool.TryParse(verbs["bool"], out autoSave)) if (!bool.TryParse(args.Verbs["bool"], out autoSave))
return RestInvalidParam("state"); return RestInvalidParam("state");
TShock.Config.AutoSave = autoSave; TShock.Config.AutoSave = autoSave;
return RestResponse("AutoSave has been set to " + autoSave); return RestResponse("AutoSave has been set to " + autoSave);
} }
private object WorldSave(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object WorldSave(RestRequestArgs args)
{ {
SaveManager.Instance.SaveWorld(); SaveManager.Instance.SaveWorld();
return RestResponse("World saved"); return RestResponse("World saved");
} }
private object WorldButcher(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object WorldButcher(RestRequestArgs args)
{ {
bool killFriendly; bool killFriendly;
if (!bool.TryParse(parameters["killfriendly"], out killFriendly)) if (!bool.TryParse(args.Parameters["killfriendly"], out killFriendly))
return RestInvalidParam("killfriendly"); return RestInvalidParam("killfriendly");
if (killFriendly)
killFriendly = !killFriendly;
int killcount = 0; int killcount = 0;
for (int i = 0; i < Main.npc.Length; i++) for (int i = 0; i < Main.npc.Length; i++)
{ {
@ -520,7 +520,7 @@ namespace TShockAPI
return RestResponse(killcount + " NPCs have been killed"); return RestResponse(killcount + " NPCs have been killed");
} }
private object WorldRead(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object WorldRead(RestRequestArgs args)
{ {
return new RestObject() return new RestObject()
{ {
@ -533,7 +533,7 @@ namespace TShockAPI
}; };
} }
private object WorldMeteor(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object WorldMeteor(RestRequestArgs args)
{ {
if (null == WorldGen.genRand) if (null == WorldGen.genRand)
WorldGen.genRand = new Random(); WorldGen.genRand = new Random();
@ -541,10 +541,10 @@ namespace TShockAPI
return RestResponse("Meteor has been spawned"); return RestResponse("Meteor has been spawned");
} }
private object WorldBloodmoon(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object WorldBloodmoon(RestRequestArgs args)
{ {
bool bloodmoon; bool bloodmoon;
if (!bool.TryParse(verbs["bool"], out bloodmoon)) if (!bool.TryParse(args.Verbs["bool"], out bloodmoon))
return RestInvalidParam("bloodmoon"); return RestInvalidParam("bloodmoon");
Main.bloodMoon = bloodmoon; Main.bloodMoon = bloodmoon;
@ -555,37 +555,37 @@ namespace TShockAPI
#region RestPlayerMethods #region RestPlayerMethods
private object PlayerUnMute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object PlayerUnMute(RestRequestArgs args)
{ {
return PlayerSetMute(parameters, false); return PlayerSetMute(args.Parameters, false);
} }
private object PlayerMute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object PlayerMute(RestRequestArgs args)
{ {
return PlayerSetMute(parameters, true); return PlayerSetMute(args.Parameters, true);
} }
private object PlayerList(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object PlayerList(RestRequestArgs args)
{ {
var activeplayers = Main.player.Where(p => null != p && p.active).ToList(); var activeplayers = Main.player.Where(p => null != p && p.active).ToList();
return new RestObject() { { "players", string.Join(", ", activeplayers.Select(p => p.name)) } }; return new RestObject() { { "players", string.Join(", ", activeplayers.Select(p => p.name)) } };
} }
private object PlayerListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object PlayerListV2(RestRequestArgs args)
{ {
var playerList = new ArrayList(); var playerList = new ArrayList();
foreach (TSPlayer tsPlayer in TShock.Players.Where(p => null != p)) foreach (TSPlayer tsPlayer in TShock.Players.Where(p => null != p))
{ {
var p = PlayerFilter(tsPlayer, parameters); var p = PlayerFilter(tsPlayer, args.Parameters);
if (null != p) if (null != p)
playerList.Add(p); playerList.Add(p);
} }
return new RestObject() { { "players", playerList } }; return new RestObject() { { "players", playerList } };
} }
private object PlayerReadV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object PlayerReadV2(RestRequestArgs args)
{ {
var ret = PlayerFind(parameters); var ret = PlayerFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
@ -603,39 +603,63 @@ namespace TShockAPI
}; };
} }
private object PlayerKickV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object PlayerReadV3(RestRequestArgs args)
{ {
var ret = PlayerFind(parameters); var ret = PlayerFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
TSPlayer player = (TSPlayer)ret; TSPlayer player = (TSPlayer)ret;
TShock.Utils.ForceKick(player, null == parameters["reason"] ? "Kicked via web" : parameters["reason"], false, true); var inventory = player.TPlayer.inventory.Where(p => p.active).ToList();
var equipment = player.TPlayer.armor.Where(p => p.active).ToList();
var dyes = player.TPlayer.dye.Where(p => p.active).ToList();
return new RestObject()
{
{"nickname", player.Name},
{"username", null == player.UserAccountName ? "" : player.UserAccountName},
{"ip", player.IP},
{"group", player.Group.Name},
{"position", player.TileX + "," + player.TileY},
{"inventory", string.Join(", ", inventory.Select(p => (p.name + ":" + p.stack)))},
{"armor", string.Join(", ", equipment.Select(p => (p.netID + ":" + p.prefix)))},
{"dyes", string.Join(", ", dyes.Select(p => (p.name)))},
{"buffs", string.Join(", ", player.TPlayer.buffType)}
};
}
private object PlayerKickV2(RestRequestArgs args)
{
var ret = PlayerFind(args.Parameters);
if (ret is RestObject)
return ret;
TSPlayer player = (TSPlayer)ret;
TShock.Utils.ForceKick(player, null == args.Parameters["reason"] ? "Kicked via web" : args.Parameters["reason"], false, true);
return RestResponse("Player " + player.Name + " was kicked"); return RestResponse("Player " + player.Name + " was kicked");
} }
private object PlayerBanV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object PlayerBanV2(RestRequestArgs args)
{ {
var ret = PlayerFind(parameters); var ret = PlayerFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
TSPlayer player = (TSPlayer)ret; TSPlayer player = (TSPlayer)ret;
var reason = null == parameters["reason"] ? "Banned via web" : parameters["reason"]; var reason = null == args.Parameters["reason"] ? "Banned via web" : args.Parameters["reason"];
TShock.Bans.AddBan(player.IP, player.Name, "", reason); TShock.Bans.AddBan(player.IP, player.Name, "", reason);
TShock.Utils.ForceKick(player, reason, false, true); TShock.Utils.ForceKick(player, reason, false, true);
return RestResponse("Player " + player.Name + " was banned"); return RestResponse("Player " + player.Name + " was banned");
} }
private object PlayerKill(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object PlayerKill(RestRequestArgs args)
{ {
var ret = PlayerFind(parameters); var ret = PlayerFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
TSPlayer player = (TSPlayer)ret; TSPlayer player = (TSPlayer)ret;
player.DamagePlayer(999999); player.DamagePlayer(999999);
var from = string.IsNullOrWhiteSpace(parameters["from"]) ? "Server Admin" : parameters["from"]; var from = string.IsNullOrWhiteSpace(args.Parameters["from"]) ? "Server Admin" : args.Parameters["from"];
player.SendMessage(string.Format("{0} just killed you!", from)); player.SendMessage(string.Format("{0} just killed you!", from));
return RestResponse("Player " + player.Name + " was killed"); return RestResponse("Player " + player.Name + " was killed");
} }
@ -644,7 +668,7 @@ namespace TShockAPI
#region RestGroupMethods #region RestGroupMethods
private object GroupList(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object GroupList(RestRequestArgs args)
{ {
var groups = new ArrayList(); var groups = new ArrayList();
foreach (Group group in TShock.Groups) foreach (Group group in TShock.Groups)
@ -654,9 +678,9 @@ namespace TShockAPI
return new RestObject() { { "groups", groups } }; return new RestObject() { { "groups", groups } };
} }
private object GroupInfo(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object GroupInfo(RestRequestArgs args)
{ {
var ret = GroupFind(parameters); var ret = GroupFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
@ -671,9 +695,9 @@ namespace TShockAPI
}; };
} }
private object GroupDestroy(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object GroupDestroy(RestRequestArgs args)
{ {
var ret = GroupFind(parameters); var ret = GroupFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
@ -690,14 +714,14 @@ namespace TShockAPI
return RestResponse("Group '" + group.Name + "' deleted successfully"); return RestResponse("Group '" + group.Name + "' deleted successfully");
} }
private object GroupCreate(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object GroupCreate(RestRequestArgs args)
{ {
var name = parameters["group"]; var name = args.Parameters["group"];
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
return RestMissingParam("group"); return RestMissingParam("group");
try try
{ {
TShock.Groups.AddGroup(name, parameters["parent"], parameters["permissions"], parameters["chatcolor"], true); TShock.Groups.AddGroup(name, args.Parameters["parent"], args.Parameters["permissions"], args.Parameters["chatcolor"], true);
} }
catch (Exception e) catch (Exception e)
{ {
@ -707,16 +731,16 @@ namespace TShockAPI
return RestResponse("Group '" + name + "' created successfully"); return RestResponse("Group '" + name + "' created successfully");
} }
private object GroupUpdate(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object GroupUpdate(RestRequestArgs args)
{ {
var ret = GroupFind(parameters); var ret = GroupFind(args.Parameters);
if (ret is RestObject) if (ret is RestObject)
return ret; return ret;
Group group = (Group)ret; Group group = (Group)ret;
var parent = (null == parameters["parent"]) ? group.ParentName : parameters["parent"]; var parent = (null == args.Parameters["parent"]) ? group.ParentName : args.Parameters["parent"];
var chatcolor = (null == parameters["chatcolor"]) ? string.Format("{0}.{1}.{2}", group.R, group.G, group.B) : parameters["chatcolor"]; var chatcolor = (null == args.Parameters["chatcolor"]) ? string.Format("{0}.{1}.{2}", group.R, group.G, group.B) : args.Parameters["chatcolor"];
var permissions = (null == parameters["permissions"]) ? group.Permissions : parameters["permissions"]; var permissions = (null == args.Parameters["permissions"]) ? group.Permissions : args.Parameters["permissions"];
try try
{ {
TShock.Groups.UpdateGroup(group.Name, parent, permissions, chatcolor, group.Suffix, group.Prefix); TShock.Groups.UpdateGroup(group.Name, parent, permissions, chatcolor, group.Suffix, group.Prefix);

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -84,9 +84,9 @@ namespace Rests
} }
} }
private object DestroyToken(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object DestroyToken(RestRequestArgs args)
{ {
var token = verbs["token"]; var token = args.Verbs["token"];
try try
{ {
Tokens.Remove(token); Tokens.Remove(token);
@ -100,7 +100,7 @@ namespace Rests
{ Response = "Requested token was successfully destroyed." }; { Response = "Requested token was successfully destroyed." };
} }
private object DestroyAllTokens(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData) private object DestroyAllTokens(RestRequestArgs args)
{ {
Tokens.Clear(); Tokens.Clear();
@ -108,18 +108,18 @@ namespace Rests
{ Response = "All tokens were successfully destroyed." }; { Response = "All tokens were successfully destroyed." };
} }
private object NewTokenV2(RestVerbs verbs, IParameterCollection parameters) private object NewTokenV2(RestRequestArgs args)
{ {
var user = parameters["username"]; var user = args.Parameters["username"];
var pass = verbs["password"]; var pass = args.Verbs["password"];
return this.NewTokenInternal(user, pass); return this.NewTokenInternal(user, pass);
} }
private object NewToken(RestVerbs verbs, IParameterCollection parameters) private object NewToken(RestRequestArgs args)
{ {
var user = verbs["username"]; var user = args.Verbs["username"];
var pass = verbs["password"]; var pass = args.Verbs["password"];
RestObject response = this.NewTokenInternal(user, pass); RestObject response = this.NewTokenInternal(user, pass);
response["deprecated"] = "This endpoint is depracted and will be removed in the future."; response["deprecated"] = "This endpoint is depracted and will be removed in the future.";
@ -157,10 +157,10 @@ namespace Rests
return response; return response;
} }
protected override object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms) protected override object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms, IRequest request)
{ {
if (!cmd.RequiresToken) if (!cmd.RequiresToken)
return base.ExecuteCommand(cmd, verbs, parms); return base.ExecuteCommand(cmd, verbs, parms, request);
var token = parms["token"]; var token = parms["token"];
if (token == null) if (token == null)
@ -191,7 +191,7 @@ namespace Rests
} }
} }
object result = secureCmd.Execute(verbs, parms, tokenData); object result = secureCmd.Execute(verbs, parms, tokenData, request);
if (cmd.DoLog && TShock.Config.LogRest) if (cmd.DoLog && TShock.Config.LogRest)
TShock.Utils.SendLogs(string.Format( TShock.Utils.SendLogs(string.Format(
"\"{0}\" requested REST endpoint: {1}", tokenData.Username, this.BuildRequestUri(cmd, verbs, parms, false)), "\"{0}\" requested REST endpoint: {1}", tokenData.Username, this.BuildRequestUri(cmd, verbs, parms, false)),

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -125,10 +125,10 @@ namespace TShockAPI
if (task.direct) if (task.direct)
{ {
OnSaveWorld(new WorldSaveEventArgs()); OnSaveWorld(new WorldSaveEventArgs());
WorldGen.realsaveWorld(task.resetTime); WorldFile.RealSaveWorld(task.resetTime);
} }
else else
WorldGen.saveWorld(task.resetTime); WorldFile.saveWorld(task.resetTime);
TShock.Utils.Broadcast("World saved.", Color.Yellow); TShock.Utils.Broadcast("World saved.", Color.Yellow);
Log.Info(string.Format("World saved at ({0})", Main.worldPathName)); Log.Info(string.Format("World saved at ({0})", Main.worldPathName));
} }

View file

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.IO;
using Newtonsoft.Json;
namespace TShockAPI.ServerSideCharacters
{
public class ServerSideConfig
{
[Description("Enable server side characters, This stops the client from saving character data! EXPERIMENTAL!!!!!")]
public bool Enabled;
[Description("How often SSC should save, in minutes.")]
public int ServerSideCharacterSave = 5;
[Description("Time, in milliseconds, to disallow discarding items after logging in when ServerSideInventory is ON.")]
public int LogonDiscardThreshold = 250;
[Description("The starting default health for new SSC.")]
public int StartingHealth = 100;
[Description("The starting default mana for new SSC.")]
public int StartingMana = 20;
[Description("The starting default inventory for new SSC.")]
public List<NetItem> StartingInventory = new List<NetItem>();
public static ServerSideConfig Read(string path)
{
using (var reader = new StreamReader(path))
{
string txt = reader.ReadToEnd();
var config = JsonConvert.DeserializeObject<ServerSideConfig>(txt);
return config;
}
}
public void Write(string path)
{
using (var writer = new StreamWriter(path))
{
writer.Write(JsonConvert.SerializeObject(this, Formatting.Indented));
}
}
}
}

View file

@ -6,6 +6,7 @@ using System.Net;
using System.Threading; using System.Threading;
using System.IO; using System.IO;
using System.Web; using System.Web;
using TerrariaApi.Server;
namespace TShockAPI namespace TShockAPI
{ {
@ -27,21 +28,6 @@ namespace TShockAPI
} }
} }
private HttpWebResponse GetResponseNoException(HttpWebRequest req)
{
try
{
return (HttpWebResponse)req.GetResponse();
}
catch (WebException we)
{
var resp = we.Response as HttpWebResponse;
if (resp == null)
throw;
return resp;
}
}
private void SendUpdate(object info) private void SendUpdate(object info)
{ {
Thread.Sleep(1000*60*15); Thread.Sleep(1000*60*15);
@ -54,7 +40,7 @@ namespace TShockAPI
systemCPUClock = 0, systemCPUClock = 0,
version = TShock.VersionNum.ToString(), version = TShock.VersionNum.ToString(),
terrariaVersion = Terraria.Main.versionNumber2, terrariaVersion = Terraria.Main.versionNumber2,
mono = Terraria.Main.runningMono mono = ServerApi.RunningMono
}; };
var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(data); var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(data);
@ -64,7 +50,7 @@ namespace TShockAPI
client.Timeout = 5000; client.Timeout = 5000;
try try
{ {
using (var resp = GetResponseNoException(client)) using (var resp = TShock.Utils.GetResponseNoException(client))
{ {
if (resp.StatusCode != HttpStatusCode.OK) if (resp.StatusCode != HttpStatusCode.OK)
{ {

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -40,11 +40,6 @@ namespace TShockAPI
/// </summary> /// </summary>
public static readonly TSPlayer All = new TSPlayer("All"); public static readonly TSPlayer All = new TSPlayer("All");
/// <summary>
/// Gets whether the player is using Raptor.
/// </summary>
public bool IsRaptor { get; internal set; }
/// <summary> /// <summary>
/// The amount of tiles that the player has killed in the last second. /// The amount of tiles that the player has killed in the last second.
/// </summary> /// </summary>
@ -75,16 +70,19 @@ namespace TShockAPI
/// </summary> /// </summary>
public int RecentFuse = 0; public int RecentFuse = 0;
/// <summary>
/// Whether to ignore packets that are SSC-relevant.
/// </summary>
public bool IgnoreSSCPackets { get; set; }
/// <summary> /// <summary>
/// A system to delay Remembered Position Teleports a few seconds /// A system to delay Remembered Position Teleports a few seconds
/// </summary> /// </summary>
public int RPPending = 0; public int RPPending = 0;
public int sX = -1; public int sX = -1;
public int sY = -1; public int sY = -1;
/// <summary> /// <summary>
/// A queue of tiles destroyed by the player for reverting. /// A queue of tiles destroyed by the player for reverting.
/// </summary> /// </summary>
@ -95,10 +93,6 @@ namespace TShockAPI
/// </summary> /// </summary>
public Dictionary<Vector2, Tile> TilesCreated { get; protected set; } public Dictionary<Vector2, Tile> TilesCreated { get; protected set; }
public int FirstMaxHP { get; set; }
public int FirstMaxMP { get; set; }
/// <summary> /// <summary>
/// The player's group. /// The player's group.
/// </summary> /// </summary>
@ -220,9 +214,9 @@ namespace TShockAPI
public bool RequestedSection; public bool RequestedSection;
/// <summary> /// <summary>
/// The last time the player died. /// The player's respawn timer.
/// </summary> /// </summary>
public DateTime LastDeath { get; set; } public int RespawnTimer;
/// <summary> /// <summary>
/// Whether the player is dead or not. /// Whether the player is dead or not.
@ -369,13 +363,22 @@ namespace TShockAPI
} }
} }
public IEnumerable<Item> Accessories
{
get
{
for (int i = 3; i < 8; i++)
yield return TPlayer.armor[i];
}
}
/// <summary> /// <summary>
/// Saves the player's inventory to SSI /// Saves the player's inventory to SSI
/// </summary> /// </summary>
/// <returns>bool - True/false if it saved successfully</returns> /// <returns>bool - True/false if it saved successfully</returns>
public bool SaveServerCharacter() public bool SaveServerCharacter()
{ {
if (!TShock.Config.ServerSideCharacter) if (!Main.ServerSideCharacter)
{ {
return false; return false;
} }
@ -398,7 +401,7 @@ namespace TShockAPI
/// <returns>bool - True/false if it saved successfully</returns> /// <returns>bool - True/false if it saved successfully</returns>
public bool SendServerCharacter() public bool SendServerCharacter()
{ {
if (!TShock.Config.ServerSideCharacter) if (!Main.ServerSideCharacter)
{ {
return false; return false;
} }
@ -525,15 +528,16 @@ namespace TShockAPI
DayTime = Main.dayTime, DayTime = Main.dayTime,
MoonPhase = (byte)Main.moonPhase, MoonPhase = (byte)Main.moonPhase,
BloodMoon = Main.bloodMoon, BloodMoon = Main.bloodMoon,
MaxTilesX = Main.maxTilesX, Eclipse = Main.eclipse,
MaxTilesY = Main.maxTilesY, MaxTilesX = (short)Main.maxTilesX,
SpawnX = tilex, MaxTilesY = (short)Main.maxTilesY,
SpawnY = tiley, SpawnX = (short)Main.spawnTileX,
WorldSurface = (int) Main.worldSurface, SpawnY = (short)Main.spawnTileY,
RockLayer = (int) Main.rockLayer, WorldSurface = (short)Main.worldSurface,
RockLayer = (short)Main.rockLayer,
//Sending a fake world id causes the client to not be able to find a stored spawnx/y. //Sending a fake world id causes the client to not be able to find a stored spawnx/y.
//This fixes the bed spawn point bug. With a fake world id it wont be able to find the bed spawn. //This fixes the bed spawn point bug. With a fake world id it wont be able to find the bed spawn.
WorldID = !fakeid ? Main.worldID : -1, WorldID = Main.worldID,
MoonType = (byte)Main.moonType, MoonType = (byte)Main.moonType,
TreeX0 = Main.treeX[0], TreeX0 = Main.treeX[0],
TreeX1 = Main.treeX[1], TreeX1 = Main.treeX[1],
@ -568,14 +572,16 @@ namespace TShockAPI
(NPC.downedBoss3 ? BossFlags.DownedBoss3 : BossFlags.None) | (NPC.downedBoss3 ? BossFlags.DownedBoss3 : BossFlags.None) |
(Main.hardMode ? BossFlags.HardMode : BossFlags.None) | (Main.hardMode ? BossFlags.HardMode : BossFlags.None) |
(NPC.downedClown ? BossFlags.DownedClown : BossFlags.None) | (NPC.downedClown ? BossFlags.DownedClown : BossFlags.None) |
(Main.ServerSideCharacter ? BossFlags.ServerSideCharacter : BossFlags.None), (Main.ServerSideCharacter ? BossFlags.ServerSideCharacter : BossFlags.None) |
(NPC.downedPlantBoss ? BossFlags.DownedPlantBoss : BossFlags.None),
BossFlags2 = (NPC.downedMechBoss1 ? BossFlags2.DownedMechBoss1 : BossFlags2.None) | BossFlags2 = (NPC.downedMechBoss1 ? BossFlags2.DownedMechBoss1 : BossFlags2.None) |
(NPC.downedMechBoss2 ? BossFlags2.DownedMechBoss2 : BossFlags2.None) | (NPC.downedMechBoss2 ? BossFlags2.DownedMechBoss2 : BossFlags2.None) |
(NPC.downedMechBoss3 ? BossFlags2.DownedMechBoss3 : BossFlags2.None) | (NPC.downedMechBoss3 ? BossFlags2.DownedMechBoss3 : BossFlags2.None) |
(NPC.downedMechBossAny ? BossFlags2.DownedMechBossAny : BossFlags2.None) | (NPC.downedMechBossAny ? BossFlags2.DownedMechBossAny : BossFlags2.None) |
(Main.cloudBGActive == 1f ? BossFlags2.CloudBg : BossFlags2.None) | (Main.cloudBGActive == 1f ? BossFlags2.CloudBg : BossFlags2.None) |
(WorldGen.crimson ? BossFlags2.Crimson : BossFlags2.None) | (WorldGen.crimson ? BossFlags2.Crimson : BossFlags2.None) |
(Main.pumpkinMoon ? BossFlags2.Pumpkin : BossFlags2.None), (Main.pumpkinMoon ? BossFlags2.PumpkinMoon : BossFlags2.None) |
(Main.snowMoon ? BossFlags2.SnowMoon : BossFlags2.None),
Rain = Main.maxRaining, Rain = Main.maxRaining,
WorldName = TShock.Config.UseServerName ? TShock.Config.ServerName : Main.worldName WorldName = TShock.Config.UseServerName ? TShock.Config.ServerName : Main.worldName
}; };
@ -609,7 +615,7 @@ namespace TShockAPI
return true; return true;
} }
public void Heal(int health = 500) public void Heal(int health = 600)
{ {
NetMessage.SendData((int)PacketTypes.PlayerHealOther, -1, -1, "", this.TPlayer.whoAmi, health); NetMessage.SendData((int)PacketTypes.PlayerHealOther, -1, -1, "", this.TPlayer.whoAmi, health);
} }
@ -634,8 +640,8 @@ namespace TShockAPI
var msg = new SpawnMsg var msg = new SpawnMsg
{ {
PlayerIndex = (byte) Index, PlayerIndex = (byte) Index,
TileX = tilex, TileX = (short)tilex,
TileY = tiley TileY = (short)tiley
}; };
msg.PackFull(ms); msg.PackFull(ms);
SendRawData(ms.ToArray()); SendRawData(ms.ToArray());
@ -809,6 +815,7 @@ namespace TShockAPI
private DateTime LastDisableNotification = DateTime.UtcNow; private DateTime LastDisableNotification = DateTime.UtcNow;
public int ActiveChest = -1; public int ActiveChest = -1;
public Item ItemInHand = new Item();
public virtual void Disable(string reason = "", bool displayConsole = true) public virtual void Disable(string reason = "", bool displayConsole = true)
{ {
@ -884,183 +891,11 @@ namespace TShockAPI
NetMessage.SendData((int) msgType, Index, -1, text, ply, number2, number3, number4, number5); NetMessage.SendData((int) msgType, Index, -1, text, ply, number2, number3, number4, number5);
} }
public virtual bool SendRawData(byte[] data) public virtual void SendRawData(byte[] data)
{ {
if (!RealPlayer || !ConnectionAlive) if (!RealPlayer || !ConnectionAlive)
return false;
return TShock.SendBytes(Netplay.serverSock[Index], data);
}
/// <summary>
/// Sends Raptor permissions to the player.
/// </summary>
public void SendRaptorPermissions()
{
if (!IsRaptor)
return; return;
NetMessage.SendBytes(Netplay.serverSock[Index], data, 0, data.Length, Netplay.serverSock[Index].ServerWriteCallBack, Netplay.serverSock[Index].networkStream);
lock (NetMessage.buffer[Index].writeBuffer)
{
int length = 0;
using (var ms = new MemoryStream(NetMessage.buffer[Index].writeBuffer, true))
{
using (var writer = new BinaryWriter(ms))
{
writer.BaseStream.Position = 4;
writer.Write((byte)PacketTypes.Placeholder);
writer.Write((byte)RaptorPacketTypes.Permissions);
writer.Write(String.Join(",", Group.TotalPermissions.ToArray()));
length = (int)writer.BaseStream.Position;
writer.BaseStream.Position = 0;
writer.Write(length - 4);
}
}
TShock.PacketBuffer.SendBytes(Netplay.serverSock[Index], NetMessage.buffer[Index].writeBuffer, 0, length);
}
}
/// <summary>
/// Sends a region to the player.
/// <param name="region">The region.</param>
/// </summary>
public void SendRaptorRegion(Region region)
{
if (!IsRaptor)
return;
lock (NetMessage.buffer[Index].writeBuffer)
{
int length = 0;
using (var ms = new MemoryStream(NetMessage.buffer[Index].writeBuffer, true))
{
using (var writer = new BinaryWriter(ms))
{
writer.BaseStream.Position = 4;
writer.Write((byte)PacketTypes.Placeholder);
writer.Write((byte)RaptorPacketTypes.Region);
writer.Write(region.Area.X);
writer.Write(region.Area.Y);
writer.Write(region.Area.Width);
writer.Write(region.Area.Height);
writer.Write(region.Name);
length = (int)writer.BaseStream.Position;
writer.BaseStream.Position = 0;
writer.Write(length - 4);
}
}
TShock.PacketBuffer.SendBytes(Netplay.serverSock[Index], NetMessage.buffer[Index].writeBuffer, 0, length);
}
}
/// <summary>
/// Sends a region deletion to the player.
/// <param name="regionName">The region name.</param>
/// </summary>
public void SendRaptorRegionDeletion(string regionName)
{
if (!IsRaptor)
return;
lock (NetMessage.buffer[Index].writeBuffer)
{
int length = 0;
using (var ms = new MemoryStream(NetMessage.buffer[Index].writeBuffer, true))
{
using (var writer = new BinaryWriter(ms))
{
writer.BaseStream.Position = 4;
writer.Write((byte)PacketTypes.Placeholder);
writer.Write((byte)RaptorPacketTypes.RegionDelete);
writer.Write(regionName);
length = (int)writer.BaseStream.Position;
writer.BaseStream.Position = 0;
writer.Write(length - 4);
}
}
TShock.PacketBuffer.SendBytes(Netplay.serverSock[Index], NetMessage.buffer[Index].writeBuffer, 0, length);
}
}
/// <summary>
/// Sends a warp to the player.
/// <param name="warp">The warp.</param>
/// </summary>
public void SendRaptorWarp(Warp warp)
{
if (!IsRaptor)
return;
lock (NetMessage.buffer[Index].writeBuffer)
{
int length = 0;
using (var ms = new MemoryStream(NetMessage.buffer[Index].writeBuffer, true))
{
using (var writer = new BinaryWriter(ms))
{
writer.BaseStream.Position = 4;
writer.Write((byte)PacketTypes.Placeholder);
writer.Write((byte)RaptorPacketTypes.Warp);
writer.Write(warp.Position.X);
writer.Write(warp.Position.Y);
writer.Write(warp.Name);
length = (int)writer.BaseStream.Position;
writer.BaseStream.Position = 0;
writer.Write(length - 4);
}
}
TShock.PacketBuffer.SendBytes(Netplay.serverSock[Index], NetMessage.buffer[Index].writeBuffer, 0, length);
}
}
/// <summary>
/// Sends a warp deletion to the player.
/// <param name="warpName">The warp name.</param>
/// </summary>
public void SendRaptorWarpDeletion(string warpName)
{
if (!IsRaptor)
return;
lock (NetMessage.buffer[Index].writeBuffer)
{
int length = 0;
using (var ms = new MemoryStream(NetMessage.buffer[Index].writeBuffer, true))
{
using (var writer = new BinaryWriter(ms))
{
writer.BaseStream.Position = 4;
writer.Write((byte)PacketTypes.Placeholder);
writer.Write((byte)RaptorPacketTypes.WarpDelete);
writer.Write(warpName);
length = (int)writer.BaseStream.Position;
writer.BaseStream.Position = 0;
writer.Write(length - 4);
}
}
TShock.PacketBuffer.SendBytes(Netplay.serverSock[Index], NetMessage.buffer[Index].writeBuffer, 0, length);
}
} }
/// <summary> /// <summary>
@ -1184,42 +1019,70 @@ namespace TShockAPI
//RconHandler.Response += msg + "\n"; //RconHandler.Response += msg + "\n";
} }
public void SetFullMoon(bool fullmoon) public void SetFullMoon()
{ {
Main.dayTime = false;
Main.moonPhase = 0; Main.moonPhase = 0;
SetTime(false, 0); Main.time = 0.0;
TSPlayer.All.SendData(PacketTypes.WorldInfo);
} }
public void SetBloodMoon(bool bloodMoon) public void SetBloodMoon(bool bloodMoon)
{ {
Main.bloodMoon = bloodMoon; if (bloodMoon)
SetTime(false, 0); {
Main.dayTime = false;
Main.bloodMoon = true;
Main.time = 0.0;
}
else
Main.bloodMoon = false;
TSPlayer.All.SendData(PacketTypes.WorldInfo);
} }
public void SetSnowMoon(bool snowMoon) public void SetFrostMoon(bool snowMoon)
{ {
Main.snowMoon = snowMoon; if (snowMoon)
SetTime(false, 0); {
Main.dayTime = false;
Main.snowMoon = true;
Main.time = 0.0;
}
else
Main.snowMoon = false;
TSPlayer.All.SendData(PacketTypes.WorldInfo);
} }
public void SetPumpkinMoon(bool pumpkinMoon) public void SetPumpkinMoon(bool pumpkinMoon)
{ {
Main.pumpkinMoon = pumpkinMoon; if (pumpkinMoon)
SetTime(false, 0); {
Main.dayTime = false;
Main.pumpkinMoon = true;
Main.time = 0.0;
}
else
Main.pumpkinMoon = false;
TSPlayer.All.SendData(PacketTypes.WorldInfo);
} }
public void SetEclipse(bool Eclipse) public void SetEclipse(bool eclipse)
{ {
Main.eclipse = Eclipse; if (eclipse)
SetTime(true, 150); {
Main.dayTime = Main.eclipse = true;
Main.time = 0.0;
}
else
Main.eclipse = false;
TSPlayer.All.SendData(PacketTypes.WorldInfo);
} }
public void SetTime(bool dayTime, double time) public void SetTime(bool dayTime, double time)
{ {
Main.dayTime = dayTime; Main.dayTime = dayTime;
Main.time = time; Main.time = time;
NetMessage.SendData((int) PacketTypes.TimeSet, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); TSPlayer.All.SendData(PacketTypes.TimeSet, "", 0, 0, Main.sunModY, Main.moonModY);
NetMessage.syncPlayers();
} }
public void SpawnNPC(int type, string name, int amount, int startTileX, int startTileY, int tileXRange = 100, public void SpawnNPC(int type, string name, int amount, int startTileX, int startTileY, int tileXRange = 100,
@ -1265,14 +1128,24 @@ namespace TShockAPI
public class PlayerData public class PlayerData
{ {
public NetItem[] inventory = new NetItem[NetItem.maxNetInventory]; public NetItem[] inventory = new NetItem[NetItem.maxNetInventory];
public int health = 100; public int health = TShock.ServerSideCharacterConfig.StartingHealth;
public int maxHealth = 100; public int maxHealth = TShock.ServerSideCharacterConfig.StartingHealth;
public int mana = 20; public int mana = TShock.ServerSideCharacterConfig.StartingMana;
public int maxMana = 20; public int maxMana = TShock.ServerSideCharacterConfig.StartingMana;
public bool exists; public bool exists;
public int spawnX= -1; public int spawnX= -1;
public int spawnY= -1; public int spawnY= -1;
public int? hair;
public byte hairDye;
public Color? hairColor;
public Color? pantsColor;
public Color? shirtColor;
public Color? underShirtColor;
public Color? shoeColor;
public Color? skinColor;
public Color? eyeColor;
public BitsByte? hideVisuals;
public int questsCompleted;
public PlayerData(TSPlayer player) public PlayerData(TSPlayer player)
{ {
@ -1293,6 +1166,11 @@ namespace TShockAPI
if (player.TPlayer.inventory[2] != null && player.TPlayer.inventory[2].netID == -16) if (player.TPlayer.inventory[2] != null && player.TPlayer.inventory[2].netID == -16)
this.inventory[2].prefix = player.TPlayer.inventory[2].prefix; this.inventory[2].prefix = player.TPlayer.inventory[2].prefix;
for (int i = 0; i < TShock.ServerSideCharacterConfig.StartingInventory.Count; i++)
{
var item = TShock.ServerSideCharacterConfig.StartingInventory[i];
StoreSlot(i, item.netID, item.prefix, item.stack);
}
} }
public void StoreSlot(int slot, int netID, int prefix, int stack) public void StoreSlot(int slot, int netID, int prefix, int stack)
@ -1331,6 +1209,18 @@ namespace TShockAPI
this.spawnX = player.TPlayer.SpawnX; this.spawnX = player.TPlayer.SpawnX;
this.spawnY = player.TPlayer.SpawnY; this.spawnY = player.TPlayer.SpawnY;
} }
this.hair = player.TPlayer.hair;
this.hairDye = player.TPlayer.hairDye;
this.hairColor = player.TPlayer.hairColor;
this.pantsColor = player.TPlayer.pantsColor;
this.shirtColor = player.TPlayer.shirtColor;
this.underShirtColor = player.TPlayer.underShirtColor;
this.shoeColor = player.TPlayer.shoeColor;
this.hideVisuals = player.TPlayer.hideVisual;
this.skinColor = player.TPlayer.skinColor;
this.eyeColor = player.TPlayer.eyeColor;
this.questsCompleted = player.TPlayer.anglerQuestsFinished;
Item[] inventory = player.TPlayer.inventory; Item[] inventory = player.TPlayer.inventory;
Item[] armor = player.TPlayer.armor; Item[] armor = player.TPlayer.armor;
Item[] dye = player.TPlayer.dye; Item[] dye = player.TPlayer.dye;
@ -1409,6 +1299,9 @@ namespace TShockAPI
public void RestoreCharacter(TSPlayer player) public void RestoreCharacter(TSPlayer player)
{ {
// Start ignoring SSC-related packets! This is critical so that we don't send or receive dirty data!
player.IgnoreSSCPackets = true;
player.TPlayer.statLife = this.health; player.TPlayer.statLife = this.health;
player.TPlayer.statLifeMax = this.maxHealth; player.TPlayer.statLifeMax = this.maxHealth;
player.TPlayer.statMana = this.maxMana; player.TPlayer.statMana = this.maxMana;
@ -1417,6 +1310,30 @@ namespace TShockAPI
player.TPlayer.SpawnY = this.spawnY; player.TPlayer.SpawnY = this.spawnY;
player.sX = this.spawnX; player.sX = this.spawnX;
player.sY = this.spawnY; player.sY = this.spawnY;
player.TPlayer.hairDye = this.hairDye;
player.TPlayer.anglerQuestsFinished = this.questsCompleted;
if (this.hair != null)
player.TPlayer.hair = this.hair.Value;
if (this.hairColor != null)
player.TPlayer.hairColor = this.hairColor.Value;
if (this.pantsColor != null)
player.TPlayer.pantsColor = this.pantsColor.Value;
if (this.shirtColor != null)
player.TPlayer.shirtColor = this.shirtColor.Value;
if (this.underShirtColor != null)
player.TPlayer.underShirtColor = this.underShirtColor.Value;
if (this.shoeColor != null)
player.TPlayer.shoeColor = this.shoeColor.Value;
if (this.skinColor != null)
player.TPlayer.skinColor = this.skinColor.Value;
if (this.eyeColor != null)
player.TPlayer.eyeColor = this.eyeColor.Value;
if (this.hideVisuals != null)
player.TPlayer.hideVisual = this.hideVisuals.Value;
else
player.TPlayer.hideVisual.ClearAll();
for (int i = 0; i < NetItem.maxNetInventory; i++) for (int i = 0; i < NetItem.maxNetInventory; i++)
{ {
@ -1490,9 +1407,19 @@ namespace TShockAPI
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[8].name, player.Index, 67f, (float)Main.player[player.Index].armor[8].prefix, 0f, 0); NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[8].name, player.Index, 67f, (float)Main.player[player.Index].armor[8].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[9].name, player.Index, 68f, (float)Main.player[player.Index].armor[9].prefix, 0f, 0); NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[9].name, player.Index, 68f, (float)Main.player[player.Index].armor[9].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[10].name, player.Index, 69f, (float)Main.player[player.Index].armor[10].prefix, 0f, 0); NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[10].name, player.Index, 69f, (float)Main.player[player.Index].armor[10].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[0].name, player.Index, 70f, (float)Main.player[player.Index].dye[0].prefix, 0f, 0); NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[11].name, player.Index, 70f, (float)Main.player[player.Index].armor[11].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[1].name, player.Index, 71f, (float)Main.player[player.Index].dye[1].prefix, 0f, 0); NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[12].name, player.Index, 71f, (float)Main.player[player.Index].armor[12].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[2].name, player.Index, 72f, (float)Main.player[player.Index].dye[2].prefix, 0f, 0); NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[13].name, player.Index, 72f, (float)Main.player[player.Index].armor[13].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[14].name, player.Index, 73f, (float)Main.player[player.Index].armor[14].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[15].name, player.Index, 74f, (float)Main.player[player.Index].armor[15].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[0].name, player.Index, 75f, (float)Main.player[player.Index].dye[0].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[1].name, player.Index, 76f, (float)Main.player[player.Index].dye[1].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[2].name, player.Index, 77f, (float)Main.player[player.Index].dye[2].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[3].name, player.Index, 78f, (float)Main.player[player.Index].dye[3].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[4].name, player.Index, 79f, (float)Main.player[player.Index].dye[4].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[5].name, player.Index, 80f, (float)Main.player[player.Index].dye[5].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[6].name, player.Index, 81f, (float)Main.player[player.Index].dye[6].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[7].name, player.Index, 82f, (float)Main.player[player.Index].dye[7].prefix, 0f, 0);
NetMessage.SendData(4, -1, -1, player.Name, player.Index, 0f, 0f, 0f, 0); NetMessage.SendData(4, -1, -1, player.Name, player.Index, 0f, 0f, 0f, 0);
NetMessage.SendData(42, -1, -1, "", player.Index, 0f, 0f, 0f, 0); NetMessage.SendData(42, -1, -1, "", player.Index, 0f, 0f, 0f, 0);
NetMessage.SendData(16, -1, -1, "", player.Index, 0f, 0f, 0f, 0); NetMessage.SendData(16, -1, -1, "", player.Index, 0f, 0f, 0f, 0);
@ -1512,50 +1439,56 @@ namespace TShockAPI
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[8].name, player.Index, 67f, (float)Main.player[player.Index].armor[8].prefix, 0f, 0); NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[8].name, player.Index, 67f, (float)Main.player[player.Index].armor[8].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[9].name, player.Index, 68f, (float)Main.player[player.Index].armor[9].prefix, 0f, 0); NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[9].name, player.Index, 68f, (float)Main.player[player.Index].armor[9].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[10].name, player.Index, 69f, (float)Main.player[player.Index].armor[10].prefix, 0f, 0); NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[10].name, player.Index, 69f, (float)Main.player[player.Index].armor[10].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[0].name, player.Index, 70f, (float)Main.player[player.Index].dye[0].prefix, 0f, 0); NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[11].name, player.Index, 70f, (float)Main.player[player.Index].armor[11].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[1].name, player.Index, 71f, (float)Main.player[player.Index].dye[1].prefix, 0f, 0); NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[12].name, player.Index, 71f, (float)Main.player[player.Index].armor[12].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[2].name, player.Index, 72f, (float)Main.player[player.Index].dye[2].prefix, 0f, 0); NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[13].name, player.Index, 72f, (float)Main.player[player.Index].armor[13].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[14].name, player.Index, 73f, (float)Main.player[player.Index].armor[14].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[15].name, player.Index, 74f, (float)Main.player[player.Index].armor[15].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[0].name, player.Index, 75f, (float)Main.player[player.Index].dye[0].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[1].name, player.Index, 76f, (float)Main.player[player.Index].dye[1].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[2].name, player.Index, 77f, (float)Main.player[player.Index].dye[2].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[3].name, player.Index, 78f, (float)Main.player[player.Index].dye[3].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[4].name, player.Index, 79f, (float)Main.player[player.Index].dye[4].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[5].name, player.Index, 80f, (float)Main.player[player.Index].dye[5].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[6].name, player.Index, 81f, (float)Main.player[player.Index].dye[6].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[7].name, player.Index, 82f, (float)Main.player[player.Index].dye[7].prefix, 0f, 0);
NetMessage.SendData(4, player.Index, -1, player.Name, player.Index, 0f, 0f, 0f, 0); NetMessage.SendData(4, player.Index, -1, player.Name, player.Index, 0f, 0f, 0f, 0);
NetMessage.SendData(42, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0); NetMessage.SendData(42, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0);
NetMessage.SendData(16, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0); NetMessage.SendData(16, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0);
for (int k = 0; k < 10; k++) for (int k = 0; k < 22; k++)
{ {
player.TPlayer.buffType[k] = 0; player.TPlayer.buffType[k] = 0;
} }
NetMessage.SendData(50, -1, -1, "", player.Index, 0f, 0f, 0f, 0); NetMessage.SendData(50, -1, -1, "", player.Index, 0f, 0f, 0f, 0);
NetMessage.SendData(50, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0); NetMessage.SendData(50, player.Index, -1, "", player.Index, 0f, 0f, 0f, 0);
NetMessage.SendData(76, -1, -1, "", player.Index);
NetMessage.SendData(39, player.Index, -1, "", 400);
} }
} }
public class NetItem public class NetItem
{ {
public static readonly int maxNetInventory = 73; public static readonly int maxNetInventory = 83;
public static readonly int armorSlots = 11; public static readonly int armorSlots = 16;
public static readonly int dyeSlots = 3; public static readonly int dyeSlots = 8;
public int netID; public int netID;
public int stack; public int stack;
public int prefix; public int prefix;
public static string ToString(NetItem[] inventory) public static string ToString(NetItem[] inventory)
{ {
string inventoryString = ""; StringBuilder items = new StringBuilder();
for (int i = 0; i < maxNetInventory; i++) for (int i = 0; i < maxNetInventory; i++)
{ {
if (i != 0) items.Append(inventory[i].netID).Append(",");
inventoryString += "~";
inventoryString += inventory[i].netID;
if (inventory[i].netID != 0) if (inventory[i].netID != 0)
{ items.Append(inventory[i].stack).Append(",").Append(inventory[i].prefix).Append("~");
inventoryString += "," + inventory[i].stack;
inventoryString += "," + inventory[i].prefix;
}
else else
{ items.Append("0,0~");
inventoryString += ",0,0";
} }
} return items.ToString(0, items.Length - 1);
return inventoryString;
} }
public static NetItem[] Parse(string data) public static NetItem[] Parse(string data)

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -38,10 +38,11 @@ using TShockAPI.DB;
using TShockAPI.Net; using TShockAPI.Net;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using TShockAPI.ServerSideCharacters;
namespace TShockAPI namespace TShockAPI
{ {
[ApiVersion(1, 14)] [ApiVersion(1, 16)]
public class TShock : TerrariaPlugin public class TShock : TerrariaPlugin
{ {
public static readonly Version VersionNum = Assembly.GetExecutingAssembly().GetName().Version; public static readonly Version VersionNum = Assembly.GetExecutingAssembly().GetName().Version;
@ -62,9 +63,12 @@ namespace TShockAPI
public static GroupManager Groups; public static GroupManager Groups;
public static UserManager Users; public static UserManager Users;
public static ItemManager Itembans; public static ItemManager Itembans;
public static ProjectileManagager ProjectileBans;
public static TileManager TileBans;
public static RememberedPosManager RememberedPos; public static RememberedPosManager RememberedPos;
public static CharacterManager CharacterDB; public static CharacterManager CharacterDB;
public static ConfigFile Config { get; set; } public static ConfigFile Config { get; set; }
public static ServerSideConfig ServerSideCharacterConfig;
public static IDbConnection DB; public static IDbConnection DB;
public static bool OverridePort; public static bool OverridePort;
public static PacketBufferer PacketBuffer; public static PacketBufferer PacketBuffer;
@ -72,7 +76,7 @@ namespace TShockAPI
public static SecureRest RestApi; public static SecureRest RestApi;
public static RestManager RestManager; public static RestManager RestManager;
public static Utils Utils = Utils.Instance; public static Utils Utils = Utils.Instance;
public static StatTracker StatTracker = new StatTracker(); public static UpdateManager UpdateManager;
/// <summary> /// <summary>
/// Used for implementing REST Tokens prior to the REST system starting up. /// Used for implementing REST Tokens prior to the REST system starting up.
/// </summary> /// </summary>
@ -111,6 +115,10 @@ namespace TShockAPI
: base(game) : base(game)
{ {
Config = new ConfigFile(); Config = new ConfigFile();
ServerSideCharacterConfig = new ServerSideConfig();
ServerSideCharacterConfig.StartingInventory.Add(new NetItem { netID = -15, prefix = 0, stack = 1 });
ServerSideCharacterConfig.StartingInventory.Add(new NetItem { netID = -13, prefix = 0, stack = 1 });
ServerSideCharacterConfig.StartingInventory.Add(new NetItem { netID = -16, prefix = 0, stack = 1 });
Order = 0; Order = 0;
} }
@ -131,7 +139,7 @@ namespace TShockAPI
ConfigFile.ConfigRead += OnConfigRead; ConfigFile.ConfigRead += OnConfigRead;
FileTools.SetupConfig(); FileTools.SetupConfig();
Main.ServerSideCharacter = Config.ServerSideCharacter; //FYI, This cannot be disabled once flipped. Main.ServerSideCharacter = ServerSideCharacterConfig.Enabled;
DateTime now = DateTime.Now; DateTime now = DateTime.Now;
string logFilename; string logFilename;
@ -223,6 +231,8 @@ namespace TShockAPI
Users = new UserManager(DB); Users = new UserManager(DB);
Groups = new GroupManager(DB); Groups = new GroupManager(DB);
Itembans = new ItemManager(DB); Itembans = new ItemManager(DB);
ProjectileBans = new ProjectileManagager(DB);
TileBans = new TileManager(DB);
RememberedPos = new RememberedPosManager(DB); RememberedPos = new RememberedPosManager(DB);
CharacterDB = new CharacterManager(DB); CharacterDB = new CharacterManager(DB);
RestApi = new SecureRest(Netplay.serverListenIP, Config.RestApiPort); RestApi = new SecureRest(Netplay.serverListenIP, Config.RestApiPort);
@ -249,7 +259,6 @@ namespace TShockAPI
ServerApi.Hooks.NetSendData.Register(this, NetHooks_SendData); ServerApi.Hooks.NetSendData.Register(this, NetHooks_SendData);
ServerApi.Hooks.NetGreetPlayer.Register(this, OnGreetPlayer); ServerApi.Hooks.NetGreetPlayer.Register(this, OnGreetPlayer);
ServerApi.Hooks.NpcStrike.Register(this, NpcHooks_OnStrikeNpc); ServerApi.Hooks.NpcStrike.Register(this, NpcHooks_OnStrikeNpc);
ServerApi.Hooks.NpcSetDefaultsInt.Register(this, OnNpcSetDefaults);
ServerApi.Hooks.ProjectileSetDefaults.Register(this, OnProjectileSetDefaults); ServerApi.Hooks.ProjectileSetDefaults.Register(this, OnProjectileSetDefaults);
ServerApi.Hooks.WorldStartHardMode.Register(this, OnStartHardMode); ServerApi.Hooks.WorldStartHardMode.Register(this, OnStartHardMode);
ServerApi.Hooks.WorldSave.Register(this, SaveManager.Instance.OnSaveWorld); ServerApi.Hooks.WorldSave.Register(this, SaveManager.Instance.OnSaveWorld);
@ -327,7 +336,6 @@ namespace TShockAPI
ServerApi.Hooks.NetSendData.Deregister(this, NetHooks_SendData); ServerApi.Hooks.NetSendData.Deregister(this, NetHooks_SendData);
ServerApi.Hooks.NetGreetPlayer.Deregister(this, OnGreetPlayer); ServerApi.Hooks.NetGreetPlayer.Deregister(this, OnGreetPlayer);
ServerApi.Hooks.NpcStrike.Deregister(this, NpcHooks_OnStrikeNpc); ServerApi.Hooks.NpcStrike.Deregister(this, NpcHooks_OnStrikeNpc);
ServerApi.Hooks.NpcSetDefaultsInt.Deregister(this, OnNpcSetDefaults);
ServerApi.Hooks.ProjectileSetDefaults.Deregister(this, OnProjectileSetDefaults); ServerApi.Hooks.ProjectileSetDefaults.Deregister(this, OnProjectileSetDefaults);
ServerApi.Hooks.WorldStartHardMode.Deregister(this, OnStartHardMode); ServerApi.Hooks.WorldStartHardMode.Deregister(this, OnStartHardMode);
ServerApi.Hooks.WorldSave.Deregister(this, SaveManager.Instance.OnSaveWorld); ServerApi.Hooks.WorldSave.Deregister(this, SaveManager.Instance.OnSaveWorld);
@ -349,24 +357,6 @@ namespace TShockAPI
private void OnPlayerLogin(Hooks.PlayerPostLoginEventArgs args) private void OnPlayerLogin(Hooks.PlayerPostLoginEventArgs args)
{ {
if (args.Player.IsRaptor)
{
Task.Factory.StartNew(() =>
{
args.Player.SendRaptorPermissions();
if (args.Player.Group.HasPermission(Permissions.manageregion))
{
for (int i = 0; i < Regions.Regions.Count; i++)
args.Player.SendRaptorRegion(Regions.Regions[i]);
}
if (args.Player.Group.HasPermission(Permissions.managewarp))
{
for (int i = 0; i < Warps.Warps.Count; i++)
args.Player.SendRaptorWarp(Warps.Warps[i]);
}
});
}
User u = Users.GetUserByName(args.Player.UserAccountName); User u = Users.GetUserByName(args.Player.UserAccountName);
List<String> KnownIps = new List<string>(); List<String> KnownIps = new List<string>();
if (!string.IsNullOrWhiteSpace(u.KnownIps)) if (!string.IsNullOrWhiteSpace(u.KnownIps))
@ -393,38 +383,40 @@ namespace TShockAPI
{ {
if (args.Player.IsLoggedIn) if (args.Player.IsLoggedIn)
args.Player.SaveServerCharacter(); args.Player.SaveServerCharacter();
if (args.Player.ItemInHand.type != 0)
{
args.Player.SendErrorMessage("Attempting to bypass SSC with item in hand.");
args.Handled = true;
}
} }
private void NetHooks_NameCollision(NameCollisionEventArgs args) private void NetHooks_NameCollision(NameCollisionEventArgs args)
{ {
string ip = TShock.Utils.GetRealIP(Netplay.serverSock[args.Who].tcpClient.Client.RemoteEndPoint.ToString()); string ip = TShock.Utils.GetRealIP(Netplay.serverSock[args.Who].tcpClient.Client.RemoteEndPoint.ToString());
foreach (TSPlayer ply in TShock.Players)
var player = TShock.Players.First(p => p != null && p.Name == args.Name && p.Index != args.Who);
if (player != null)
{ {
if (ply == null) if (player.IP == ip)
{ {
continue; Netplay.serverSock[player.Index].kill = true;
}
if (ply.Name == args.Name && ply.Index != args.Who)
{
if (ply.IP == ip)
{
if (ply.State < 2)
{
Utils.ForceKick(ply, "Name collision and this client has no world data.", true, false);
args.Handled = true; args.Handled = true;
return; return;
} }
else else if (player.IsLoggedIn)
{ {
args.Handled = false; User user = TShock.Users.GetUserByName(player.UserAccountName);
var ips = JsonConvert.DeserializeObject<List<string>>(user.KnownIps);
if (ips.Contains(ip))
{
Netplay.serverSock[player.Index].kill = true;
args.Handled = true;
return; return;
} }
} }
} }
} }
args.Handled = false;
return;
}
private void OnXmasCheck(ChristmasCheckEventArgs args) private void OnXmasCheck(ChristmasCheckEventArgs args)
{ {
@ -620,7 +612,7 @@ namespace TShockAPI
ComputeMaxStyles(); ComputeMaxStyles();
FixChestStacks(); FixChestStacks();
StatTracker.Initialize(); UpdateManager = new UpdateManager();
} }
private void ComputeMaxStyles() private void ComputeMaxStyles()
@ -664,7 +656,6 @@ namespace TShockAPI
private void OnUpdate(EventArgs args) private void OnUpdate(EventArgs args)
{ {
UpdateManager.UpdateProcedureCheck();
if (Backups.IsBackupTime) if (Backups.IsBackupTime)
Backups.Backup(); Backups.Backup();
//call these every second, not every update //call these every second, not every update
@ -674,7 +665,7 @@ namespace TShockAPI
LastCheck = DateTime.UtcNow; LastCheck = DateTime.UtcNow;
} }
if (TShock.Config.ServerSideCharacter && (DateTime.UtcNow - LastSave).TotalMinutes >= Config.ServerSideCharacterSave) if (Main.ServerSideCharacter && (DateTime.UtcNow - LastSave).TotalMinutes >= ServerSideCharacterConfig.ServerSideCharacterSave)
{ {
foreach (TSPlayer player in Players) foreach (TSPlayer player in Players)
{ {
@ -741,13 +732,13 @@ namespace TShockAPI
if (player.RecentFuse >0) if (player.RecentFuse >0)
player.RecentFuse--; player.RecentFuse--;
if ((TShock.Config.ServerSideCharacter) && (player.TPlayer.SpawnX > 0) &&(player.sX != player.TPlayer.SpawnX)) if ((Main.ServerSideCharacter) && (player.TPlayer.SpawnX > 0) &&(player.sX != player.TPlayer.SpawnX))
{ {
player.sX=player.TPlayer.SpawnX; player.sX=player.TPlayer.SpawnX;
player.sY=player.TPlayer.SpawnY; player.sY=player.TPlayer.SpawnY;
} }
if ((TShock.Config.ServerSideCharacter) && (player.sX > 0) && (player.sY > 0) && (player.TPlayer.SpawnX < 0)) if ((Main.ServerSideCharacter) && (player.sX > 0) && (player.sY > 0) && (player.TPlayer.SpawnX < 0))
{ {
player.TPlayer.SpawnX = player.sX; player.TPlayer.SpawnX = player.sX;
player.TPlayer.SpawnY = player.sY; player.TPlayer.SpawnY = player.sY;
@ -794,21 +785,24 @@ namespace TShockAPI
player.PaintThreshold = 0; player.PaintThreshold = 0;
} }
if (player.Dead && (DateTime.Now - player.LastDeath).Seconds >= Config.RespawnSeconds && player.Difficulty != 2) if (player.RespawnTimer > 0 && --player.RespawnTimer == 0 && player.Difficulty != 2)
{ {
player.Spawn(); player.Spawn();
} }
string check = "none"; string check = "none";
foreach (Item item in player.TPlayer.inventory) foreach (Item item in player.TPlayer.inventory)
{ {
if (!player.Group.HasPermission(Permissions.ignorestackhackdetection) && item.stack > item.maxStack && if (!player.Group.HasPermission(Permissions.ignorestackhackdetection) && (item.stack > item.maxStack || item.stack < 0) &&
item.type != 0) item.type != 0)
{ {
check = "Remove item " + item.name + " (" + item.stack + ") exceeds max stack of " + item.maxStack; check = "Remove item " + item.name + " (" + item.stack + ") exceeds max stack of " + item.maxStack;
player.SendErrorMessage(check);
break;
} }
} }
player.IgnoreActionsForCheating = check; player.IgnoreActionsForCheating = check;
check = "none"; check = "none";
//todo: pretty sure we check every place a players inventory can change, so do we really need to do this?
foreach (Item item in player.TPlayer.armor) foreach (Item item in player.TPlayer.armor)
{ {
if (Itembans.ItemIsBanned(item.name, player)) if (Itembans.ItemIsBanned(item.name, player))
@ -816,6 +810,9 @@ namespace TShockAPI
player.SetBuff(30, 120); //Bleeding player.SetBuff(30, 120); //Bleeding
player.SetBuff(36, 120); //Broken Armor player.SetBuff(36, 120); //Broken Armor
check = "Remove armor/accessory " + item.name; check = "Remove armor/accessory " + item.name;
player.SendErrorMessage(string.Format("You are wearing banned equipment. {0}", check));
break;
} }
} }
player.IgnoreActionsForDisabledArmor = check; player.IgnoreActionsForDisabledArmor = check;
@ -845,7 +842,8 @@ namespace TShockAPI
if (args.Handled) if (args.Handled)
return; return;
if (!Config.AllowCrimsonCreep && (args.Type == 0 || args.Type == 199 || args.Type == 203 || args.Type == 234)) if (!Config.AllowCrimsonCreep && (args.Type == 0 || args.Type == 199 || args.Type == 200 || args.Type == 203
|| args.Type == 234))
{ {
args.Handled = true; args.Handled = true;
return; return;
@ -858,7 +856,8 @@ namespace TShockAPI
return; return;
} }
if (!Config.AllowHallowCreep && (args.Type == 109 || args.Type == 117 || args.Type == 116)) if (!Config.AllowHallowCreep && (args.Type == 109 || args.Type == 117 || args.Type == 116 || args.Type == 115
|| args.Type == 164))
{ {
args.Handled = true; args.Handled = true;
} }
@ -973,12 +972,16 @@ namespace TShockAPI
player.Disconnect(String.Format("You are banned for {0} hour{1} and {2} minute{3}: {4}", player.Disconnect(String.Format("You are banned for {0} hour{1} and {2} minute{3}: {4}",
ts.Hours, ts.Hours == 1 ? "" : "s", ts.Minutes, ts.Minutes == 1 ? "" : "s", ban.Reason)); ts.Hours, ts.Hours == 1 ? "" : "s", ts.Minutes, ts.Minutes == 1 ? "" : "s", ban.Reason));
} }
else if (ts.Minutes > 0)
{
player.Disconnect(String.Format("You are banned for {0} minute{1} and {2} second{3}: {4}",
ts.Minutes, ts.Minutes == 1 ? "" : "s", ts.Seconds, ts.Seconds == 1 ? "" : "s", ban.Reason));
}
else else
{ {
player.Disconnect(String.Format("You are banned for {0} minute{1}: {2}", player.Disconnect(String.Format("You are banned for {0} second{1}: {2}",
ts.Minutes, ts.Minutes == 1 ? "" : "s", ban.Reason)); ts.Seconds, ts.Seconds == 1 ? "" : "s", ban.Reason));
} }
} }
args.Handled = true; args.Handled = true;
} }
@ -996,7 +999,7 @@ namespace TShockAPI
Utils.Broadcast(tsplr.Name + " has left.", Color.Yellow); Utils.Broadcast(tsplr.Name + " has left.", Color.Yellow);
Log.Info(string.Format("{0} disconnected.", tsplr.Name)); Log.Info(string.Format("{0} disconnected.", tsplr.Name));
if (tsplr.IsLoggedIn && !tsplr.IgnoreActionsForClearingTrashCan && TShock.Config.ServerSideCharacter && (!tsplr.Dead || tsplr.TPlayer.difficulty != 2)) if (tsplr.IsLoggedIn && !tsplr.IgnoreActionsForClearingTrashCan && Main.ServerSideCharacter && (!tsplr.Dead || tsplr.TPlayer.difficulty != 2))
{ {
tsplr.PlayerData.CopyCharacter(tsplr); tsplr.PlayerData.CopyCharacter(tsplr);
CharacterDB.InsertPlayerData(tsplr); CharacterDB.InsertPlayerData(tsplr);
@ -1034,7 +1037,7 @@ namespace TShockAPI
return; return;
}*/ }*/
if (args.Text.StartsWith("/") && args.Text.Length > 1) if (args.Text.StartsWith(Config.CommandSpecifier) && !string.IsNullOrWhiteSpace(args.Text.Substring(1)))
{ {
try try
{ {
@ -1059,9 +1062,10 @@ namespace TShockAPI
} }
else if (!TShock.Config.EnableChatAboveHeads) else if (!TShock.Config.EnableChatAboveHeads)
{ {
Utils.Broadcast( var text = String.Format(Config.ChatFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix,
String.Format(Config.ChatFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix, args.Text), args.Text);
tsplr.Group.R, tsplr.Group.G, tsplr.Group.B); Hooks.PlayerHooks.OnPlayerChat(tsplr, args.Text, ref text);
Utils.Broadcast(text, tsplr.Group.R, tsplr.Group.G, tsplr.Group.B);
args.Handled = true; args.Handled = true;
} }
else else
@ -1071,12 +1075,14 @@ namespace TShockAPI
ply.name = String.Format(Config.ChatAboveHeadsFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix); ply.name = String.Format(Config.ChatAboveHeadsFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix);
NetMessage.SendData((int)PacketTypes.PlayerInfo, -1, -1, ply.name, args.Who, 0, 0, 0, 0); NetMessage.SendData((int)PacketTypes.PlayerInfo, -1, -1, ply.name, args.Who, 0, 0, 0, 0);
ply.name = name; ply.name = name;
NetMessage.SendData((int) PacketTypes.ChatText, -1, args.Who, args.Text, args.Who, tsplr.Group.R, tsplr.Group.G, tsplr.Group.B); var text = args.Text;
Hooks.PlayerHooks.OnPlayerChat(tsplr, args.Text, ref text);
NetMessage.SendData((int)PacketTypes.ChatText, -1, args.Who, text, args.Who, tsplr.Group.R, tsplr.Group.G, tsplr.Group.B);
NetMessage.SendData((int)PacketTypes.PlayerInfo, -1, -1, name, args.Who, 0, 0, 0, 0); NetMessage.SendData((int)PacketTypes.PlayerInfo, -1, -1, name, args.Who, 0, 0, 0, 0);
string msg = String.Format("<{0}> {1}", string msg = String.Format("<{0}> {1}",
String.Format(Config.ChatAboveHeadsFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix), String.Format(Config.ChatAboveHeadsFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix),
args.Text); text);
tsplr.SendMessage(msg, tsplr.Group.R, tsplr.Group.G, tsplr.Group.B); tsplr.SendMessage(msg, tsplr.Group.R, tsplr.Group.G, tsplr.Group.B);
@ -1160,13 +1166,13 @@ namespace TShockAPI
} }
if ((player.State < 10 || player.Dead) && (int) type > 12 && (int) type != 16 && (int) type != 42 && (int) type != 50 && if ((player.State < 10 || player.Dead) && (int) type > 12 && (int) type != 16 && (int) type != 42 && (int) type != 50 &&
(int) type != 38 && (int) type != 21) (int) type != 38 && (int) type != 21 && (int) type != 22)
{ {
e.Handled = true; e.Handled = true;
return; return;
} }
using (var data = new MemoryStream(e.Msg.readBuffer, e.Index, e.Length)) using (var data = new MemoryStream(e.Msg.readBuffer, e.Index, e.Length - 1))
{ {
// Exceptions are already handled // Exceptions are already handled
e.Handled = GetDataHandlers.HandlerGetData(type, player, data); e.Handled = GetDataHandlers.HandlerGetData(type, player, data);
@ -1215,7 +1221,7 @@ namespace TShockAPI
if (!player.IsLoggedIn) if (!player.IsLoggedIn)
{ {
if (Config.ServerSideCharacter) if (Main.ServerSideCharacter)
{ {
player.SendMessage( player.SendMessage(
player.IgnoreActionsForInventory = "Server side characters is enabled! Please /register or /login to play!", player.IgnoreActionsForInventory = "Server side characters is enabled! Please /register or /login to play!",
@ -1266,14 +1272,6 @@ namespace TShockAPI
e.Object.SetDefaults(0); e.Object.SetDefaults(0);
} }
private void OnNpcSetDefaults(SetDefaultsEventArgs<NPC, int> e)
{
if (Itembans.ItemIsBanned(e.Object.name, null))
{
e.Object.SetDefaults(0);
}
}
/// <summary> /// <summary>
/// Send bytes to client using packetbuffering if available /// Send bytes to client using packetbuffering if available
/// </summary> /// </summary>
@ -1351,8 +1349,6 @@ namespace TShockAPI
if (e.remoteClient == -1) return; if (e.remoteClient == -1) return;
var player = Players[e.remoteClient]; var player = Players[e.remoteClient];
if (player == null) return; if (player == null) return;
if (Config.UseServerName)
{
using (var ms = new MemoryStream()) using (var ms = new MemoryStream())
{ {
var msg = new WorldInfoMsg var msg = new WorldInfoMsg
@ -1361,12 +1357,13 @@ namespace TShockAPI
DayTime = Main.dayTime, DayTime = Main.dayTime,
MoonPhase = (byte)Main.moonPhase, MoonPhase = (byte)Main.moonPhase,
BloodMoon = Main.bloodMoon, BloodMoon = Main.bloodMoon,
MaxTilesX = Main.maxTilesX, Eclipse = Main.eclipse,
MaxTilesY = Main.maxTilesY, MaxTilesX = (short)Main.maxTilesX,
SpawnX = Main.spawnTileX, MaxTilesY = (short)Main.maxTilesY,
SpawnY = Main.spawnTileY, SpawnX = (short)Main.spawnTileX,
WorldSurface = (int)Main.worldSurface, SpawnY = (short)Main.spawnTileY,
RockLayer = (int)Main.rockLayer, WorldSurface = (short)Main.worldSurface,
RockLayer = (short)Main.rockLayer,
//Sending a fake world id causes the client to not be able to find a stored spawnx/y. //Sending a fake world id causes the client to not be able to find a stored spawnx/y.
//This fixes the bed spawn point bug. With a fake world id it wont be able to find the bed spawn. //This fixes the bed spawn point bug. With a fake world id it wont be able to find the bed spawn.
WorldID = Main.worldID, WorldID = Main.worldID,
@ -1404,14 +1401,16 @@ namespace TShockAPI
(NPC.downedBoss3 ? BossFlags.DownedBoss3 : BossFlags.None) | (NPC.downedBoss3 ? BossFlags.DownedBoss3 : BossFlags.None) |
(Main.hardMode ? BossFlags.HardMode : BossFlags.None) | (Main.hardMode ? BossFlags.HardMode : BossFlags.None) |
(NPC.downedClown ? BossFlags.DownedClown : BossFlags.None) | (NPC.downedClown ? BossFlags.DownedClown : BossFlags.None) |
(Main.ServerSideCharacter ? BossFlags.ServerSideCharacter : BossFlags.None), (Main.ServerSideCharacter ? BossFlags.ServerSideCharacter : BossFlags.None) |
(NPC.downedPlantBoss ? BossFlags.DownedPlantBoss : BossFlags.None),
BossFlags2 = (NPC.downedMechBoss1 ? BossFlags2.DownedMechBoss1 : BossFlags2.None) | BossFlags2 = (NPC.downedMechBoss1 ? BossFlags2.DownedMechBoss1 : BossFlags2.None) |
(NPC.downedMechBoss2 ? BossFlags2.DownedMechBoss2 : BossFlags2.None) | (NPC.downedMechBoss2 ? BossFlags2.DownedMechBoss2 : BossFlags2.None) |
(NPC.downedMechBoss3 ? BossFlags2.DownedMechBoss3 : BossFlags2.None) | (NPC.downedMechBoss3 ? BossFlags2.DownedMechBoss3 : BossFlags2.None) |
(NPC.downedMechBossAny ? BossFlags2.DownedMechBossAny : BossFlags2.None) | (NPC.downedMechBossAny ? BossFlags2.DownedMechBossAny : BossFlags2.None) |
(Main.cloudBGActive == 1f ? BossFlags2.CloudBg : BossFlags2.None) | (Main.cloudBGActive >= 1f ? BossFlags2.CloudBg : BossFlags2.None) |
(WorldGen.crimson ? BossFlags2.Crimson : BossFlags2.None) | (WorldGen.crimson ? BossFlags2.Crimson : BossFlags2.None) |
(Main.pumpkinMoon ? BossFlags2.Pumpkin : BossFlags2.None), (Main.pumpkinMoon ? BossFlags2.PumpkinMoon : BossFlags2.None) |
(Main.snowMoon ? BossFlags2.SnowMoon : BossFlags2.None) ,
Rain = Main.maxRaining, Rain = Main.maxRaining,
WorldName = TShock.Config.UseServerName ? TShock.Config.ServerName : Main.worldName WorldName = TShock.Config.UseServerName ? TShock.Config.ServerName : Main.worldName
}; };
@ -1421,7 +1420,6 @@ namespace TShockAPI
e.Handled = true; e.Handled = true;
return; return;
} }
}
else if (e.MsgId == PacketTypes.PlayerHp) else if (e.MsgId == PacketTypes.PlayerHp)
{ {
if (Main.player[(byte)e.number].statLife <= 0) if (Main.player[(byte)e.number].statLife <= 0)
@ -1519,11 +1517,6 @@ namespace TShockAPI
Projectile proj = new Projectile(); Projectile proj = new Projectile();
proj.SetDefaults(type); proj.SetDefaults(type);
if (Itembans.ItemIsBanned(proj.name, player))
{
return true;
}
if (Main.projHostile[type]) if (Main.projHostile[type])
{ {
//player.SendMessage( proj.name, Color.Yellow); //player.SendMessage( proj.name, Color.Yellow);
@ -1542,7 +1535,7 @@ namespace TShockAPI
return false; return false;
} }
public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY, byte tileType, GetDataHandlers.EditAction actionType) public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY, short tileType, GetDataHandlers.EditAction actionType)
{ {
if (!player.Group.HasPermission(Permissions.canbuild)) if (!player.Group.HasPermission(Permissions.canbuild))
{ {
@ -1760,7 +1753,7 @@ namespace TShockAPI
public static bool CheckIgnores(TSPlayer player) public static bool CheckIgnores(TSPlayer player)
{ {
return player.IgnoreActionsForInventory != "none" || player.IgnoreActionsForCheating != "none" || player.IgnoreActionsForDisabledArmor != "none" || player.IgnoreActionsForClearingTrashCan || !player.IsLoggedIn && Config.RequireLogin;; return player.IgnoreActionsForInventory != "none" || player.IgnoreActionsForCheating != "none" || player.IgnoreActionsForDisabledArmor != "none" || player.IgnoreActionsForClearingTrashCan || !player.IsLoggedIn && Config.RequireLogin;
} }
public void OnConfigRead(ConfigFile file) public void OnConfigRead(ConfigFile file)

View file

@ -72,11 +72,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="BackupManager.cs" /> <Compile Include="BackupManager.cs" />
<Compile Include="DB\ProjectileManager.cs" />
<Compile Include="DB\RegionManager.cs" /> <Compile Include="DB\RegionManager.cs" />
<Compile Include="DB\TileManager.cs" />
<Compile Include="Hooks\GeneralHooks.cs" /> <Compile Include="Hooks\GeneralHooks.cs" />
<Compile Include="Hooks\PlayerHooks.cs" /> <Compile Include="Hooks\PlayerHooks.cs" />
<Compile Include="PaginationTools.cs" /> <Compile Include="PaginationTools.cs" />
<Compile Include="RaptorPacketTypes.cs" />
<Compile Include="Rest\RestPermissions.cs" /> <Compile Include="Rest\RestPermissions.cs" />
<Compile Include="SaveManager.cs" /> <Compile Include="SaveManager.cs" />
<Compile Include="DB\BanManager.cs" /> <Compile Include="DB\BanManager.cs" />
@ -122,6 +123,7 @@
<Compile Include="Rest\RestObject.cs" /> <Compile Include="Rest\RestObject.cs" />
<Compile Include="Rest\RestVerbs.cs" /> <Compile Include="Rest\RestVerbs.cs" />
<Compile Include="Rest\SecureRest.cs" /> <Compile Include="Rest\SecureRest.cs" />
<Compile Include="ServerSideCharacters\ServerSideConfig.cs" />
<Compile Include="StatTracker.cs" /> <Compile Include="StatTracker.cs" />
<Compile Include="Utils.cs" /> <Compile Include="Utils.cs" />
<Compile Include="TShock.cs" /> <Compile Include="TShock.cs" />

View file

@ -1,7 +1,7 @@
extensions: .cs extensions: .cs
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

72
TShockAPI/UpdateManager.cs Normal file → Executable file
View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -18,32 +18,44 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Net; using System.Net;
using System.Threading; using System.Threading;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace TShockAPI namespace TShockAPI
{ {
internal class UpdateManager public class UpdateManager
{ {
private static string updateUrl = "http://shankshock.com/tshock-update.json"; private string updateUrl = "http://update.tshock.co/latest/";
public static DateTime lastcheck = DateTime.MinValue;
/// <summary> /// <summary>
/// Check once every X minutes. /// Check once every X minutes.
/// </summary> /// </summary>
private static readonly int CheckXMinutes = 30; private readonly int CheckXMinutes = 30;
public static void UpdateProcedureCheck() public UpdateManager()
{ {
if ((DateTime.Now - lastcheck).TotalMinutes >= CheckXMinutes) ThreadPool.QueueUserWorkItem(CheckForUpdates);
{
ThreadPool.QueueUserWorkItem(CheckUpdate);
lastcheck = DateTime.Now;
}
} }
public static void CheckUpdate(object o) private void CheckForUpdates(object state)
{
try
{
UpdateCheck(state);
}
catch (Exception)
{
//swallow the exception
return;
}
Thread.Sleep(CheckXMinutes * 60 * 1000);
ThreadPool.QueueUserWorkItem(CheckForUpdates);
}
public void UpdateCheck(object o)
{ {
var updates = ServerIsOutOfDate(); var updates = ServerIsOutOfDate();
if (updates != null) if (updates != null)
@ -56,29 +68,39 @@ namespace TShockAPI
/// Checks to see if the server is out of date. /// Checks to see if the server is out of date.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private static Dictionary<string, string> ServerIsOutOfDate() private Dictionary<string, string> ServerIsOutOfDate()
{ {
using (var client = new WebClient()) var client = (HttpWebRequest)WebRequest.Create(updateUrl);
{ client.Timeout = 5000;
client.Headers.Add("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705;)");
try try
{ {
string updatejson = client.DownloadString(updateUrl); using (var resp = TShock.Utils.GetResponseNoException(client))
{
if (resp.StatusCode != HttpStatusCode.OK)
{
throw new IOException("Server did not respond with an OK.");
}
using(var reader = new StreamReader(resp.GetResponseStream()))
{
string updatejson = reader.ReadToEnd();
var update = JsonConvert.DeserializeObject<Dictionary<string, string>>(updatejson); var update = JsonConvert.DeserializeObject<Dictionary<string, string>>(updatejson);
var version = new Version(update["version"]); var version = new Version(update["version"]);
if (TShock.VersionNum.CompareTo(version) < 0) if (TShock.VersionNum.CompareTo(version) < 0)
return update; return update;
} }
}
}
catch (Exception e) catch (Exception e)
{ {
Log.Error(e.ToString()); Log.ConsoleError("UpdateManager Exception: {0}", e);
} throw e;
return null;
}
} }
private static void NotifyAdministrators(Dictionary<string, string> update) return null;
}
private void NotifyAdministrators(Dictionary<string, string> update)
{ {
var changes = update["changes"].Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries); var changes = update["changes"].Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries);
NotifyAdministrator(TSPlayer.Server, changes); NotifyAdministrator(TSPlayer.Server, changes);
@ -91,9 +113,9 @@ namespace TShockAPI
} }
} }
private static void NotifyAdministrator(TSPlayer player, string[] changes) private void NotifyAdministrator(TSPlayer player, string[] changes)
{ {
player.SendMessage("The server is out of date.", Color.Red); player.SendMessage("The server is out of date. Latest version: ", Color.Red);
for (int j = 0; j < changes.Length; j++) for (int j = 0; j < changes.Length; j++)
{ {
player.SendMessage(changes[j], Color.Red); player.SendMessage(changes[j], Color.Red);

View file

@ -1,6 +1,6 @@
/* /*
TShock, a server mod for Terraria TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team) Copyright (C) 2011-2015 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -442,7 +442,7 @@ namespace TShockAPI
/// <returns>name</returns> /// <returns>name</returns>
public string GetBuffName(int id) public string GetBuffName(int id)
{ {
return (id > 0 && id < Main.maxBuffs) ? Main.buffName[id] : "null"; return (id > 0 && id < Main.maxBuffTypes) ? Main.buffName[id] : "null";
} }
/// <summary> /// <summary>
@ -452,7 +452,7 @@ namespace TShockAPI
/// <returns>description</returns> /// <returns>description</returns>
public string GetBuffDescription(int id) public string GetBuffDescription(int id)
{ {
return (id > 0 && id < Main.maxBuffs) ? Main.buffTip[id] : "null"; return (id > 0 && id < Main.maxBuffTypes) ? Main.buffTip[id] : "null";
} }
/// <summary> /// <summary>
@ -463,13 +463,13 @@ namespace TShockAPI
public List<int> GetBuffByName(string name) public List<int> GetBuffByName(string name)
{ {
string nameLower = name.ToLower(); string nameLower = name.ToLower();
for (int i = 1; i < Main.maxBuffs; i++) for (int i = 1; i < Main.maxBuffTypes; i++)
{ {
if (Main.buffName[i].ToLower() == nameLower) if (Main.buffName[i].ToLower() == nameLower)
return new List<int> {i}; return new List<int> {i};
} }
var found = new List<int>(); var found = new List<int>();
for (int i = 1; i < Main.maxBuffs; i++) for (int i = 1; i < Main.maxBuffTypes; i++)
{ {
if (Main.buffName[i].ToLower().StartsWith(nameLower)) if (Main.buffName[i].ToLower().StartsWith(nameLower))
found.Add(i); found.Add(i);
@ -484,11 +484,7 @@ namespace TShockAPI
/// <returns>Prefix name</returns> /// <returns>Prefix name</returns>
public string GetPrefixById(int id) public string GetPrefixById(int id)
{ {
var item = new Item(); return id < FirstItemPrefix || id > LastItemPrefix ? "" : Lang.prefix[id] ?? "";
item.SetDefaults(0);
item.prefix = (byte) id;
item.AffixName();
return item.name.Trim();
} }
/// <summary> /// <summary>
@ -574,7 +570,7 @@ namespace TShockAPI
/// <param name="reason">string reason (default: "Server shutting down!")</param> /// <param name="reason">string reason (default: "Server shutting down!")</param>
public void RestartServer(bool save = true, string reason = "Server shutting down!") public void RestartServer(bool save = true, string reason = "Server shutting down!")
{ {
if (TShock.Config.ServerSideCharacter) if (Main.ServerSideCharacter)
foreach (TSPlayer player in TShock.Players) foreach (TSPlayer player in TShock.Players)
if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan) if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan)
TShock.CharacterDB.InsertPlayerData(player); TShock.CharacterDB.InsertPlayerData(player);
@ -681,12 +677,11 @@ namespace TShockAPI
string playerName = player.Name; string playerName = player.Name;
TShock.Bans.AddBan(ip, playerName, uuid, reason, false, adminUserName); TShock.Bans.AddBan(ip, playerName, uuid, reason, false, adminUserName);
player.Disconnect(string.Format("Banned: {0}", reason)); player.Disconnect(string.Format("Banned: {0}", reason));
Log.ConsoleInfo(string.Format("Banned {0} for : '{1}'", playerName, reason));
string verb = force ? "force " : ""; string verb = force ? "force " : "";
if (string.IsNullOrWhiteSpace(adminUserName)) if (string.IsNullOrWhiteSpace(adminUserName))
Broadcast(string.Format("{0} was {1}banned for '{2}'", playerName, verb, reason.ToLower())); TSPlayer.All.SendInfoMessage("{0} was {1}banned for '{2}'.", playerName, verb, reason);
else else
Broadcast(string.Format("{0} {1}banned {2} for '{3}'", adminUserName, verb, playerName, reason.ToLower())); TSPlayer.All.SendInfoMessage("{0} {1}banned {2} for '{3}'.", adminUserName, verb, playerName, reason);
return true; return true;
} }
return false; return false;
@ -893,7 +888,7 @@ namespace TShockAPI
var sb = new StringBuilder(3); var sb = new StringBuilder(3);
for (int i = 0; i < str.Length; i++) for (int i = 0; i < str.Length; i++)
{ {
if (char.IsDigit(str[i]) || (str[i] == '-' || str[i] == '+')) if (Char.IsDigit(str[i]) || (str[i] == '-' || str[i] == '+'))
sb.Append(str[i]); sb.Append(str[i]);
else else
{ {
@ -921,6 +916,8 @@ namespace TShockAPI
} }
} }
} }
if (sb.Length != 0)
return false;
return true; return true;
} }
@ -975,5 +972,62 @@ namespace TShockAPI
yield return new Point(regionArea.Right, regionArea.Top + y); yield return new Point(regionArea.Right, regionArea.Top + y);
} }
} }
public int? EncodeColor(Color? color)
{
if (color == null)
return null;
return BitConverter.ToInt32(new[] { color.Value.R, color.Value.G, color.Value.B, color.Value.A }, 0);
}
public Color? DecodeColor(int? encodedColor)
{
if (encodedColor == null)
return null;
byte[] data = BitConverter.GetBytes(encodedColor.Value);
return new Color(data[0], data[1], data[2], data[3]);
}
public byte? EncodeBitsByte(BitsByte? bitsByte)
{
if (bitsByte == null)
return null;
byte result = 0;
for (int i = 0; i < 8; i++)
if (bitsByte.Value[i])
result |= (byte)(1 << i);
return result;
}
public BitsByte? DecodeBitsByte(int? encodedBitsByte)
{
if (encodedBitsByte == null)
return null;
BitsByte result = new BitsByte();
for (int i = 0; i < 8; i++)
result[i] = (encodedBitsByte & 1 << i) != 0;
return result;
}
public HttpWebResponse GetResponseNoException(HttpWebRequest req)
{
try
{
return (HttpWebResponse)req.GetResponse();
}
catch (WebException we)
{
var resp = we.Response as HttpWebResponse;
if (resp == null)
throw;
return resp;
}
}
} }
} }

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<TestLists xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<TestList name="Bamboo" id="63a4ff11-fe54-4b77-97f5-2e5034a7c905" parentListId="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
<TestLinks>
<TestLink id="7601a790-d2fb-45d2-a612-1ae4de84eb61" name="regionmanagertest" storage="unittests\regionmanagertest.orderedtest" type="Microsoft.VisualStudio.TestTools.TestTypes.Ordered.AutoSuite, Microsoft.VisualStudio.QualityTools.Tips.OrderedTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f28695ef-8181-4996-8783-b5059ce904b1" name="banmanagertest" storage="unittests\banmanagertest.orderedtest" type="Microsoft.VisualStudio.TestTools.TestTypes.Ordered.AutoSuite, Microsoft.VisualStudio.QualityTools.Tips.OrderedTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="b9c6b3d7-52d8-4b49-bfbf-933efa073ca8" name="itemmanagertest" storage="unittests\itemmanagertest.orderedtest" type="Microsoft.VisualStudio.TestTools.TestTypes.Ordered.AutoSuite, Microsoft.VisualStudio.QualityTools.Tips.OrderedTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="ec2aa146-8548-415b-a9f5-80472ce3c7d9" name="groupmanagertest" storage="unittests\groupmanagertest.orderedtest" type="Microsoft.VisualStudio.TestTools.TestTypes.Ordered.AutoSuite, Microsoft.VisualStudio.QualityTools.Tips.OrderedTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
</TestLinks>
</TestList>
<TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
<RunConfiguration id="943ada2e-478e-45be-b4b8-6f7d6d949602" name="Local" storage="local.testsettings" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</TestList>
</TestLists>

@ -1 +1 @@
Subproject commit 0ddd492aa03e5c97dddbc95b2e605fa2823804ab Subproject commit 50a04c45bfc2d1de2de1a31b215f7bdc546cfdd5

View file

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<TestSettings name="Trace and Test Impact" id="8af8e0df-7e31-4229-8e49-54b1487fd7e4" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Description>These are test settings for Trace and Test Impact.</Description>
<Execution>
<TestTypeSpecific />
<AgentRule name="Execution Agents">
</AgentRule>
</Execution>
</TestSettings>

View file

@ -1,68 +0,0 @@
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2012 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 System.Text;
using System.Collections.Generic;
using System.Linq;
using Mono.Data.Sqlite;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TShockAPI;
using TShockAPI.DB;
namespace UnitTests
{
[TestClass]
public class BanManagerTest
{
public static IDbConnection DB;
private BanManager Bans;
[TestInitialize]
public void Initialize()
{
TShock.Config = new ConfigFile();
TShock.Config.StorageType = "sqlite";
DB = new SqliteConnection(string.Format("uri=file://{0},Version=3", "tshock.test.sqlite"));
DB.Open();
Bans = new BanManager(DB);
}
[TestMethod]
public void TestBansDBNotNull()
{
Assert.IsNotNull(Bans);
}
[TestMethod]
public void AddBanTest()
{
Assert.IsTrue(Bans.AddBan("127.0.0.1", "BanTest", "BanTest2", "Ban Testing"));
}
[TestMethod]
public void FindBanTest()
{
Assert.IsNotNull(Bans.GetBanByIp("127.0.0.1"));
Assert.IsNotNull(Bans.GetBanByName("BanTest"));
Assert.IsNotNull(Bans.GetBanByUUID("BanTest2"));
}
}
}

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<OrderedTest name="banmanagertest" storage="c:\users\virus\git\tshock\unittests\banmanagertest.orderedtest" id="f28695ef-8181-4996-8783-b5059ce904b1" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<TestLinks>
<TestLink id="7cc70e31-eeb8-f6b8-afa2-17bf975873ed" name="TestBansDBNotNull" storage="bin\debug\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="67a76536-c5c2-4d99-515a-498708451061" name="AddBanTest" storage="bin\debug\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="9265845c-1bec-1156-2e22-1a64c5bd689f" name="FindBanTest" storage="bin\debug\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</TestLinks>
</OrderedTest>

View file

@ -1,80 +0,0 @@
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2012 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 System.Text;
using System.Collections.Generic;
using System.Linq;
using Mono.Data.Sqlite;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TShockAPI;
using TShockAPI.DB;
namespace UnitTests
{
[TestClass]
public class GroupManagerTest
{
public static IDbConnection DB;
private GroupManager Groups;
[TestInitialize]
public void Initialize()
{
TShock.Config = new ConfigFile();
TShock.Config.StorageType = "sqlite";
DB = new SqliteConnection(string.Format("uri=file://{0},Version=3", "tshock.test.sqlite"));
DB.Open();
Groups = new GroupManager(DB);
TShock.Groups = this.Groups;
}
[TestMethod]
public void TestGroupsDBNotNull()
{
Assert.IsNotNull(Groups);
}
[TestMethod]
public void CreateGroup()
{
Assert.IsTrue(Groups.AddGroup("test1", "heal") != "");
Assert.IsTrue(Groups.GroupExists("test1"));
Assert.IsTrue(TShock.Utils.GetGroup("test1").HasPermission("heal"));
}
[TestMethod]
public void DeleteGroup()
{
Assert.IsTrue(Groups.AddGroup("test1", "heal") != "");
Assert.IsTrue(Groups.GroupExists("test1"));
Assert.IsTrue(Groups.DeleteGroup("test1") != "");
Assert.IsFalse( Groups.GroupExists( "test1") );
}
/*[TestMethod]
public void CreateGroup()
{
Assert.IsTrue(Groups.AddGroup("test1", "heal") != "");
Assert.IsTrue(Groups.GroupExists("test1"));
Assert.IsTrue(Tools.GetGroup("test1").HasPermission("heal"));
}*/
}
}

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<OrderedTest name="groupmanagertest" storage="c:\users\virus\git\tshock\unittests\groupmanagertest.orderedtest" id="ec2aa146-8548-415b-a9f5-80472ce3c7d9" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<TestLinks>
<TestLink id="4b09514b-0cca-b305-b9af-a4ceaaaf12dd" name="TestGroupsDBNotNull" storage="bin\debug\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="6ea1e597-9c3c-745b-5307-55ff47787810" name="DeleteGroup" storage="bin\debug\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="a66f56ff-803a-ff91-0bca-9abde10363de" name="CreateGroup" storage="bin\debug\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</TestLinks>
</OrderedTest>

View file

@ -1,97 +0,0 @@
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2012 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.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using System.Data;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Threading;
using Mono.Data.Sqlite;
using TShockAPI.DB;
using TShockAPI;
namespace UnitTests
{
/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestClass]
public class ItemManagerTest
{
public static IDbConnection DB;
public static ItemManager manager;
[TestInitialize]
public void Initialize()
{
TShock.Config = new ConfigFile();
TShock.Config.StorageType = "sqlite";
DB = new SqliteConnection(string.Format("uri=file://{0},Version=3", "tshock.test.sqlite"));
DB.Open();
manager = new ItemManager(DB);
}
[TestMethod]
public void SQLiteItemTest_AddBan()
{
Assert.IsNotNull(manager);
Assert.IsFalse( manager.ItemIsBanned("Dirt Block"), "Item isn't banned" );
manager.AddNewBan("Dirt Block");
Assert.IsTrue( manager.ItemIsBanned("Dirt Block"), "New item is added");
Assert.IsFalse( manager.ItemIsBanned("Green Brick"), "Item isn't banned");
manager.AddNewBan("Green Brick");
Assert.IsTrue( manager.ItemIsBanned("Green Brick"), "New item is added");
Assert.AreEqual(2, manager.ItemBans.Count, "Adding both items");
manager.AddNewBan("Green Brick" );
Assert.AreEqual(2, manager.ItemBans.Count, "Adding duplicate items");
}
[TestMethod]
public void SQLiteItemTest_RemoveBan()
{
manager = new ItemManager(DB);
Assert.IsNotNull(manager);
Assert.AreEqual(2, manager.ItemBans.Count);
manager.AddNewBan("Dirt Block");
Assert.AreEqual(2, manager.ItemBans.Count);
Assert.AreEqual(true, manager.ItemIsBanned("Dirt Block"));
manager.RemoveBan("Dirt Block");
manager.UpdateItemBans();
Assert.AreEqual(1, manager.ItemBans.Count);
Assert.AreEqual(false, manager.ItemIsBanned("Dirt Block"));
manager.RemoveBan("Dirt Block");
Assert.AreEqual(false, manager.ItemIsBanned("Dirt Block"));
Assert.AreEqual(true, manager.ItemIsBanned("Green Brick"));
manager.RemoveBan("Green Brick");
Assert.AreEqual(false, manager.ItemIsBanned("Green Brick"));
}
[TestCleanup]
public void Cleanup()
{
DB.Close();
}
}
}

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<OrderedTest name="ItemManagerTest" storage="c:\users\virus\git\tshock\unittests\itemmanagertest.orderedtest" id="b9c6b3d7-52d8-4b49-bfbf-933efa073ca8" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<TestLinks>
<TestLink id="851eff7f-13e8-7778-e7ca-71ff3ce24234" name="SQLiteItemTest_AddBan" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="26cf8396-064b-1c1d-c511-37969c68dfbd" name="SQLiteItemTest_RemoveBan" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</TestLinks>
</OrderedTest>

View file

@ -1,52 +0,0 @@
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2012 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("UnitTests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("UnitTests")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
[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("edd69981-21b0-42af-bb55-25088efab253")]
// 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.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -1,141 +0,0 @@
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2012 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.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data;
using TShockAPI;
using Mono.Data.Sqlite;
using TShockAPI.DB;
using Region = TShockAPI.DB.Region;
namespace UnitTests
{
/// <summary>
/// Summary description for RegionManagerTest
/// </summary>
[TestClass]
public class RegionManagerTest
{
public static IDbConnection DB;
public static RegionManager manager;
[TestInitialize]
public void Initialize()
{
TShock.Config = new ConfigFile();
TShock.Config.StorageType = "sqlite";
DB = new SqliteConnection(string.Format("uri=file://{0},Version=3", "tshock.test.sqlite"));
DB.Open();
manager = new RegionManager(DB);
TShock.Regions = manager;
manager.ReloadForUnitTest("test");
}
[TestMethod]
public void AddRegion()
{
Region r = new Region( new Rectangle(100,100,100,100), "test", "test", true, "test", 0);
Assert.IsTrue(manager.AddRegion(r.Area.X, r.Area.Y, r.Area.Width, r.Area.Height, r.Name, r.Owner, r.WorldID));
Assert.AreEqual(1, manager.Regions.Count);
Assert.IsNotNull(manager.ZacksGetRegionByName("test"));
Region r2 = new Region(new Rectangle(201, 201, 100, 100), "test2", "test2", true, "test", 0);
manager.AddRegion(r2.Area.X, r2.Area.Y, r2.Area.Width, r2.Area.Height, r2.Name, r2.Owner, r2.WorldID);
Assert.AreEqual(2, manager.Regions.Count);
Assert.IsNotNull(manager.ZacksGetRegionByName("test2"));
}
[TestMethod]
public void DeleteRegion()
{
Assert.IsTrue(2 == manager.Regions.Count);
Assert.IsTrue(manager.DeleteRegion("test"));
Assert.IsTrue(1 == manager.Regions.Count);
Assert.IsTrue(manager.DeleteRegion("test2"));
Assert.IsTrue(0 == manager.Regions.Count);
}
[TestMethod]
public void InRegion()
{
Assert.IsTrue(manager.InArea(100, 100));
Assert.IsTrue(manager.InArea(150, 150));
Assert.IsTrue(manager.InArea(200, 200));
Assert.IsTrue(manager.InArea(201, 201));
Assert.IsTrue(manager.InArea(251, 251));
Assert.IsTrue(manager.InArea(301, 301));
Assert.IsFalse(manager.InArea(311, 311));
Assert.IsFalse(manager.InArea(99, 99));
}
[TestMethod]
public void SetRegionState()
{
Assert.IsTrue(manager.ZacksGetRegionByName("test").DisableBuild);
manager.SetRegionStateTest("test", "test", false);
Assert.IsTrue(!manager.ZacksGetRegionByName("test").DisableBuild);
manager.SetRegionStateTest("test", "test", true);
Assert.IsTrue(manager.ZacksGetRegionByName("test").DisableBuild);
Assert.IsTrue(manager.ZacksGetRegionByName("test2").DisableBuild);
manager.SetRegionStateTest("test2", "test", false);
Assert.IsTrue(!manager.ZacksGetRegionByName("test2").DisableBuild);
manager.SetRegionStateTest("test2", "test", true);
Assert.IsTrue(manager.ZacksGetRegionByName("test2").DisableBuild);
}
[TestMethod]
public void CanBuild()
{
/**
* For now, this test is useless. Need to implement user groups so we can alter Canbuild permission.
*/
}
[TestMethod]
public void AddUser()
{
/**
* For now, this test is useless. Need to implement users so we have names to get ids from.
*/
}
[TestMethod]
public void ListID()
{
Assert.IsTrue(RegionManager.ListIDs("1,2,3,4,5").Count == 5);
Assert.IsTrue(RegionManager.ListIDs("").Count == 0);
}
[TestMethod]
public void ListRegions()
{
//needs a little more work.
}
[TestCleanup]
public void Cleanup()
{
DB.Close();
}
}
}

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<OrderedTest name="regionmanagertest" storage="c:\users\shank\dropbox\design and development\csharp\tshock\unittests\regionmanagertest.orderedtest" id="7601a790-d2fb-45d2-a612-1ae4de84eb61" continueAfterFailure="true" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Execution id="41a9a1cc-4b4c-466c-b54a-8bd056d3489f" />
<TestLinks>
<TestLink id="8d92e80b-8c9d-7a14-5c3a-eba6790be784" name="AddRegion" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="57686a56-2684-8c17-1564-ed9a3c37b167" name="InRegion" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="05a473bf-6457-6122-6150-b1aa82e8f869" name="SetRegionState" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="999dec4b-8a9b-3d06-02fb-622ecb449e82" name="CanBuild" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="80e781d1-fd68-212a-9099-8791ad55ed9f" name="AddUser" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="dc9d05c0-db88-716a-bbe0-aff585f7681d" name="ListID" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="e13e8546-b310-71c3-e068-1ecd18bfec8f" name="ListRegions" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="a8d03dce-530d-a255-9115-3b783c8a973c" name="DeleteRegion" storage="bin\release\unittests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</TestLinks>
</OrderedTest>

File diff suppressed because it is too large Load diff

View file

@ -1,176 +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>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{F3742F51-D7BF-4754-A68A-CD944D2A21FF}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>UnitTests</RootNamespace>
<AssemblyName>UnitTests</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>WebTest</TestProjectType>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>4.0</OldToolsVersion>
</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.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.VisualStudio.QualityTools.WebTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="Mono.Data.Sqlite">
<HintPath>..\SqlBins\Mono.Data.Sqlite.dll</HintPath>
</Reference>
<Reference Include="MySql.Data">
<HintPath>..\SqlBins\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="MySql.Web">
<HintPath>..\SqlBins\MySql.Web.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="TerrariaServer, Version=0.0.0.0, Culture=neutral, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<ExecutableExtension>.exe</ExecutableExtension>
<HintPath>..\TerrariaServerBins\TerrariaServer.exe</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
<Visible>False</Visible>
</CodeAnalysisDependentAssemblyPaths>
</ItemGroup>
<ItemGroup>
<Compile Include="BanManagerTest.cs" />
<Compile Include="GroupManagerTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ItemManagerTest.cs" />
<Compile Include="RegionManagerTest.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TShockAPI\TShockAPI.csproj">
<Project>{49606449-072B-4CF5-8088-AA49DA586694}</Project>
<Name>TShockAPI</Name>
</ProjectReference>
<ProjectReference Include="..\TShockRestTestPlugin\TShockRestTestPlugin.csproj">
<Project>{F2FEDAFB-58DE-4611-9168-A86112C346C7}</Project>
<Name>TShockRestTestPlugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="BanManagerTest.orderedtest">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="ItemManagerTest.orderedtest">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="GroupManagerTest.orderedtest">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="RegionManagerTest.orderedtest">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="UnitTests.licenseheader" />
<None Include="RestApiTests.webtest">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
</When>
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>xcopy .\..\..\..\SqlBins\sqlite3.dll . /Y</PostBuildEvent>
</PropertyGroup>
<!-- 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>

View file

@ -1,18 +0,0 @@
extensions: .cs
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2012 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/>.
*/

4
tshock_update.json Normal file
View file

@ -0,0 +1,4 @@
{
"version": "4.2.4.0128",
"changes": "TShock 4.2.4 for Terraria 1.2.4.1\nhttp://tshock.co/xf/index.php?threads/tshock-4-2-4-for-terraria-1-2-4-1.3398/"
}