Is there any document outlining the binary protocol used by LLAPI anywhere? Something like this: https://doc.photonengine.com/en/onpremise/current/reference/binary-protocol I am doing a kind of a tricky proxy for UNet traffic, and I need to know the QoS channel number by looking into binary protocol data. Is that possible?
Yes, Do you have a UNet Protocol Sepcification? I have used wireshark to capture UNET.pcap,I want to reverse engineering UNET Protocol, but it's too hard!
Code (CSharp): //all 16 and 32 bit data are network ordered //message length occupy 1 byte length if first bit == 0 or 2 bytes if it equal 1: int SetLength(char* buffer, uint16_t messageLength) { int messageLengthSize = (messageLength > 0x7F) ? 2 : 1; if (messageLengthSize == 1) { *buffer = (uint8_t)messageLength; } else { Assert(messageLength < 0x7FFF); *buffer = (messageLength >> 8) | 0x80; *(buffer + 1) = (uint8_t)messageLength & 0xFF; } return messageLengthSize; } //packets: // header: struct PacketBaseHeader { uint16_t connectionId; //if 0 it will be system packet }; // user packet headers: struct NetPacketHeader : public PacketBaseHeader { uint16_t packetId; uint16_t sessionId; //never changed and always in network order }; // if there are reliable channels struct PacketAcksXX //XX == 32, 64, 96, 128 { uint16_t ackMessageId; uint32_t acks[x]; //x == 1,2,3,4 }; // system packets: struct LocalDiscoveryPacket : public PacketBaseHeader //note that structure of broad cast packet is different from system! { uint8_t requestType; uint16_t clientPort; uint8_t guid[kUnetGUIDLength]; //kUnetGUIDLength == 36 uint32_t version; uint32_t subversrion; }; //helper for other structures described below struct SystemPacket : public PacketBaseHeader { uint8_t requestType; uint16_t packetId; uint16_t sessionId; //never changed uint16_t localConnectionId; uint16_t remoteConnectionId; }; struct ConnectPacket : public SystemPacket { uint32_t lib_version; uint32_t crc; }; struct DisconnectPacket : public SystemPacket { uint32_t lib_version; uint8_t reason; }; struct PingPacket : public SystemPacket { uint32_t sentPingTime; //timestamp when this ping was sent uint32_t ackPingTime; //when we receive last ping from remote connection uint32_t localTimeCorrection;//how many ms has been spent between time when we receive ackPingTime and time when we send this ping uint8_t intDropRate; //how many packet (in % from 255) was dropped due lack storage in buffers uint8_t extDropRate; //how many packet (in % from 255) was lost or delivered out of order due network conditions uint16_t remoteSessionId; //ping packet serves as connection request acknowledging, to avoid scenario where wrong ping will be ack connection, both session should be taken into account }; //Messages commons structure //{message} == {channelId (uint8_t)|length(1 or 2 bytes)|message header|payload} //special channels: //reliable channelId == 255 //message == 255|length|NMReliableHeader|{message}{message}{message} //and all messages lost its NMReliableHeader from message headers //combined message - messages from one channel combined to one combined message and shared the same header //channelId == 254 //message == 254|OriginChannelId{uint8_t)|length|{message in format: length|payload -- no header no channel number} //headers: //helpers: struct NMReliableHeader //reliable header { uint16_t messageId; }; struct NetMessageOrderedHeader //this header applied to sequenced and state update qos { uint8_t orderedMessageId; }; struct NetMessageFragmentedHeader //this header applied to fragmented messages { uint8_t fragmentedMessageId; //id of fragmented message uint8_t fragmentIdx; //id of fragment uint8_t fragmentAmnt; // fragments total }; //all reliable messages will be combined to one, except AllCost qos, so if channel has alacost host message = channelId|)|length(1 or 2 bytes)|NMReliableHeader|payload
@ProinterRage it was for you. You can ping me directly if you will have a questions :0) (I guess you will )