Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shorts, Threes, and Ints aren’t unsigned #149

Closed
sorokya opened this issue Mar 25, 2022 · 8 comments · Fixed by #294
Closed

Shorts, Threes, and Ints aren’t unsigned #149

sorokya opened this issue Mar 25, 2022 · 8 comments · Fixed by #294
Assignees
Milestone

Comments

@sorokya
Copy link
Contributor

sorokya commented Mar 25, 2022

Noticed while testing this with reoserv that the client reads shorts, threes, and ints as signed values.

This became an issue when reoserv tried to send a a session id that was bigger than a signed short can hold.

I tried fixing this myself but it quickly became a huge change to over 100 files and broke a lot of stuff.

@ethanmoffat
Copy link
Owner

Yeah this is a big problem. I also went through and tried to update it to use signed values and had the same issue, 100+ files changed quickly became a headache.

The actual problem is that because NumberEncoderService takes an int, it will sign extend shorts that are greater than short.MaxValue. See: b80ff5c

What I ended up doing to resolve it is just casting to ushort client-side. It's an ugly hack but it works.

Which session id specifically was causing the issue?

@sorokya
Copy link
Contributor Author

sorokya commented Mar 26, 2022

In reoserv I generate a random short value between 0 and the max2 value.

https://github.com/sorokya/reoserv/blob/async-rewrite/src/player/player.rs#L154

the error was coming up during the welcome message packet. The session id reoserv sent was too big.

@ethanmoffat
Copy link
Owner

I'll see if I can reproduce it against reoserv. That commit I linked (b80ff5c) was working for me with larger player IDs on GameServer and etheos

@sorokya
Copy link
Contributor Author

sorokya commented Mar 26, 2022

Ah you’re right casting it back to unsigned does fix it. I’ll just do that for now in my branch. :P

edit:
Doesn't look like that will work if you need to use AddShort.

Using AddThree((ushort) SessionID) works fine because you can fit a ushort in an int but you can't do AddShort((ushort) SessionID).

In #150 I did a dirty workaround by just adding an overload to PacketBuilder AddShort(ushort s)

Let me know what you think :)

@ethanmoffat
Copy link
Owner

I didn't have that issue for shorts in my testing. I also added a line to PacketBuilder that casts the short to ushort prior to calling EncodeNumber with it so it doesn't get sign-extended during encoding:

return AddBytes(_encoderService.EncodeNumber((ushort)s, 2));

I forgot I updated it in both these places, but it was working consistently for me on both etheos and gameserver

@sorokya
Copy link
Contributor Author

sorokya commented Mar 26, 2022

You're right that totally fixes it. No need for the overload :)

@ethanmoffat ethanmoffat added this to the Version 1 milestone Apr 11, 2022
@ethanmoffat
Copy link
Owner

When playing on BU, this problem is pretty apparent once you get over TWO_BYTE_MAX HP:
image

Adding the ushort cast fixes it but we need a more universal solution because that's gross and hacky.

@ethanmoffat
Copy link
Owner

I'm going to take the eolib-java approach and make everything an int instead of using exotic types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants