Merge branch 'general-devel' into pscheck
This commit is contained in:
commit
3664b81c3f
13 changed files with 531 additions and 127 deletions
18
CHANGELOG.md
18
CHANGELOG.md
|
|
@ -13,12 +13,28 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
|
|||
* If there is no section called "Upcoming changes" below this line, please add one with `## Upcoming changes` as the first line, and then a bulleted item directly after with the first change.
|
||||
|
||||
## Upcoming changes
|
||||
* This could be you!
|
||||
* Fixed server crash from `/v2/players/list` & other parameterised REST endpoints. (@QuiCM, reported by @ATFGK)
|
||||
* Added handling to the PlayerChat hook event. (@QuiCM - Thanks for the suggestion @Arthri)
|
||||
* Changed the spawnboss command to support silent command specifiers. (@QuiCM, suggested by @nojomyth-dev)
|
||||
|
||||
## TShock 4.5.0.1
|
||||
* Fixed conversion from old to new ban system for MySQL hosted ban databases. (@DeathCradle, @ATFGK)
|
||||
* Fixed wrong identifier used for UUID bans. (@DeathCradle, @ATFGK)
|
||||
* Fixed conversion from sqlite bans due to locking issue. (@DeathCradle, @Kojirremer)
|
||||
|
||||
## TShock 4.5.0
|
||||
* Updated OTAPI and TSAPI to Terraria 1.4.2.1. (@Stealownz, @DeathCradle)
|
||||
* Updated TShock with preliminary protocol support for Terraria 1.4.2.1. (@Stealownz)
|
||||
|
||||
## TShock 4.4.0 (Pre-release 16)
|
||||
* Patched protocol issue. Thanks to Off (@tlworks) and @bartico6 for contributions, including packet captures, packet analysis, exploit proof-of-concept testing, patch testing, and detailed reproduction steps. (@hakusaro)
|
||||
* Disabled debug by default. (@hakusaro)
|
||||
* Changed "WinVer" field in `/serverinfo` to "Operating System". (@Terrabade)
|
||||
* Rewritten `/grow`, added every default tree type & changed the default help response. (@Nova4334)
|
||||
* Added a new permission: `tshock.world.growevil` to prevent players to grow evil biome trees, these trees spawn with evil biome blocks below them.
|
||||
* Introduced `/wallow` to disable or enable recieving whispers from other players. (@Nova4334)
|
||||
* Removed stoned & webbed from disabled status (@QuiCM)
|
||||
* Fix -forceupdate flag not forcing updates (@Quake)
|
||||
|
||||
## TShock 4.4.0 (Pre-release 15)
|
||||
* Overhauled Bans system. Bans are now based on 'identifiers'. (@QuiCM)
|
||||
|
|
|
|||
|
|
@ -585,6 +585,11 @@ namespace TShockAPI
|
|||
{
|
||||
HelpText = "Sends a PM to a player."
|
||||
});
|
||||
add(new Command(Permissions.whisper, Wallow, "wallow")
|
||||
{
|
||||
AllowServer = false,
|
||||
HelpText = "Toggles to either ignore or recieve whispers from other players."
|
||||
});
|
||||
add(new Command(Permissions.createdumps, CreateDumps, "dump-reference-data")
|
||||
{
|
||||
HelpText = "Creates a reference tables for Terraria data types and the TShock permission system in the server folder."
|
||||
|
|
@ -2421,6 +2426,8 @@ namespace TShockAPI
|
|||
return;
|
||||
}
|
||||
|
||||
string message = "{0} spawned {1} {2} time(s)";
|
||||
string spawnName;
|
||||
NPC npc = new NPC();
|
||||
switch (args.Parameters[0].ToLower())
|
||||
{
|
||||
|
|
@ -2433,87 +2440,89 @@ namespace TShockAPI
|
|||
npc.SetDefaults(i);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
}
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned all bosses {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "all bosses";
|
||||
break;
|
||||
|
||||
case "brain":
|
||||
case "brain of cthulhu":
|
||||
case "boc":
|
||||
npc.SetDefaults(266);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Brain of Cthulhu {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Brain of Cthulhu";
|
||||
break;
|
||||
|
||||
case "destroyer":
|
||||
npc.SetDefaults(134);
|
||||
TSPlayer.Server.SetTime(false, 0.0);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Destroyer {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Destroyer";
|
||||
break;
|
||||
case "duke":
|
||||
case "duke fishron":
|
||||
case "fishron":
|
||||
npc.SetDefaults(370);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Duke Fishron {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "Duke Fishron";
|
||||
break;
|
||||
case "eater":
|
||||
case "eater of worlds":
|
||||
case "eow":
|
||||
npc.SetDefaults(13);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Eater of Worlds {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Eater of Worlds";
|
||||
break;
|
||||
case "eye":
|
||||
case "eye of cthulhu":
|
||||
case "eoc":
|
||||
npc.SetDefaults(4);
|
||||
TSPlayer.Server.SetTime(false, 0.0);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Eye of Cthulhu {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Eye of Cthulhu";
|
||||
break;
|
||||
case "golem":
|
||||
npc.SetDefaults(245);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Golem {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Golem";
|
||||
break;
|
||||
case "king":
|
||||
case "king slime":
|
||||
case "ks":
|
||||
npc.SetDefaults(50);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned King Slime {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the King Slime";
|
||||
break;
|
||||
case "plantera":
|
||||
npc.SetDefaults(262);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Plantera {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "Plantera";
|
||||
break;
|
||||
case "prime":
|
||||
case "skeletron prime":
|
||||
npc.SetDefaults(127);
|
||||
TSPlayer.Server.SetTime(false, 0.0);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Skeletron Prime {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "Skeletron Prime";
|
||||
break;
|
||||
case "queen bee":
|
||||
case "qb":
|
||||
npc.SetDefaults(222);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Queen Bee {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Queen Bee";
|
||||
break;
|
||||
case "skeletron":
|
||||
npc.SetDefaults(35);
|
||||
TSPlayer.Server.SetTime(false, 0.0);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Skeletron {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "Skeletron";
|
||||
break;
|
||||
case "twins":
|
||||
TSPlayer.Server.SetTime(false, 0.0);
|
||||
npc.SetDefaults(125);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
npc.SetDefaults(126);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Twins {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Twins";
|
||||
break;
|
||||
case "wof":
|
||||
case "wall of flesh":
|
||||
if (Main.wofNPCIndex != -1)
|
||||
|
|
@ -2527,103 +2536,114 @@ namespace TShockAPI
|
|||
return;
|
||||
}
|
||||
NPC.SpawnWOF(new Vector2(args.Player.X, args.Player.Y));
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Wall of Flesh.", args.Player.Name);
|
||||
return;
|
||||
spawnName = "the Wall of Flesh";
|
||||
break;
|
||||
case "moon":
|
||||
case "moon lord":
|
||||
case "ml":
|
||||
npc.SetDefaults(398);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Moon Lord {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Moon Lord";
|
||||
break;
|
||||
case "empress":
|
||||
case "empress of light":
|
||||
case "eol":
|
||||
npc.SetDefaults(636);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Empress of Light {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Empress of Light";
|
||||
break;
|
||||
case "queen slime":
|
||||
case "qs":
|
||||
npc.SetDefaults(657);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Queen Slime {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Queen Slime";
|
||||
break;
|
||||
case "lunatic":
|
||||
case "lunatic cultist":
|
||||
case "cultist":
|
||||
case "lc":
|
||||
npc.SetDefaults(439);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Lunatic Cultist {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Lunatic Cultist";
|
||||
break;
|
||||
case "betsy":
|
||||
npc.SetDefaults(551);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Betsy {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "Betsy";
|
||||
break;
|
||||
case "flying dutchman":
|
||||
case "flying":
|
||||
case "dutchman":
|
||||
npc.SetDefaults(491);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Flying Dutchman {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Flying Dutchman";
|
||||
break;
|
||||
case "mourning wood":
|
||||
npc.SetDefaults(325);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Mourning Wood {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "Mourning Wood";
|
||||
break;
|
||||
case "pumpking":
|
||||
npc.SetDefaults(327);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Pumpking {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Pumpking";
|
||||
break;
|
||||
case "everscream":
|
||||
npc.SetDefaults(344);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Everscream {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "Everscream";
|
||||
break;
|
||||
case "santa-nk1":
|
||||
case "santa":
|
||||
npc.SetDefaults(346);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned Santa-NK1 {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "Santa-NK1";
|
||||
break;
|
||||
case "ice queen":
|
||||
npc.SetDefaults(345);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Ice Queen {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "the Ice Queen";
|
||||
break;
|
||||
case "martian saucer":
|
||||
npc.SetDefaults(392);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Martian Saucer {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "a Martian Saucer";
|
||||
break;
|
||||
case "solar pillar":
|
||||
npc.SetDefaults(517);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Solar Pillar {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "a Solar Pillar";
|
||||
break;
|
||||
case "nebula pillar":
|
||||
npc.SetDefaults(507);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Nebula Pillar {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "a Nebula Pillar";
|
||||
break;
|
||||
case "vortex pillar":
|
||||
npc.SetDefaults(422);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Vortex Pillar {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "a Vortex Pillar";
|
||||
break;
|
||||
case "stardust pillar":
|
||||
npc.SetDefaults(493);
|
||||
TSPlayer.Server.SpawnNPC(npc.type, npc.FullName, amount, args.Player.TileX, args.Player.TileY);
|
||||
TSPlayer.All.SendSuccessMessage("{0} has spawned the Stardust Pillar {1} time(s).", args.Player.Name, amount);
|
||||
return;
|
||||
spawnName = "a Stardust Pillar";
|
||||
break;
|
||||
default:
|
||||
args.Player.SendErrorMessage("Invalid boss type!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Silent)
|
||||
{
|
||||
//"You spawned <spawn name> <x> time(s)"
|
||||
args.Player.SendSuccessMessage(message, "You", spawnName, amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
//"<player> spawned <spawn name> <x> time(s)"
|
||||
TSPlayer.All.SendSuccessMessage(message, args.Player.Name, spawnName, amount);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SpawnMob(CommandArgs args)
|
||||
|
|
@ -5283,14 +5303,15 @@ namespace TShockAPI
|
|||
args.Player.SendFileTextAsMessage(FileTools.RulesPath);
|
||||
}
|
||||
|
||||
private static void Whisper(CommandArgs args)
|
||||
public static bool[] WDisabled { get; set; } = new bool[256];
|
||||
|
||||
public static void Whisper(CommandArgs args)
|
||||
{
|
||||
if (args.Parameters.Count < 2)
|
||||
{
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}whisper <player> <text>", Specifier);
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper usage: /whisper <player> <text>");
|
||||
return;
|
||||
}
|
||||
|
||||
var players = TSPlayer.FindByNameOrID(args.Parameters[0]);
|
||||
if (players.Count == 0)
|
||||
{
|
||||
|
|
@ -5308,6 +5329,11 @@ namespace TShockAPI
|
|||
{
|
||||
var plr = players[0];
|
||||
var msg = string.Join(" ", args.Parameters.ToArray(), 1, args.Parameters.Count - 1);
|
||||
if (WDisabled[players[0].Index])
|
||||
{
|
||||
args.Player.SendErrorMessage("This player has disabled people from sending whispers!");
|
||||
return;
|
||||
}
|
||||
plr.SendMessage(String.Format("<From {0}> {1}", args.Player.Name, msg), Color.MediumPurple);
|
||||
args.Player.SendMessage(String.Format("<To {0}> {1}", plr.Name, msg), Color.MediumPurple);
|
||||
plr.LastWhisper = args.Player;
|
||||
|
|
@ -5315,6 +5341,19 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
public static void Wallow(CommandArgs args)
|
||||
{
|
||||
int index = args.Player.Index;
|
||||
if (WDisabled[index])
|
||||
{
|
||||
args.Player.SendSuccessMessage("You will now recieve whispers from other players!");
|
||||
WDisabled[index] = !WDisabled[index];
|
||||
return;
|
||||
}
|
||||
WDisabled[index] = !WDisabled[index];
|
||||
args.Player.SendSuccessMessage("You will now not recieve whispers from other players, type '/wallow' to recieve them again!");
|
||||
}
|
||||
|
||||
private static void Reply(CommandArgs args)
|
||||
{
|
||||
if (args.Player.mute)
|
||||
|
|
@ -5410,7 +5449,7 @@ namespace TShockAPI
|
|||
type = 170;
|
||||
}
|
||||
var ply = players[0];
|
||||
int p = Projectile.NewProjectile(ply.TPlayer.position.X, ply.TPlayer.position.Y - 64f, 0f, -8f, type, 0, (float)0);
|
||||
int p = Projectile.NewProjectile(Projectile.GetNoneSource(), ply.TPlayer.position.X, ply.TPlayer.position.Y - 64f, 0f, -8f, type, 0, (float)0);
|
||||
Main.projectile[p].Kill();
|
||||
args.Player.SendSuccessMessage("Launched Firework on {0}.", ply.Name);
|
||||
}
|
||||
|
|
@ -6010,13 +6049,11 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
private static void Grow(CommandArgs args)
|
||||
public static void Grow(CommandArgs args)
|
||||
{
|
||||
if (args.Parameters.Count != 1)
|
||||
{
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}grow <tree/epictree/mushroom/cactus/herb>", Specifier);
|
||||
return;
|
||||
}
|
||||
bool growevilAmb = args.Player.HasPermission(Permissions.growevil);
|
||||
string subcmd = args.Parameters.Count == 0 ? "help" : args.Parameters[0].ToLower();
|
||||
|
||||
var name = "Fail";
|
||||
var x = args.Player.TileX;
|
||||
var y = args.Player.TileY + 3;
|
||||
|
|
@ -6027,10 +6064,37 @@ namespace TShockAPI
|
|||
return;
|
||||
}
|
||||
|
||||
switch (args.Parameters[0].ToLower())
|
||||
switch (subcmd)
|
||||
{
|
||||
case "tree":
|
||||
for (int i = x - 1; i < x + 2; i++)
|
||||
case "help":
|
||||
{
|
||||
if (!PaginationTools.TryParsePageNumber(args.Parameters, 1, args.Player, out int pageNumber))
|
||||
return;
|
||||
|
||||
var lines = new List<string>
|
||||
{
|
||||
"- Default trees :",
|
||||
" 'basic', 'sakura', 'willow', 'boreal', 'mahogany', 'ebonwood', 'shadewood', 'pearlwood'.",
|
||||
"- Palm trees :",
|
||||
" 'palm', 'corruptpalm', 'crimsonpalm', 'hallowpalm'.",
|
||||
"- Gem trees :",
|
||||
" 'topaz', 'amethyst', 'sapphire', 'emerald', 'ruby', 'diamond', 'amber'.",
|
||||
"- Misc :",
|
||||
" 'cactus', 'herb', 'mushroom'."
|
||||
};
|
||||
|
||||
PaginationTools.SendPage(args.Player, pageNumber, lines,
|
||||
new PaginationTools.Settings
|
||||
{
|
||||
HeaderFormat = "Trees types & misc available to use. ({0}/{1}):",
|
||||
FooterFormat = "Type {0}grow help {{0}} for more sub-commands.".SFormat(Commands.Specifier)
|
||||
}
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case "basic":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 2;
|
||||
|
|
@ -6038,37 +6102,279 @@ namespace TShockAPI
|
|||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowTree(x, y);
|
||||
name = "Tree";
|
||||
name = "Basic Tree";
|
||||
break;
|
||||
case "epictree":
|
||||
for (int i = x - 1; i < x + 2; i++)
|
||||
|
||||
case "boreal":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 147;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowTree(x, y);
|
||||
name = "Boreal Tree";
|
||||
break;
|
||||
|
||||
case "mahogany":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 60;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowTree(x, y);
|
||||
name = "Rich Mahogany";
|
||||
break;
|
||||
|
||||
case "sakura":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 2;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
Main.tile[x, y - 1].liquid = 0;
|
||||
Main.tile[x, y - 1].active(true);
|
||||
WorldGen.GrowEpicTree(x, y);
|
||||
name = "Epic Tree";
|
||||
WorldGen.TryGrowingTreeByType(596, x, y);
|
||||
name = "Sakura Tree";
|
||||
break;
|
||||
case "mushroom":
|
||||
for (int i = x - 1; i < x + 2; i++)
|
||||
|
||||
case "willow":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 70;
|
||||
Main.tile[i, y].type = 2;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowShroom(x, y);
|
||||
name = "Mushroom";
|
||||
WorldGen.TryGrowingTreeByType(616, x, y);
|
||||
name = "Willow Tree";
|
||||
break;
|
||||
|
||||
case "shadewood":
|
||||
if (growevilAmb)
|
||||
{
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 199;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowTree(x, y);
|
||||
name = "Shadewood tree";
|
||||
}
|
||||
else args.Player.SendErrorMessage("You do not have permission to grow this tree type");
|
||||
break;
|
||||
|
||||
case "ebonwood":
|
||||
if (growevilAmb)
|
||||
{
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 23;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowTree(x, y);
|
||||
name = "Ebonwood Tree";
|
||||
}
|
||||
else args.Player.SendErrorMessage("You do not have permission to grow this tree type");
|
||||
break;
|
||||
|
||||
case "pearlwood":
|
||||
if (growevilAmb)
|
||||
{
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 109;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowTree(x, y);
|
||||
name = "Pearlwood Tree";
|
||||
}
|
||||
else args.Player.SendErrorMessage("You do not have permission to grow this tree type");
|
||||
break;
|
||||
|
||||
case "palm":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 53;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y + 1].active(true);
|
||||
Main.tile[i, y + 1].type = 397;
|
||||
Main.tile[i, y + 1].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowPalmTree(x, y);
|
||||
name = "Desert Palm";
|
||||
break;
|
||||
|
||||
case "hallowpalm":
|
||||
if (growevilAmb)
|
||||
{
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 116;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y + 1].active(true);
|
||||
Main.tile[i, y + 1].type = 402;
|
||||
Main.tile[i, y + 1].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowPalmTree(x, y);
|
||||
name = "Hallow Palm";
|
||||
}
|
||||
else args.Player.SendErrorMessage("You do not have permission to grow this tree type");
|
||||
break;
|
||||
|
||||
case "crimsonpalm":
|
||||
if (growevilAmb)
|
||||
{
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 234;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y + 1].active(true);
|
||||
Main.tile[i, y + 1].type = 399;
|
||||
Main.tile[i, y + 1].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowPalmTree(x, y);
|
||||
name = "Crimson Palm";
|
||||
}
|
||||
else args.Player.SendErrorMessage("You do not have permission to grow this tree type");
|
||||
break;
|
||||
|
||||
case "corruptpalm":
|
||||
if (growevilAmb)
|
||||
{
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 112;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y + 1].active(true);
|
||||
Main.tile[i, y + 1].type = 398;
|
||||
Main.tile[i, y + 1].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowPalmTree(x, y);
|
||||
name = "Corruption Palm";
|
||||
}
|
||||
else args.Player.SendErrorMessage("You do not have permission to grow this tree type");
|
||||
break;
|
||||
|
||||
case "topaz":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 1;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.TryGrowingTreeByType(583, x, y);
|
||||
name = "Topaz Gemtree";
|
||||
break;
|
||||
|
||||
case "amethyst":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 1;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.TryGrowingTreeByType(584, x, y);
|
||||
name = "Amethust Gemtree";
|
||||
break;
|
||||
|
||||
case "sapphire":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 1;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.TryGrowingTreeByType(585, x, y);
|
||||
name = "Sapphire Gemtree";
|
||||
break;
|
||||
|
||||
case "emerald":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 1;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.TryGrowingTreeByType(586, x, y);
|
||||
name = "Emerald Gemtree";
|
||||
break;
|
||||
|
||||
case "ruby":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 1;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.TryGrowingTreeByType(587, x, y);
|
||||
name = "Ruby Gemtree";
|
||||
break;
|
||||
|
||||
case "diamond":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 1;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.TryGrowingTreeByType(588, x, y);
|
||||
name = "Diamond Gemtree";
|
||||
break;
|
||||
|
||||
case "amber":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 1;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.TryGrowingTreeByType(589, x, y);
|
||||
name = "Amber Gemtree";
|
||||
break;
|
||||
|
||||
case "cactus":
|
||||
Main.tile[x, y].type = 53;
|
||||
WorldGen.GrowCactus(x, y);
|
||||
name = "Cactus";
|
||||
break;
|
||||
|
||||
case "herb":
|
||||
Main.tile[x, y].active(true);
|
||||
Main.tile[x, y].frameX = 36;
|
||||
|
|
@ -6076,12 +6382,28 @@ namespace TShockAPI
|
|||
WorldGen.GrowAlch(x, y);
|
||||
name = "Herb";
|
||||
break;
|
||||
|
||||
case "mushroom":
|
||||
for (int i = x - 2; i < x + 3; i++)
|
||||
{
|
||||
Main.tile[i, y].active(true);
|
||||
Main.tile[i, y].type = 70;
|
||||
Main.tile[i, y].wall = 0;
|
||||
}
|
||||
Main.tile[x, y - 1].wall = 0;
|
||||
WorldGen.GrowShroom(x, y);
|
||||
name = "Glowing Mushroom Tree";
|
||||
break;
|
||||
|
||||
default:
|
||||
args.Player.SendErrorMessage("Unknown plant!");
|
||||
return;
|
||||
}
|
||||
args.Player.SendTileSquare(x, y);
|
||||
args.Player.SendSuccessMessage("Tried to grow a " + name + ".");
|
||||
if (args.Parameters.Count == 1)
|
||||
{
|
||||
args.Player.SendTileSquare(x - 2, y - 20, 25);
|
||||
args.Player.SendSuccessMessage("Tried to grow a " + name + ".");
|
||||
}
|
||||
}
|
||||
|
||||
private static void ToggleGodMode(CommandArgs args)
|
||||
|
|
|
|||
|
|
@ -37,18 +37,7 @@ namespace TShockAPI.DB
|
|||
/// <summary>
|
||||
/// Readonly dictionary of Bans, keyed on ban ticket number.
|
||||
/// </summary>
|
||||
public ReadOnlyDictionary<int, Ban> Bans
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_bans == null)
|
||||
{
|
||||
_bans = RetrieveAllBans().ToDictionary(b => b.TicketNumber);
|
||||
}
|
||||
|
||||
return new ReadOnlyDictionary<int, Ban>(_bans);
|
||||
}
|
||||
}
|
||||
public ReadOnlyDictionary<int, Ban> Bans => new ReadOnlyDictionary<int, Ban>(_bans);
|
||||
|
||||
/// <summary>
|
||||
/// Event invoked when a ban is checked for validity
|
||||
|
|
@ -93,12 +82,24 @@ namespace TShockAPI.DB
|
|||
throw new Exception("Could not find a database library (probably Sqlite3.dll)");
|
||||
}
|
||||
|
||||
EnsureBansCollection();
|
||||
TryConvertBans();
|
||||
|
||||
OnBanValidate += BanValidateCheck;
|
||||
OnBanPreAdd += BanAddedCheck;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the <see cref="_bans"/> collection is ready to use.
|
||||
/// </summary>
|
||||
private void EnsureBansCollection()
|
||||
{
|
||||
if (_bans == null)
|
||||
{
|
||||
_bans = RetrieveAllBans().ToDictionary(b => b.TicketNumber);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts bans from the old ban system to the new.
|
||||
/// </summary>
|
||||
|
|
@ -107,7 +108,7 @@ namespace TShockAPI.DB
|
|||
int res;
|
||||
if (database.GetSqlType() == SqlType.Mysql)
|
||||
{
|
||||
res = database.QueryScalar<int>("SELECT COUNT(name) FROM information_schema.tables WHERE table_schema = @0 and table_name = 'Bans'", TShock.Config.Settings.MySqlDbName);
|
||||
res = database.QueryScalar<int>("SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema = @0 and table_name = 'Bans'", TShock.Config.Settings.MySqlDbName);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -116,6 +117,7 @@ namespace TShockAPI.DB
|
|||
|
||||
if (res != 0)
|
||||
{
|
||||
var bans = new List<BanPreAddEventArgs>();
|
||||
using (var reader = database.QueryReader("SELECT * FROM Bans"))
|
||||
{
|
||||
while (reader.Read())
|
||||
|
|
@ -140,22 +142,46 @@ namespace TShockAPI.DB
|
|||
|
||||
if (!string.IsNullOrWhiteSpace(ip))
|
||||
{
|
||||
InsertBan($"{Identifier.IP}{ip}", reason, banningUser, start, end);
|
||||
bans.Add(new BanPreAddEventArgs
|
||||
{
|
||||
Identifier = $"{Identifier.IP}{ip}",
|
||||
Reason = reason,
|
||||
BanningUser = banningUser,
|
||||
BanDateTime = start,
|
||||
ExpirationDateTime = end
|
||||
});
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(account))
|
||||
{
|
||||
InsertBan($"{Identifier.Account}{account}", reason, banningUser, start, end);
|
||||
bans.Add(new BanPreAddEventArgs
|
||||
{
|
||||
Identifier = $"{Identifier.Account}{account}",
|
||||
Reason = reason,
|
||||
BanningUser = banningUser,
|
||||
BanDateTime = start,
|
||||
ExpirationDateTime = end
|
||||
});
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(uuid))
|
||||
{
|
||||
InsertBan($"{Identifier.UUID}{uuid}", reason, banningUser, start, end);
|
||||
bans.Add(new BanPreAddEventArgs
|
||||
{
|
||||
Identifier = $"{Identifier.UUID}{uuid}",
|
||||
Reason = reason,
|
||||
BanningUser = banningUser,
|
||||
BanDateTime = start,
|
||||
ExpirationDateTime = end
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
database.Query("DROP TABLE 'Bans'");
|
||||
foreach (var ban in bans)
|
||||
InsertBan(ban);
|
||||
|
||||
database.Query("DROP TABLE Bans");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +258,7 @@ namespace TShockAPI.DB
|
|||
args.Message = args.Valid ? null : "a current ban for this identifier already exists.";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new ban for the given identifier. Returns a Ban object if the ban was added, else null
|
||||
/// </summary>
|
||||
|
|
@ -252,7 +278,16 @@ namespace TShockAPI.DB
|
|||
BanDateTime = fromDate,
|
||||
ExpirationDateTime = toDate
|
||||
};
|
||||
return InsertBan(args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new ban for the given data. Returns a Ban object if the ban was added, else null
|
||||
/// </summary>
|
||||
/// <param name="args">A predefined instance of <see cref="BanPreAddEventArgs"/></param>
|
||||
/// <returns></returns>
|
||||
public AddBanResult InsertBan(BanPreAddEventArgs args)
|
||||
{
|
||||
OnBanPreAdd?.Invoke(this, args);
|
||||
|
||||
if (!args.Valid)
|
||||
|
|
@ -265,21 +300,21 @@ namespace TShockAPI.DB
|
|||
|
||||
if (database.GetSqlType() == SqlType.Mysql)
|
||||
{
|
||||
query += "SELECT CAST(LAST_INSERT_ID() as INT);";
|
||||
query += "SELECT LAST_INSERT_ID();";
|
||||
}
|
||||
else
|
||||
{
|
||||
query += "SELECT CAST(last_insert_rowid() as INT);";
|
||||
}
|
||||
|
||||
int ticketId = database.QueryScalar<int>(query, identifier, reason, banningUser, fromDate.Ticks, toDate.Ticks);
|
||||
int ticketId = database.QueryScalar<int>(query, args.Identifier, args.Reason, args.BanningUser, args.BanDateTime.Ticks, args.ExpirationDateTime.Ticks);
|
||||
|
||||
if (ticketId == 0)
|
||||
{
|
||||
return new AddBanResult { Message = "Database insert failed." };
|
||||
}
|
||||
|
||||
Ban b = new Ban(ticketId, identifier, reason, banningUser, fromDate, toDate);
|
||||
Ban b = new Ban(ticketId, args.Identifier, args.Reason, args.BanningUser, args.BanDateTime, args.ExpirationDateTime);
|
||||
_bans.Add(ticketId, b);
|
||||
|
||||
OnBanPostAdd?.Invoke(this, new BanEventArgs { Ban = b });
|
||||
|
|
|
|||
|
|
@ -2704,6 +2704,7 @@ namespace TShockAPI
|
|||
float[] ai = new float[Projectile.maxAI];
|
||||
for (int i = 0; i < Projectile.maxAI; ++i)
|
||||
ai[i] = !bits.AI[i] ? 0.0f : args.Data.ReadSingle();
|
||||
ushort bannerId = bits.HasBannerIdToRespondTo ? args.Data.ReadUInt16() : (ushort)0;
|
||||
short dmg = bits.HasDamage ? args.Data.ReadInt16() : (short)0;
|
||||
float knockback = bits.HasKnockback ? args.Data.ReadSingle() : 0.0f;
|
||||
short origDmg = bits.HasOriginalDamage ? args.Data.ReadInt16() : (short)0;
|
||||
|
|
|
|||
|
|
@ -449,14 +449,16 @@ namespace TShockAPI.Hooks
|
|||
/// <param name="ply">The player firing the event.</param>
|
||||
/// <param name="rawtext">The raw chat text sent by the player.</param>
|
||||
/// <param name="tshockText">The chat text after being formatted.</param>
|
||||
public static void OnPlayerChat(TSPlayer ply, string rawtext, ref string tshockText)
|
||||
public static bool OnPlayerChat(TSPlayer ply, string rawtext, ref string tshockText)
|
||||
{
|
||||
if (PlayerChat == null)
|
||||
return;
|
||||
return false;
|
||||
|
||||
var args = new PlayerChatEventArgs {Player = ply, RawText = rawtext, TShockFormattedText = tshockText};
|
||||
PlayerChat(args);
|
||||
tshockText = args.TShockFormattedText;
|
||||
|
||||
return args.Handled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ namespace TShockAPI.Models.Projectiles
|
|||
}
|
||||
}
|
||||
|
||||
public bool HasBannerIdToRespondTo
|
||||
{
|
||||
get => bitsbyte[3];
|
||||
set => bitsbyte[3] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets the Damage flag on the backing field
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -319,6 +319,9 @@ namespace TShockAPI
|
|||
[Description("User can grow plants.")]
|
||||
public static readonly string grow = "tshock.world.grow";
|
||||
|
||||
[Description("User can grow evil biome plants.")]
|
||||
public static readonly string growevil = "tshock.world.growevil";
|
||||
|
||||
[Description("User can change hardmode state.")]
|
||||
public static readonly string hardmode = "tshock.world.hardmode";
|
||||
|
||||
|
|
|
|||
|
|
@ -53,5 +53,5 @@ using System.Runtime.InteropServices;
|
|||
// Also, be sure to release on github with the exact assembly version tag as below
|
||||
// so that the update manager works correctly (via the Github releases api and mimic)
|
||||
|
||||
[assembly: AssemblyVersion("4.4.0")]
|
||||
[assembly: AssemblyFileVersion("4.4.0")]
|
||||
[assembly: AssemblyVersion("4.5.0.1")]
|
||||
[assembly: AssemblyFileVersion("4.5.0.1")]
|
||||
|
|
|
|||
|
|
@ -94,17 +94,17 @@ namespace Rests
|
|||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator<EscapedParameter> GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
foreach (IParameter param in _collection)
|
||||
{
|
||||
yield return new EscapedParameter(param);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return this.GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1557,8 +1557,6 @@ namespace TShockAPI
|
|||
public virtual void Disable(string reason = "", DisableFlags flags = DisableFlags.WriteToLog)
|
||||
{
|
||||
LastThreat = DateTime.UtcNow;
|
||||
SetBuff(BuffID.Frozen, 330, true);
|
||||
SetBuff(BuffID.Stoned, 330, true);
|
||||
SetBuff(BuffID.Webbed, 330, true);
|
||||
|
||||
if (ActiveChest != -1)
|
||||
|
|
@ -1639,7 +1637,7 @@ namespace TShockAPI
|
|||
if (force)
|
||||
{
|
||||
TShock.Bans.InsertBan($"{Identifier.IP}{IP}", reason, adminUserName, DateTime.UtcNow, DateTime.MaxValue);
|
||||
TShock.Bans.InsertBan($"{Identifier.IP}{UUID}", reason, adminUserName, DateTime.UtcNow, DateTime.MaxValue);
|
||||
TShock.Bans.InsertBan($"{Identifier.UUID}{UUID}", reason, adminUserName, DateTime.UtcNow, DateTime.MaxValue);
|
||||
if (Account != null)
|
||||
{
|
||||
TShock.Bans.InsertBan($"{Identifier.Account}{Account.Name}", reason, adminUserName, DateTime.UtcNow, DateTime.MaxValue);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ namespace TShockAPI
|
|||
/// <summary>VersionNum - The version number the TerrariaAPI will return back to the API. We just use the Assembly info.</summary>
|
||||
public static readonly Version VersionNum = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
/// <summary>VersionCodename - The version codename is displayed when the server starts. Inspired by software codenames conventions.</summary>
|
||||
public static readonly string VersionCodename = "Now with less velocity, thanks to Off + Quake. Usual thanks to Chris/White <3";
|
||||
public static readonly string VersionCodename = "Stealownz + DeathCradle edition";
|
||||
|
||||
/// <summary>SavePath - This is the path TShock saves its data in. This path is relative to the TerrariaServer.exe (not in ServerPlugins).</summary>
|
||||
public static string SavePath = "tshock";
|
||||
|
|
@ -890,6 +890,13 @@ namespace TShockAPI
|
|||
/// <param name="args">args - EventArgs args</param>
|
||||
private void OnUpdate(EventArgs args)
|
||||
{
|
||||
// This forces Terraria to actually continue to update
|
||||
// even if there are no clients connected
|
||||
if (ServerApi.ForceUpdate)
|
||||
{
|
||||
Netplay.HasClients = true;
|
||||
}
|
||||
|
||||
if (Backups.IsBackupTime)
|
||||
Backups.Backup();
|
||||
//call these every second, not every update
|
||||
|
|
@ -1323,9 +1330,17 @@ namespace TShockAPI
|
|||
{
|
||||
text = String.Format(Config.Settings.ChatFormat, tsplr.Group.Name, tsplr.Group.Prefix, tsplr.Name, tsplr.Group.Suffix,
|
||||
args.Text);
|
||||
Hooks.PlayerHooks.OnPlayerChat(tsplr, args.Text, ref text);
|
||||
Utils.Broadcast(text, tsplr.Group.R, tsplr.Group.G, tsplr.Group.B);
|
||||
|
||||
//Invoke the PlayerChat hook. If this hook event is handled then we need to prevent sending the chat message
|
||||
bool cancelChat = PlayerHooks.OnPlayerChat(tsplr, args.Text, ref text);
|
||||
args.Handled = true;
|
||||
|
||||
if (cancelChat)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Utils.Broadcast(text, tsplr.Group.R, tsplr.Group.G, tsplr.Group.B);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1337,7 +1352,13 @@ namespace TShockAPI
|
|||
|
||||
//Give that poor player their name back :'c
|
||||
ply.name = name;
|
||||
PlayerHooks.OnPlayerChat(tsplr, args.Text, ref text);
|
||||
|
||||
bool cancelChat = PlayerHooks.OnPlayerChat(tsplr, args.Text, ref text);
|
||||
if (cancelChat)
|
||||
{
|
||||
args.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
//This netpacket is used to send chat text from the server to clients, in this case on behalf of a client
|
||||
Terraria.Net.NetPacket packet = Terraria.GameContent.NetModules.NetTextModule.SerializeServerMessage(
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="OTAPI=">
|
||||
<Reference Include="OTAPI">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath Condition="Exists('..\TerrariaServerAPI\TerrariaServerAPI\bin\$(ConfigurationName)\OTAPI.dll')">..\TerrariaServerAPI\TerrariaServerAPI\bin\$(ConfigurationName)\OTAPI.dll</HintPath>
|
||||
</Reference>
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 2a0b338a3c4fb82e05946082ab31def771b783fb
|
||||
Subproject commit e0302513009220a8d92ba12c867a401e7731d28a
|
||||
Loading…
Add table
Add a link
Reference in a new issue