• Unfortunately, we have experienced significant hard drive damage that requires urgent maintenance and rebuilding. The forum will be a state of read only until we install our new drives and rebuild all the configurations needed. Please follow our Facebook page for updates, we will be back up shortly! (The forum could go offline at any given time due to the nature of the failed drives whilst awaiting the upgrades.) When you see an Incapsula error, you know we are in the process of migration.

Adding custom command and packets

Status
Not open for further replies.
Newbie Spellweaver
Joined
Jan 23, 2012
Messages
9
Reaction score
27
This isn't noob-proof. I only should what needs to be done. I whipped this up in about 20 minutes, so no bitching k.

1. Go to GunZ Solution -> Interface -> Base -> ZChat_Cmds.cpp

2. Look for the first wave of "void ChatCmd_..." code. (Should be near the top)

3. Add one that fits for your command name. I'll be using this:

Code:
void ChatCmd_CharInfo( const char* line, const int argc, char** const argv );

4. Go into the ZChat::InitCmds() function and scroll to the bottom of it.

5. Add this line:

Code:
_CC_AC( "charinfo", &ChatCmd_CharInfo, CCF_ADMIN, ARGVNoMin, 2, true, "/charinfo", "" );

/*
1st param = name of command
2nd param = callback for command
3rd param = flag (admin use only, lobby use only, etc.)
4th param = Minimum arguments
5th param = Maximum arguments
6th param = Repeat Enabled
7th param = Usage
8th param = Help
*/

6. Scroll all the way to the bottom of the file, and add this:

Code:
void ChatCmd_CharInfo( const char* line, const int argc, char** const argv )
{
}


7. Go to CSCommon -> SharedCommand folder -> MSharedCommandTable.h

