Read CString (or what type it really is in raknet) in BitStream.

0x32789

Expert
Joined
May 26, 2014
Messages
849
Reaction score
51
Location
LongForgotten <-> 0x32789
How would I read the parameter type CString in a bitstream? and if I want to write, how'd I do it aswell?
The RPC Parameters for SetPlayerObjectMaterial(Text)- ID: 84 is:

Parameters For MaterialText: UINT16 wObjectID, UINT8 MaterialType, UINT8 MaterialID, UINT8 MaterialSize, UINT8 fontNameLength, char fontName[], UINT8 FontSize, UINT8 Bold, UNIT32 FontColor, UNIT32 BackgroundColor, UNIT8 Align, CSTRING text[2048]

as it says, CSTRING text[2048]
I don't know how to do it, I have tried to read it as a char with 2048 length, still can't figure out.
Did some googling, learned it has to do something with encoding and decoding but I got no idea.
Also I'm using minimal raknet libraries or the ones present in s0biet. Can someone provide help or the decode function, I got no idea how it's done.

Thx.
 

0x_

Wtf I'm not new....
Administrator
Joined
Feb 18, 2013
Messages
1,118
Reaction score
166
You're searching the raknet string compressor class.
 

0x32789

Expert
Joined
May 26, 2014
Messages
849
Reaction score
51
Location
LongForgotten <-> 0x32789
You're searching the raknet string compressor class.

I found this paste online:
https://pastebin.com/kK48vy3R

I noticed that dialog also uses CString and saw something like this in netrpc.cpp in RakSAMP src, but there's a snippet/function for decoding without actually using the raknet string compressor in the paste..

Code:
typedef uint32_t BitSize_t;
    struct HuffmanEncodingTreeNode
    {
        unsigned char value;
        unsigned weight;
        HuffmanEncodingTreeNode *left;
        HuffmanEncodingTreeNode *right;
        HuffmanEncodingTreeNode *parent;
    };
    HuffmanEncodingTreeNode *root;
    unsigned DecodeArray(BitStream * input, BitSize_t sizeInBits, size_t maxCharsToWrite, unsigned char *output)
    {
        HuffmanEncodingTreeNode * currentNode;
 
        unsigned outputWriteIndex;
        outputWriteIndex = 0;
        currentNode = root;
 
        // For each bit, go left if it is a 0 and right if it is a 1.  When we reach a leaf, that gives us the desired value and we restart from the root
 
        for (unsigned counter = 0; counter < sizeInBits; counter++)
        {
            if (input->ReadBit() == false)   // left!
                currentNode = currentNode->left;
            else
                currentNode = currentNode->right;
 
            if (currentNode->left == 0 && currentNode->right == 0)   // Leaf
            {
 
                if (outputWriteIndex < maxCharsToWrite)
                    output[outputWriteIndex] = currentNode->value;
 
                outputWriteIndex++;
 
                currentNode = root;
            }
        }
 
        return outputWriteIndex;
    }
 
    bool DecodeString(char *output, int maxCharsToWrite, BitStream *input)
    {
        if (maxCharsToWrite <= 0)
            return false;
 
        uint32_t stringBitLength;
        int bytesInStream;
 
        output[0] = 0;
 
        if (input->ReadCompressed(stringBitLength) == false)
            return false;
 
        if ((unsigned)input->GetNumberOfUnreadBits() < stringBitLength)
            return false;
 
        bytesInStream = DecodeArray(input, stringBitLength, maxCharsToWrite, (unsigned char*)output);
 
        if (bytesInStream < maxCharsToWrite)
            output[bytesInStream] = 0;
        else
            output[maxCharsToWrite - 1] = 0;
 
        return true;
    }

I compared it to the function in StringCompressor found in raknet source file, Though this does not appear to work, I get a null/empty char array and when I tried to debug, it fails at
here:
Code:
if ((unsigned)input->GetNumberOfUnreadBits() < stringBitLength)
            return false;

Got a idea why it isn't working? Maybe my read pointer is messed up? It's pretty much the same function except it doesn't require all the raknet src and the Huffman encoding tree completely.
 
Top