Using Protocol Buffers to serialize data in Flyff

Welcome to our Community
Wanting to join the rest of our members? Feel free to sign up today.
Sign up

Ssam

Member
Registered
Joined
Jun 17, 2024
Messages
22
Reaction score
26
Points
13
Hello !

Introduction

Writing & reading data on the network in a painful job to do (and ugly to write, prone to errors etc...). It appears that writing it manually can also be kind of slow, and that's exactly what we do in flyff with that kind of code (here, an example taken from PACKETTYPE_BUYITEM) :

(Writing data)
Hey There!
Please login and(or) register to see this awesome content today.

(Receiving data)
Hey There!
Please login and(or) register to see this awesome content today.

Of course there are more complex examples in the actual source code of flyff, but this one is a good start. As you can see, we write manually each field of our imaginary data structure, there is no error handling (ar >> cTab, what if there's no ctab ? what if the client sent a int32 instead of a byte ? ...).

There's also no trivial way to reuse components, how many times I've seen the same data structure over multiple packets ? Like an object id, and a material id (awakening, manual upgrade, card insertion...).

Protocol buffers

Protocol buffers (https://protobuf.dev/), is a tool that helps to solve this exact problem (aswell as many others). You write your messages in a .proto file (it's like a DSL) that is agnostic from any programming language (like C++).

Here's what it looks like with our "UseMaterialOnItem" data structure :
Hey There!
Please login and(or) register to see this awesome content today.

Now, I need to compile this to the programming language I want (here, C++), I'm following this docs : https://protobuf.dev/getting-started/cpptutorial/#compiling-protocol-buffers.

And it generates me some unreadable files. Great. Here's how it looks in the code when I want to use those generated structures.

(Writing data)
Hey There!
Please login and(or) register to see this awesome content today.

Under the hood, SendProtoPacket simply writes the UseMaterialOnItem packet as a string (which is a perfectly valid protobuf representation, even if it's not really human-readable)

Hey There!
Please login and(or) register to see this awesome content today.

(Receiving data)
Hey There!
Please login and(or) register to see this awesome content today.

Any deserialization error will be catched by ParseFromString, it's a one-liner that parses every single field of your packet, and is perfectly safe to use. Of course, it doesn't perform semantics validation, this is still up to you.

Conclusion

Protobuf helps me A LOT. Everyday. I'm using vcpkg to embed it in my application as a static library, and I'm using a manually installed protoc on my computer. It's amazing because you can reuse messages, embed them into other messages, and reduce a lot boilerplate code.

(Embedding is done like this in proto)
Hey There!
Please login and(or) register to see this awesome content today.

And you ? What are you using to serialize your data ?
 
Thank @zOmbie for bringing back this topic.

Another developer expressed his concern about the bad performance of serializing and deserializing protocol buffer information to a byte array (a string).

I have to say that, after more than a year of using this in production, it never caused me any problem performance-wise, and the built-in security & its ease of use and readability are a game-changer.
 
  • Like
Reactions: zOmbie