Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions TShockAPI/Bouncer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2019 Pryaxis & TShock Contributors

Expand Down Expand Up @@ -2676,7 +2676,7 @@ internal void OnPlaceItemFrame(object sender, GetDataHandlers.PlaceItemFrameEven

if (!args.Player.HasBuildPermission(args.X, args.Y))
{
int num = Item.NewItem(null, (args.X * 16) + 8, (args.Y * 16) + 8, args.Player.TPlayer.width, args.Player.TPlayer.height, args.ItemID, args.Stack, noBroadcast: true, args.Prefix, noGrabDelay: true);
int num = Item.NewItem(null, (args.X * 16) + 8, (args.Y * 16) + 8, args.Player.TPlayer.width, args.Player.TPlayer.height, args.ItemID, args.Stack, noBroadcast: true, args.Prefix, Terraria.NewItemOwnership.None);
Main.item[num].playerIndexTheItemIsReservedFor = args.Player.Index;
NetMessage.SendData((int)PacketTypes.ItemDrop, args.Player.Index, -1, NetworkText.Empty, num, 1f);
NetMessage.SendData((int)PacketTypes.ItemOwner, args.Player.Index, -1, NetworkText.Empty, num);
Expand Down
2 changes: 1 addition & 1 deletion TShockAPI/Commands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2537,7 +2537,7 @@ private static void Rain(CommandArgs args)
}
else
{
Main.StartRain(garenteeCoinRain: true);
Main.StartRain(guaranteeCoinRain: true);
TSPlayer.All.SendData(PacketTypes.WorldInfo);
TSPlayer.All.SendInfoMessage(GetString("{0} caused it to coin rain.", args.Player.Name));
}
Expand Down
67 changes: 51 additions & 16 deletions TShockAPI/GetDataHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3260,8 +3260,21 @@ private static bool HandleItemDrop(GetDataHandlerArgs args)
var vel = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle());
var stacks = args.Data.ReadInt16();
var prefix = args.Data.ReadInt8();
var noDelay = args.Data.ReadInt8() == 1;
BitsByte flags = args.Data.ReadInt8();
// Bits 0-1: Terraria.NewItemOwnership (0 None, 1 ReserveForLocalPlayer,
// 2 GrabDelayForLocalPlayer, 3 GrabDelayForAllPlayers)
var ownership = (byte)((flags[0] ? 1 : 0) | (flags[1] ? 2 : 0));
var noDelay = ownership <= 1;
var type = args.Data.ReadInt16();
if (flags[2])
{
args.Data.ReadBoolean(); // shimmered
args.Data.ReadSingle(); // shimmerTime
}
if (flags[3])
{
args.Data.ReadInt8(); // enemyGrabDelayTime
}

if (OnItemDrop(args.Player, args.Data, id, pos, vel, stacks, prefix, noDelay, type))
return true;
Expand All @@ -3271,6 +3284,8 @@ private static bool HandleItemDrop(GetDataHandlerArgs args)