8. Scroll all the way to the bottom (but before the #endif) and add this:

Code:
#define MC_ADMINCMD_REQUEST_CHAR_INFO		70000
#define MC_ADMINCMD_RESPONSE_CHAR_INFO		70001

9. Open MSharedCommandTable.cpp, scroll all the way to the bottom (but before the END_CMD_DESC();)
and add this:

Code:
C( MC_ADMINCMD_REQUEST_CHAR_INFO, "AdminCmd.Request.Char.Info", "Whatever.", MCDT_MACHINE2MACHINE )
    P( MPT_UID, "uidPlayer" )
    P( MPT_STR, "szName" )

C( MC_ADMINCMD_RESPONSE_CHAR_INFO, "AdminCmd.Response.Char.Info", "Whatever.", MCDT_MACHINE2MACHINE )
    P( MPT_BLOB, "pBlob" )

10. Go to the GunZ Solution -> Network -> ZPost.h, scroll all the way to the bottom (but before the #edif -- for fucks sake)
and add this:

Code:
inline void ZPostAdminCmdRequestCharInfo( const MUID& uidPlayer, const char* szName )
{
    ZPOSTCMD2( MC_ADMINCMD_REQUEST_CHAR_INFO, MCmdParamUID(uidPlayer), MCmdParamStr(szName) );
}

11. Go back to ZChat_Cmds.cpp, back to the last line we added and add this:

Code:
void ChatCmd_CharInfo( const char* line, const int argc, char** const argv )
{
	if( argc < 2 )
	{
		OutputCmdWrongArgument( argv[0] );
		return;
	}

	if( strlen(argv[1]) > 16 )
	{
		ZChatOutput( "Name must be 16 letters or less." );
		return;
	}

	char szPlayerName[16];
	strcpy( szPlayerName, argv[1] );

	ZPostAdminCmdRequestCharInfo( ZGetGameClient()->GetPlayerUID(), szPlayerName );
}

The fun part.
12. Go to Gunz Solution -> Network -> ZGameClient.h, scroll near the bottom of the class and add this:

Code:
void OnAdminCmdResponseCharInfo( void* pBlob );
(Note; put it underneath "OnAdminResponseMutePlayer( ... );")

13. Open ZGameClient.cpp, scroll to the bottom and add this:

Code:
void ZGameClient::OnAdminCmdResponseCharInfo( void* pBlob )
{
	char szBuffer[128] = { 0 };
	unsigned long nCID = 0;
	unsigned long nBP = 0;
	unsigned long nXP = 0;

	nCID = (unsigned long)MGetBlobArrayElement( pBlob, 0 );
	nBP = (unsigned long)MGetBlobArrayElement( pBlob, 1 );
	nXP = (unsigned long)MGetBlobArrayElement( pBlob, 2 );

	sprintf( szBuffer, "CID: %d\nBP: %d\nXP: %d\n", nCID, nBP, nXP );
	ZChatOutput( szBuffer );
}

14. Open ZGameClient_OnCommand.cpp and scroll to the "MC_ADMIN_RESPONSE_MUTE_PLAYER" switch clause

15. Underneath it, add this:

Code:
		case MC_ADMINCMD_RESPONSE_CHAR_INFO:
			{
				//void* pBlob = pCommand->GetParameter( 0 )->GetPointer();
				//Note; you should probably add a check to see if it is a blob first. like so.
				MCommandParameter* pParam = pCommand->GetParameter( 0 );
				if( pParam->GetType() != MPT_BLOB )
					break;

				OnAdminCmdResponseCharInfo( pParam->GetPointer() );
			}

16. Open CSCommon solution -> MatchServer -> MMatchServer -> MMatchServer.h and
add this near the end of the class:

Code:
void OnRequestAdminCmdCharInfo( const MUID& uidPlayer, const char* szPlayerName );

17. Open MMatchServer.cpp and add this near the end:

Code:
void MMatchServer::OnRequestAdminCmdCharInfo( const MUID& uidPlayer, const char* szPlayerName )
{
	MMatchObject* pObject = GetObject( uidPlayer );

	if( pObject )
	{
		if( IsAdminGrade( pObject ) )
		{
			MMatchObject* pTarget = GetPlayerByName( szPlayerName );

			if( pTarget )
			{
				unsigned long nCID, nBP, nXP = 0;

				nCID = pTarget->GetCharInfo()->m_nCID;
				nBP = pTarget->GetCharInfo()->m_nBP;
				nXP = pTarget->GetCharInfo()->m_nXP;

				void* pBlob = MMakeBlobArray( sizeof(unsigned long) * 3, 3 );

				unsigned char* pCpy = (unsigned char*)MGetBlobArrayElement( pBlob, 0 );
				CopyMemory( pCpy, &nCID, sizeof(unsigned long) );
				pCpy = (unsigned char*)MGetBlobArrayElement( pBlob, 1 );
				CopyMemory( pCpy, &nBP, sizeof(unsigned long) );
				pCpy = (unsigned char*)MGetBlobArrayElement( pBlob, 2 );
				CopyMemory( pCpy, &nXP, sizeof(unsigned long) );

				MCommand* pCmd = CreateCommand( MC_ADMINCMD_RESPONSE_CHAR_INFO, pObject->GetUID() );

				if( pCmd )
				{
					pCmd->AddParameter( new MCommandParameterBlob( pBlob, MGetBlobArraySize(pBlob) ) );
					MEraseBlobArray( pBlob );

					MMatchServer::GetInstance()->RouteToListener( pObject, pCmd );
				}
			}
		}
	}
}

18. Go to MMatchServer_OnCommand, scroll near to the bottom of the switch clause and
add this:

Code:
		case MC_ADMINCMD_REQUEST_CHAR_INFO:
			{
				MUID uidPlayer;
				char szPlayerName[16] = { 0 };

				pCommand->GetParameter( &uidPlayer, 0, MPT_UID );
				pCommand->GetParameter( szPlayerName, 1, MPT_STR, 16 );

				OnRequestAdminCmdCharInfo( uidPlayer, szPlayerName );
				break;
			}

I think I tagged everything. Hopefully, I'm running late as it is, if not, well, you will understand 99% of it lol. Look out for my other tutorials coming:
-Admin Console, AES on packets and SHA1 checks

P.S: It'll only work if the player is online.
 
2D > 3D
Loyal Member
Joined
Dec 19, 2008
Messages
2,413
Reaction score
1,193
This is wonderful to see

.-. maybe we will see some OC now?

(nope.jpg)

You can only hope though ^^
 
Skilled Illusionist
Joined
Apr 3, 2009
Messages
323
Reaction score
2
nice stuff man :) how would i do this though im totaly new to c++ could you teach me or somthing
 
2D > 3D
Loyal Member
Joined
Dec 19, 2008
Messages
2,413
Reaction score
1,193
nice stuff man :) how would i do this though im totaly new to c++ could you teach me or somthing

there is absolutely no way you can make this any more
"new" friendly. You copy and paste his codes wherever
he said, compile, end. If you cant get this, just dont
worry about it .-..
 
Skilled Illusionist
Joined
Apr 3, 2009
Messages
323
Reaction score
2
ok is there any one who would do it for me and if yes how much for 1 command? like killstreaks
 
Junior Spellweaver
Joined
Oct 30, 2011
Messages
117
Reaction score
16
i've disconnected every time I use this command
ps: the player that i want to get the info is online
 
Newbie Spellweaver
Joined
Jan 23, 2012
Messages
9
Reaction score
27
I think I fucked up on the response function in MatchServer. I'll check up on it when I have access to my computer. (P.S - that specific command was supposed to be used as an example only..)
 
Experienced Elementalist
Joined
Jan 7, 2011
Messages
262
Reaction score
54
In ZChat_Cmds why did you declare two times ChatCmd_CharInfo ?
 
Status
Not open for further replies.
Back
Top