More character encoding alternatives

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Punpun
:warning: Old Version Published before Godot 3 was released.

Hey guys, lately I’ve been getting my godot project to work with my old server, and I got it to recieve, process and send data. For sending data I’ve been relying on RawArrays in which I put the string I want to send followed by .to_utf8. Works well.

However, I need to send more types of data other than strings and single byte integers, like a signed 32bit integer, which I couldn’t find any kind of support in the docs.

I know about .put_32 function in the StreamPeer, but that is only useful when sending one type of information per packet, which is not a common situation.

Is there a alternative to convert data in other encodings? I’m looking for an int.to_s32(signed 32bits) that would return a RawArray, much like string.to_utf8 does.

Is something like that already in the engine? Should I make a request?

I still don’t understand why you don’t use put_32. This function actually appends one 32-bit integer to the stream, you can continue writing what you want after that. What is wrong with it?

Zylann | 2016-10-27 19:07

Because I as said, put_32 takes all the data, converts it all into this format, and instantly sends it to the server. I work with a RawArray of information, containing various strings and 1byte integers, which don’t use the same encoding as 32bit , if I would send it all in the .put_32, it would convert all the data as 32bites and it would be unreadable in the server.
Besides, if .to_utf8 exists, functions like .to_16 and .to_s32 also should, they’re all essential for netcode.

Punpun | 2016-10-27 19:31

Which type of StreamPeer are you using? TCP? UDP? Other? (or you don’t know? Sorry I never used this class yet, it just looks confusing because I don’t understand why putting a single integer would send an entire packet :s)

Zylann | 2016-10-27 23:15

I use TCP.

Putting a single integer will send that only integer, but I don’t use it like that, is just not efficient nor is it enough for a consistent replication in most cases. The way I would send a coord. packet, for example, would be: [“coord”.to_utf8, pos_x, pos_y] (in RawArray)

As you can see, it will send a packet with more than one information and type. The first is a string, my server uses it to know what kind of handling it will need to do; pos_x and pos_y should be written in 32bits, thats why I miss an .to_32 function that works like.to_utf8.

Punpun | 2016-10-28 00:35

:bust_in_silhouette: Reply From: Zylann

I had a look at the latest sources on Github and I see there is a new class, StreamPeerBuffer, which has the same functions but simply puts the data in a buffer without sending it. It even has a method RawArray get_data_array() which returns you the array. I don’t see any formatting except the big-endian thing. Perhaps that’s what you need?

No, that would be doing the same I do with a RawArray, which is store more and more data until I’m ready to send it. Thanks for taking the time to look at it, though.

Punpun | 2016-10-28 00:39

Uh… ok I’m still confused about what you want to do then, you said you don’t want to send only one kind of data :s
If so, you have to buffer it.

With StreamPeerBuffer, building the data of the packet you talk about in above comments would be done like this:

stream.put_utf8_string("coord")
stream.put_32(pos.x)
stream.put_32(pos.y)
raw = stream.get_array_data()

The same goes if you only want one element.
Then you can simply send raw with TCP.

(note: I’m not sure what Godot will do with pos.x/y, they are floats, not integers)

Zylann | 2016-10-28 16:16

Oh, you mean that with StreamPeerBuffer I can use .put_ functions and have it append data and not send it right away? Now that would be awesome.

All the already existing .put_ functions send the data instantly, not really appending to anything.

I’ll look for it right now, thanks.

Punpun | 2016-10-28 16:54

Yeah, I think that’s what StreamPeerBuffer is made for, because it’s not bound to any network system (at least, from what I’ve read after having a glance at the source code). It’s in the name, “buffer”, so it goes to a buffer, not the network :slight_smile:

Zylann | 2016-10-28 19:07