private static bool HandleItemOwner(GetDataHandlerArgs args)
{
// As of 1.4.5.7 this packet is server->client only and vanilla ignores it inbound;
// clients no longer send it (including the old slot-400 SSC echo).
var id = args.Data.ReadInt16();
var owner = args.Data.ReadInt8();

Expand All @@ -3295,10 +3310,14 @@ private static bool HandleNpcItemStrike(GetDataHandlerArgs args)

private static bool HandleProjectileNew(GetDataHandlerArgs args)
{
short ident = args.Data.ReadInt16();
// 1.4.5.7: a packed ProjectileKey (spawner:8 | index:10 | generation:14) replaces
// the old identity short + owner byte; the trailing bit7 UUID short is gone.
uint key = (uint)args.Data.ReadInt32();
byte owner = (byte)(key & 255u);
short ident = (short)(key >> 8 & 1023u);
int generation = (int)(key >> 18 & 16383u);
Vector2 pos = args.Data.ReadVector2();
Vector2 vel = args.Data.ReadVector2();
byte owner = args.Data.ReadInt8();
short type = args.Data.ReadInt16();
BitsByte bitsByte = (BitsByte)args.Data.ReadByte();
BitsByte bitsByte2 = (BitsByte)(bitsByte[2] ? args.Data.ReadByte() : 0);
Expand All @@ -3310,11 +3329,17 @@ private static bool HandleProjectileNew(GetDataHandlerArgs args)
short dmg = (short)(bitsByte[4] ? args.Data.ReadInt16() : 0);
float knockback = bitsByte[5] ? args.Data.ReadSingle() : 0f;
short origDmg = (short)(bitsByte[6] ? args.Data.ReadInt16() : 0);
short projUUID = (short)(bitsByte[7] ? args.Data.ReadInt16() : -1);
if (projUUID >= 1000) projUUID = -1;
ai[2] = (bitsByte2[0] ? args.Data.ReadSingle() : 0f);

var index = TShock.Utils.SearchProjectile(ident, owner);
// Vanilla rejects keys whose spawner isn't the sending client; mirror that here.
if (owner != args.Player.Index)
{
TShock.Log.ConsoleDebug(GetString("GetDataHandlers / HandleProjectileNew rejected key spawner mismatch {0}", args.Player.Name));
return true;
}

// The key's index is the projectile slot; the old identity scan no longer applies.
var index = (int)ident;

// Cattiva's dig ability can bypass build permissions via vanilla exploit in Terraria v1.4.5
// Block ai[0] == 3 (dig state)
Expand Down Expand Up @@ -3344,12 +3369,19 @@ private static bool HandleProjectileNew(GetDataHandlerArgs args)

private static bool HandleNpcStrike(GetDataHandlerArgs args)
{
var id = args.Data.ReadInt16();
// 1.4.5.7: slot shrank to a byte and gained a generation byte (slot-reuse guard).
// Vanilla drops strikes whose generation doesn't match and acks each one with
// packet 162 (DamageNPCAck).
short id = args.Data.ReadInt8();
var generation = args.Data.ReadInt8();
var dmg = args.Data.ReadInt16();
var knockback = args.Data.ReadSingle();
var direction = (byte)(args.Data.ReadInt8() - 1);
var crit = args.Data.ReadInt8();

if (id >= Main.npc.Length)
return true;

if (OnNPCStrike(args.Player, args.Data, id, direction, dmg, knockback, crit))
return true;

Expand Down Expand Up @@ -3393,10 +3425,15 @@ private static bool HandleNpcStrike(GetDataHandlerArgs args)

private static bool HandleProjectileKill(GetDataHandlerArgs args)
{
var ident = args.Data.ReadInt16();
var owner = args.Data.ReadInt8();
owner = (byte)args.Player.Index;
var index = TShock.Utils.SearchProjectile(ident, owner);
// 1.4.5.7: i32 ProjectileKey + kill-effect position replace the old identity/owner pair.
uint key = (uint)args.Data.ReadInt32();
var killPos = args.Data.ReadVector2();
var ident = (short)(key >> 8 & 1023u);
var owner = (byte)args.Player.Index;
var index = (int)ident;

if (index >= Main.projectile.Length)
return true;

if (OnProjectileKill(args.Player, args.Data, ident, owner, index))
{
Expand Down Expand Up @@ -4280,8 +4317,8 @@ private static bool HandleHealOther(GetDataHandlerArgs args)

private static bool HandleCatchNpc(GetDataHandlerArgs args)
{
// 1.4.5.7 removed the trailing "who" byte; the server uses the sender's index.
var npcID = args.Data.ReadInt16();
var who = args.Data.ReadByte();

if (Main.npc[npcID]?.catchItem == 0)
{
Expand Down Expand Up @@ -5193,18 +5230,16 @@ public enum NetModuleType
Ping,
Ambience,
Bestiary,
CreativeUnlocks,
CreativePowers,
CreativeUnlocksPlayerReport,
TeleportPylon,
Particles,
CreativePowerPermissions,
Banners,
CraftingRequests,
TagEffectState,
LeashedEntity,
UnbreakableWallScan,
[Obsolete("Removed in 1.4.5")]
CreativeUnlocks
UnbreakableWallScan
}

public enum CreativePowerTypes
Expand Down
13 changes: 7 additions & 6 deletions TShockAPI/Net/ProjectileRemoveMsg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,21 @@ public override PacketTypes ID

public short Index { get; set; }
public byte Owner { get; set; }
/// <summary>Slot-reuse counter of the projectile being removed. A stale generation makes
/// clients treat the key as a fresh (type 0) projectile, which still clears the slot.</summary>
public int Generation { get; set; }

public override void Pack(Stream stream)
{
stream.WriteInt16(Index);
// ProjectileKey: spawner:8 | index:10 | generation:14
int key = (Owner & 255) | (Index & 1023) << 8 | (Generation & 16383) << 18;
stream.WriteInt32(key);
stream.WriteSingle(-1);
stream.WriteSingle(-1);
stream.WriteSingle(0);
stream.WriteSingle(0);
stream.WriteSingle(0);
stream.WriteInt16(0);
stream.WriteByte(Owner);
stream.WriteInt16(0);
stream.WriteSingle(0);
stream.WriteSingle(0);
stream.WriteByte(0);
}
}
}
18 changes: 9 additions & 9 deletions TShockAPI/Rest/RestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -976,9 +976,9 @@ private object PlayerReadV3(RestRequestArgs args)
return ret;

TSPlayer player = (TSPlayer)ret;
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();
var inventory = player.TPlayer.inventory.Where(p => !p.IsAir).ToList();
var equipment = player.TPlayer.armor.Where(p => !p.IsAir).ToList();
var dyes = player.TPlayer.dye.Where(p => !p.IsAir).ToList();
return new RestObject()
{
{"nickname", player.Name},
Expand Down Expand Up @@ -1012,12 +1012,12 @@ private object PlayerReadV4(RestRequestArgs args)

object items = new
{
inventory = player.TPlayer.inventory.Where(i => i.active).Select(item => (NetItem)item),
equipment = player.TPlayer.armor.Where(i => i.active).Select(item => (NetItem)item),
dyes = player.TPlayer.dye.Where(i => i.active).Select(item => (NetItem)item),
piggy = player.TPlayer.bank.item.Where(i => i.active).Select(item => (NetItem)item),
safe = player.TPlayer.bank2.item.Where(i => i.active).Select(item => (NetItem)item),
forge = player.TPlayer.bank3.item.Where(i => i.active).Select(item => (NetItem)item)
inventory = player.TPlayer.inventory.Where(i => !i.IsAir).Select(item => (NetItem)item),
equipment = player.TPlayer.armor.Where(i => !i.IsAir).Select(item => (NetItem)item),
dyes = player.TPlayer.dye.Where(i => !i.IsAir).Select(item => (NetItem)item),
piggy = player.TPlayer.bank.item.Where(i => !i.IsAir).Select(item => (NetItem)item),
safe = player.TPlayer.bank2.item.Where(i => !i.IsAir).Select(item => (NetItem)item),
forge = player.TPlayer.bank3.item.Where(i => !i.IsAir).Select(item => (NetItem)item)
};

return new RestObject
Expand Down
4 changes: 2 additions & 2 deletions TShockAPI/TSPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1420,7 +1420,7 @@ public bool InventorySlotAvailable
{
for (int i = 0; i < 50; i++) //51 is trash can, 52-55 is coins, 56-59 is ammo
{
if (TPlayer.inventory[i] == null || !TPlayer.inventory[i].active || TPlayer.inventory[i].Name == "")
if (TPlayer.inventory[i] == null || TPlayer.inventory[i].IsAir || TPlayer.inventory[i].Name == "")
{
flag = true;
break;
Expand Down Expand Up @@ -1984,7 +1984,7 @@ private Item GiveItemDirectly_FillEmptyInventorySlot(Item item, int slot)

private void GiveItemByDrop(int type, int stack, int prefix)
{
int itemIndex = Item.NewItem(new EntitySource_DebugCommand(), (int)X, (int)Y, TPlayer.width, TPlayer.height, type, stack, true, prefix, true);
int itemIndex = Item.NewItem(new EntitySource_DebugCommand(), (int)X, (int)Y, TPlayer.width, TPlayer.height, type, stack, true, prefix, Terraria.NewItemOwnership.None);
Main.item[itemIndex].playerIndexTheItemIsReservedFor = this.Index;
SendData(PacketTypes.ItemDrop, "", itemIndex, 1);
SendData(PacketTypes.ItemOwner, null, itemIndex);
Expand Down
4 changes: 2 additions & 2 deletions TShockAPI/TShock.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2019 Pryaxis & TShock Contributors

Expand Down Expand Up @@ -1066,7 +1066,7 @@ private void OnUpdate(EventArgs args)
// even if there are no clients connected
if (ServerApi.ForceUpdate)
{
Netplay.HasClients = true;
Netplay.HasFullyConnectedClients = true;
}

if (Backups.IsBackupTime)
Expand Down
9 changes: 4 additions & 5 deletions TShockAPI/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -779,11 +779,10 @@ public bool TryParseTime(string str, out ulong seconds)
/// <returns>projectile ID</returns>
public int SearchProjectile(short identity, int owner)
{
for (int i = 0; i < Main.maxProjectiles; i++)
{
if (Main.projectile[i].identity == identity && Main.projectile[i].owner == owner)
return i;
}
// 1.4.5.7 replaced Projectile.identity with ProjectileKey, whose index component
// is the slot in Main.projectile, so the lookup is direct.
if (identity >= 0 && identity < Main.maxProjectiles && Main.projectile[identity].owner == owner)
return identity;
return 1000;
}

Expand Down
2 changes: 1 addition & 1 deletion TShockLauncher/TShockLauncher.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<PackageReference Include="GetText.NET" Version="8.0.5" /> <!-- only used to extract out to ./bin. -->

<!-- the launcher doesnt need the direct OTAPI reference, but since PackageReference[ExcludeFromSingleFile] doesnt work, exclude the assets and copy manually -->
<PackageReference Include="OTAPI.Upcoming" Version="3.3.11" ExcludeAssets="all" GeneratePathProperty="true" />
<PackageReference Include="OTAPI.Upcoming" Version="3.3.12" ExcludeAssets="all" GeneratePathProperty="true" />
<None Include="$(PkgOTAPI_Upcoming)\lib\net9.0\OTAPI.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
Expand Down
7 changes: 7 additions & 0 deletions nuget.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="local-otapi" value="/home/zak/local-nuget" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
Loading