what kind of spaghetti code ass shitRaj wrote: ↑Fri Mar 03, 2023 1:49 amIt 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.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
I'd like to know the story of how it was discovered
UIMs found it most frequently, naturally
2 March Updates - Item pile & CoX leaderboard fixes
- Brant
- Honor Player
- Posts: 4324
- Joined: Tue Aug 12, 2014 3:17 am
Re: 2 March Updates - Item pile & CoX leaderboard fixes
- Fungamer
- Developer
- Posts: 11407
- Joined: Sun Jun 30, 2013 8:44 pm
Re: 2 March Updates - Item pile & CoX leaderboard fixes
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 codebaseBrant wrote: ↑Fri Mar 03, 2023 7:13 pmwhat kind of spaghetti code ass shitRaj wrote: ↑Fri Mar 03, 2023 1:49 amIt 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.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
I'd like to know the story of how it was discovered
UIMs found it most frequently, naturally
-
- Developer
- Posts: 2696
- Joined: Sun Dec 30, 2018 2:50 am
Re: 2 March Updates - Item pile & CoX leaderboard fixes
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:Fungamer wrote: ↑Fri Mar 03, 2023 9:02 pmI'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 codebaseBrant wrote: ↑Fri Mar 03, 2023 7:13 pmwhat kind of spaghetti code ass shitRaj 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
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
- Fungamer
- Developer
- Posts: 11407
- Joined: Sun Jun 30, 2013 8:44 pm
Re: 2 March Updates - Item pile & CoX leaderboard fixes
Wow thats fucking crazy lmaoRaj wrote: ↑Fri Mar 03, 2023 10:58 pmOn 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