Script -> Client RakNet colors? big confuse i am

0x32789

Expert
Joined
May 26, 2014
Messages
849
Reaction score
51
Location
LongForgotten <-> 0x32789
https://github.com/BrunoBM16/samp-packet-list/wiki/RPC-List
over here I can see a list of SAMP RPC's and shit, on some RPC's like ClientMessage or related whichever has colours, the color is mostly UINT32.

So on the page it's written UINT32 dColor..
Now, I don't know if I'm doing it fine but all I do is read it normally like...

UINT32 COLOR;
BitStream.Read(COLOR);

Now, the problem is, the color mismatches, I directly use it like for instance in sending player a chat message, the color is different, I also tested the color on a test script and the integer values are different.. Why?
What am I doing wrong?
Help will be appreciated.

@springfield ?
 

Parazitas

God
Joined
Jan 2, 2017
Messages
3,117
Solutions
5
Reaction score
882
Location
Lithuania
Try this one, I found on russian site.
C++:
bool CALLBACK incomingRPC(stRakNetHookParams * params)
{
    if (params->packetId == ScriptRPCEnumeration::RPC_ScrClientMessage)
    {
        if (translatorEnabled)
        {
            DWORD color;
            DWORD strlen;
            char string[2048];
            params->bitStream->ResetReadPointer();
            params->bitStream->Read(color);
            params->bitStream->Read(strlen);
            params->bitStream->Read(string, strlen);
            string[strlen] = '\0';

            //code...

            AddMessageToChat(D3DCOLOR_XRGB(0, 0XAA, 0), "%s", string);

            return false;
        }
    }
    return true;
}
void CALLBACK mainloop()
{

    static bool init = false;
    if (!init)
    {
        init = true;
        SF->getRakNet()->registerRakNetCallback(RakNetScriptHookType::RAKHOOK_TYPE_INCOMING_RPC, incomingRPC);
    }
}
 

0x32789

Expert
Joined
May 26, 2014
Messages
849
Reaction score
51
Location
LongForgotten <-> 0x32789
Changing to DWORD doesn't help either. Still different color value from thescript.
For example if I send with color 987651 from a script.
The client receives (or atleast me while reading from the bitstream) does it 20xxx smthing forgot.
 
Joined
Feb 18, 2005
Messages
2,963
Reaction score
267
Show some code example, there are two different 'chat' messages, players chat and messages, also is it sent or received?
If you don't use SF API, maybe you forgot to skip the first 8 bits which contains the packet indentifier?
 

0x32789

Expert
Joined
May 26, 2014
Messages
849
Reaction score
51
Location
LongForgotten <-> 0x32789
Show some code example, there are two different 'chat' messages, players chat and messages, also is it sent or received?
If you don't use SF API, maybe you forgot to skip the first 8 bits which contains the packet indentifier?

It is the received chat message.
The "SendClientMessage" RPC from the server.

Code:
void HandleRPCPacketFunc(unsigned char id, RPCParameters* rpcParams, void(*callback) (RPCParameters*), bool edit)
{
	if (rpcParams != nullptr && rpcParams->numberOfBitsOfData >= 8 && edit)
	{
		BitStream bsData(rpcParams->input, rpcParams->numberOfBitsOfData / 8, false);
		
		if(id == RPC_ClientMessage && toggled_in == true)
		{
			UINT32 color;
			UINT32 stringlen;
			char string[255];

			bsData.ResetReadPointer();
			bsData.Read(color);
			bsData.Read(stringlen);


			bsData.Read(string, stringlen);

			string[stringlen] = '\0';

			translatorData tdat;
			tdat.type = TEXT;

			tdat.translationData[0] = malloc(strlen(string));
			strcpy((char*)tdat.translationData[0], string);

			tdat.translationData[1] = (void*)color;
			
			workQueue.enqueue(tdat); // enqueue the data and put it in the thread to go for translation..
			return;
		}
	}
	callback(rpcParams);
}

later in the queued data processing:

Code:
string res = Translate(code_in.c_str(), (char*)tdat.translationData[0], TRANSLATE_KEY, CyrillicOut);

				/*char hexcol[16];

				snprintf(hexcol, sizeof hexcol, "%02x%02x%02x", ExtractRed((DWORD)tdat.translationData[1]), \
					ExtractGreen((DWORD)tdat.translationData[1]), \
					ExtractBlue((DWORD)tdat.translationData[1]));*/

				addToChatWindow((UINT32)tdat.translationData[1], "%s", res.c_str());

