2 March Updates - Item pile & CoX leaderboard fixes

All of PkHonor's news will be posted here.
User avatar
Brant
Fanatic
Posts: 4193
Joined: Tue Aug 12, 2014 3:17 am

Re: 2 March Updates - Item pile & CoX leaderboard fixes

Post by Brant » Fri Mar 03, 2023 7:13 pm

Raj wrote: Fri Mar 03, 2023 1:49 am
Iron podge wrote: Fri Mar 03, 2023 1:38 am The dropped items bug is wild. Imagine you're group pvming, you get the drop, and someone snipes that shit :kekw:

I'd like to know the story of how it was discovered :lol:
It happened specifically if you loaded a region with a ground item with a quantity which was a multiple of 256. So mostly it happened after people died with stacks of items, like UIMs or people using bolts at corp. Normal dropping of items wasn't effected, just entering a region where items were already on the ground.

UIMs found it most frequently, naturally
what kind of spaghetti code ass shit

User avatar
Fungamer
Developer
Posts: 11407
Joined: Sun Jun 30, 2013 8:44 pm

Re: 2 March Updates - Item pile & CoX leaderboard fixes

Post by Fungamer » Fri Mar 03, 2023 9:02 pm

Brant wrote: Fri Mar 03, 2023 7:13 pm
Raj wrote: Fri Mar 03, 2023 1:49 am
Iron podge wrote: Fri Mar 03, 2023 1:38 am The dropped items bug is wild. Imagine you're group pvming, you get the drop, and someone snipes that shit :kekw:

I'd like to know the story of how it was discovered :lol:
It happened specifically if you loaded a region with a ground item with a quantity which was a multiple of 256. So mostly it happened after people died with stacks of items, like UIMs or people using bolts at corp. Normal dropping of items wasn't effected, just entering a region where items were already on the ground.

UIMs found it most frequently, naturally
what kind of spaghetti code ass shit
I'm really curious what the actual technical explanation behind this is and what caused it. Especially since I'm wondering whether this is something to look out for as a software dev or if it's a super obscure thing that was specific to pkh codebase
Image

Raj
Developer
Posts: 2617
Joined: Sun Dec 30, 2018 2:50 am

Re: 2 March Updates - Item pile & CoX leaderboard fixes

Post by Raj » Fri Mar 03, 2023 10:58 pm

Fungamer wrote: Fri Mar 03, 2023 9:02 pm
Brant wrote: Fri Mar 03, 2023 7:13 pm
Raj wrote: Fri Mar 03, 2023 1:49 am

It happened specifically if you loaded a region with a ground item with a quantity which was a multiple of 256. So mostly it happened after people died with stacks of items, like UIMs or people using bolts at corp. Normal dropping of items wasn't effected, just entering a region where items were already on the ground.

UIMs found it most frequently, naturally
what kind of spaghetti code ass shit
I'm really curious what the actual technical explanation behind this is and what caused it. Especially since I'm wondering whether this is something to look out for as a software dev or if it's a super obscure thing that was specific to pkh codebase
On region load, the server would send a large binary mass to the client. The binary mass contained a number of item pile info. It also is headed by an integer representing the number of items to be processed in the binary mass. Each entry on the giant binary mass was composed of the following:

itemId - int I think
toRemove - byte

If toRemove was not 0, then the following would be read/written to/from the current point in the stream (written in the server, read in the client):
quantity - int
tradeable - int

So here’s what happened. To provide the “toRemove” info, the server would encode the item quantity to a byte and send it over. Thus, any quantity which was a multiple of 256 was sent as 0. Because 0 was read, the quantity and tradeable data weren’t read. So say we have this:

itemId toRemove quantity tradeable -> maybe 0, 0, 256, 1.

For say toRemove is 0 because it was encoded using int to byte casting on the 256 value. The clients gonna read the first two 0’s. When it sees toRemove is 0, it won’t read 256 and 1 as quantity and tradeable. Instead, it will try to read 256 and 1 (the second being read a single byte stream read) as “itemId” and “toRemove” for the next item, because “toRemove” being 0 (which it observed) is meant to signal to continue to the next item. The offset would also affect the entire rest of the stream read. This is why massive piles of salmon would randomly appear; the client was offsetting its stream reads wrong, and would frequently read in junk data from the big binary mass because it thought the item before contained only an int and a byte rather than an int, a byte, and 2 more ints

I think, our solution was just to do away with the removal flag entirely, and do that in other places, rather than trying to make it a conditional read during a loop over a stream. So now the binary for each item pile is a constant length block contained in the aforementioned binary mass, and this should never happen again

Edit: I think the name “toRemove” is inverted, because “toRemove == 0” was “remove”, and “toRemove != 0” was “do not remove”, but it’s tangential at this point because it doesn’t exist anymore

User avatar
Fungamer
Developer
Posts: 11407
Joined: Sun Jun 30, 2013 8:44 pm

Re: 2 March Updates - Item pile & CoX leaderboard fixes

Post by Fungamer » Sat Mar 04, 2023 12:14 am

Raj wrote: Fri Mar 03, 2023 10:58 pm
Fungamer wrote: Fri Mar 03, 2023 9:02 pm
Brant wrote: Fri Mar 03, 2023 7:13 pm
what kind of spaghetti code ass shit
I'm really curious what the actual technical explanation behind this is and what caused it. Especially since I'm wondering whether this is something to look out for as a software dev or if it's a super obscure thing that was specific to pkh codebase
On region load, the server would send a large binary mass to the client. The binary mass contained a number of item pile info. It also is headed by an integer representing the number of items to be processed in the binary mass. Each entry on the giant binary mass was composed of the following:

itemId - int I think
toRemove - byte

If toRemove was not 0, then the following would be read/written to/from the current point in the stream (written in the server, read in the client):
quantity - int
tradeable - int

So here’s what happened. To provide the “toRemove” info, the server would encode the item quantity to a byte and send it over. Thus, any quantity which was a multiple of 256 was sent as 0. Because 0 was read, the quantity and tradeable data weren’t read. So say we have this:

itemId toRemove quantity tradeable -> maybe 0, 0, 256, 1.

For say toRemove is 0 because it was encoded using int to byte casting on the 256 value. The clients gonna read the first two 0’s. When it sees toRemove is 0, it won’t read 256 and 1 as quantity and tradeable. Instead, it will try to read 256 and 1 (the second being read a single byte stream read) as “itemId” and “toRemove” for the next item, because “toRemove” being 0 (which it observed) is meant to signal to continue to the next item. The offset would also affect the entire rest of the stream read. This is why massive piles of salmon would randomly appear; the client was offsetting its stream reads wrong, and would frequently read in junk data from the big binary mass because it thought the item before contained only an int and a byte rather than an int, a byte, and 2 more ints

I think, our solution was just to do away with the removal flag entirely, and do that in other places, rather than trying to make it a conditional read during a loop over a stream. So now the binary for each item pile is a constant length block contained in the aforementioned binary mass, and this should never happen again

Edit: I think the name “toRemove” is inverted, because “toRemove == 0” was “remove”, and “toRemove != 0” was “do not remove”, but it’s tangential at this point because it doesn’t exist anymore
Wow thats fucking crazy lmao
Image

Post Reply