the string isjust fine, the color is fucked.

This is how it appears to me:
Untitled.png

How the color should be (when it's turned off and doesn't matter if PM was sent or received because the color is same.)
sa-mp-000.png

It should be yellow, turning it off, it displays the original color.

Same problem in intercepting SetObjectMaterial, the color of the material.

Code:
if (id == RPC_SetObjectMaterial)
{
			UINT16 objid;
			UINT8 MaterialType;
			UINT8 tmpMatID;

			bsData.Read(objid);
			bsData.Read(MaterialType);
			bsData.Read(tmpMatID);
(bla bla bla checks and shit)
                       DWORD objectColor; (tried UINT32 aswell)
                       bsData.Read(objectColor);
}
 

0x_

Wtf I'm not new....
Administrator
Joined
Feb 18, 2013
Messages
1,118
Reaction score
166
The color isn't uint32 it's either ARGB or RGBA uint32 is just the data type.

Object material is ARGB and SCM RGBA.
Try changing your extraction method.
 

0x32789

Expert
Joined
May 26, 2014
Messages
849
Reaction score
51
Location
LongForgotten <-> 0x32789
The color isn't uint32 it's either ARGB or RGBA uint32 is just the data type.

Object material is ARGB and SCM RGBA.
Try changing your extraction method.

How would I extract?

I'm trying this:
Code:
uint8_t ExtractColor(uint32_t c, int colorval)
{
	return c >> colorval;
}

Code:
r = ExtractColor(color, 24);
g = ExtractColor(color, 16);
b = ExtractColor(color, 8);
a = ExtractColor(color, 0);

addMessageToChatWindow("%d %d %d %d", r, g, b, a);

addToChatWindow(D3DCOLOR_COLORVALUE(r, g, b, a), "%s", res.c_str());

This is giving me correct color values, the red green blue alpha values as I used a debug script and the hex matched the RGB values but I still see different color...
 
Joined
Feb 18, 2005
Messages
2,963
Reaction score
267
You receive RGBA color, but you need to pass ARGB to 'addToChatWindow'
C++:
addToChatWindow((color >> 8) | 0xFF000000, "%s", res.c_str());
 
Last edited:

monday

Expert
Joined
Jun 23, 2014
Messages
1,126
Solutions
1
Reaction score
158
Building on springfield's post, this way you could preserve the original alpha value
C:
unsigned int color = 0xAABBCCDD;
printf("rgba = %X argb = %X", color, (color >> 8) | (color << 24));
rgba = AABBCCDD argb = DDAABBCC

It's worth to notice that if you define color as "int" instead of "unsigned int" then the "shift right" operator (>>) will fill the new bits with 1's instead of 0's, meaning that the output of the same program would be:
rgba = AABBCCDD argb = FFAABBCC
 

0x32789

Expert
Joined
May 26, 2014
Messages
849
Reaction score
51
Location
LongForgotten <-> 0x32789
Building on springfield's post, this way you could preserve the original alpha value
C:
unsigned int color = 0xAABBCCDD;
printf("rgba = %X argb = %X", color, (color >> 8) | (color << 24));


It's worth to notice that if you define color as "int" instead of "unsigned int" then the "shift right" operator (>>) will fill the new bits with 1's instead of 0's, meaning that the output of the same program would be:
Works.

Thanks problem fixed and for SetObjectMaterial(Optionally Text aswell)
In wiki it's written that it uses ARGB, but it uses ABGR for some reason OR it's that ABGR is sent via the RPC Bitstream.
Anyways, you can invert it/fix it eitherways with this little function..

Code:
UINT32 ARGBtoABGR(UINT32 col) // Converts ARGB to ABGR
{
	//Normally col = 0xffa5a7a4
	//Target/script = 0xFFA4A7A5
	//To achieve: 0xffa4a7a5 (swap R and B)

	int r = (col >> 16) & 0xFF;
	int b = col & 0xFF;
	return (col & 0xFF00FF00) | (b << 16) | r;
}/code] Can work both ways I think.

https://forum.sa-mp.com/showthread.php?t=331647
 
Top