Packet help

Junior Spellweaver
Joined
Oct 23, 2006
Messages
111
Reaction score
0
I am working on the storage code atm. I have the packet 7ad but I don't know how to get the contents of the packet. I am a good Java Programmer, but never did anything with packets. Does anyone have a way of logging the packets?
 
Here is a bit of storage information for you... First is a log of a few packets for it and the second is a basic storage function only allows you to open storage as of right now...

Code:
open storage
[3]<<7ad- 00
[3]>>7ad- 01 00

deposit bamboo spear from slot 2 inventory to slot 1 storage
[3]<<7ae- 00 0d 28 14 00 46 c4 00 00
[3]>>7ae- 0d 00 00 00 00 00 00 00 00 00 28 14 00 46 c4 00 1e 02 00 00 00 00 00 00

withdraw bamboo spear from slot 1 storage to slot 2 inventory
[3]<<7ae- 01 00 28 14 00 46 c4 00 00
[3]>>7ae- 0d 00 00 00 28 14 00 46 c4 00 00 00 00 00 00 00

deposit soldier gloves from slot 2 inventory to slot 1 storage
[3]<<7ae- 00 0e e4 03 00 36 e8 03 00
[3]>>7ae- 0e 00 00 00 00 00 00 00 00 00 e4 03 00 36 e8 03 17 02 00 00 00 00 00 00

Withdraw soldier gloves from slot 1 storage to slot 2 inventory
[3]<<7ae- 01 00 e4 03 00 36 e8 03 00
[3]>>7ae- 0e 00 00 00 e4 03 00 36 e8 03 00 00 00 00 00 00

deposit 1 junon return scroll from slot 42 inventory to slot 13 storage
[3]<<7ae- 00 2e 0a 2c 01 00 00 00 00
[3]>>7ae- 2e 00 0c 00 0a 2c 04 00 00 00 0a 2c 01 00 00 00 33 06 00 00 00 00 00 00

deposit 1 junon return scroll from slot 42 inventory to slot 14 storage
[3]<<7ae- 00 2e 0a 2c 01 00 00 00 00
[3]>>7ae- 2e 00 0d 00 0a 2c 04 00 00 00 0a 2c 01 00 00 00 5d 06 00 00 00 00 00 00

Code:
bool CWorldServer::pakOpenStorage(CWorldClient* thisclient, CPacket* P )
{
	BEGINPACKET(pak,0x7ad);
	ADDBYTE(pak, 1);
	ADDBYTE(pak, 0);
	thisclient->SendPacket(&pak);
	return true;
}
bool CWorldServer::pakStorage(CWorldClient* thisclient, CPacket* P )
{
	switch( GETBYTE((*P), 0x0))
	{
	case 0: //Deposit
		{
			Log(MSG_WARNING, "Deposit: %02x %02x %02x %02x %02x %02x %02x %02x %02x",GETBYTE((*P),0x0),GETBYTE((*P),0x1),GETBYTE((*P),0x2),GETBYTE((*P),0x3),GETBYTE((*P),0x4),GETBYTE((*P),0x5),GETBYTE((*P),0x6),GETBYTE((*P),0x7),GETBYTE((*P),0x8));
			/*BEGINPACKET(pak,0x7ae);
			ADDBYTE(pak, GETBYTE((*P),0x1) ); //Wtf is this?
			ADDBYTE(pak, 0 );
			ADDBYTE(pak, );
			ADDBYTE(pak, GETBYTE((*P),0x2) ); //Item ID?
			ADDBYTE(pak, GETBYTE((*P),0x3) ); //Item ID?*/
			
		}
		break;
	case 1: //Withdraw
		{
		}
		break;
	default:
		Log(MSG_NOTICE,"Invalid storage action by %c",thisclient->charname);
	}
	return true;
}
 
lol, you dont need to.
Since I'm quitting rose now (i didnt code for a month or so) and I'm going over to coding my own 3D-MMORPG with some friends, im releasing more and more parts of my code here. later, ill release all my source, it has everything the svn has,
Code:
+ full clan system (except clan skills&points)
+ custom clan images (upload and download)
+ AoE skills
+ learning and lvling skills
+ non-attacking mob movement
+ full drop table
+ private shops almost 100% done, only selling an item to a shop doesnt work yet, but its almost done, quitted when i was coding this =P (its pretty easy to finish it though)
+ party chat
+ clan chat
+ buddy system 100% working
+ party system has some coded things, not done though, but better than the svns one
+ dance scrolls
+ private shop and clan info visibility at pakSpawnChar
+ some starts to the arrow/bullet packet, its working, but buggy
+ many more useful gm commands
+ saving respawn point
+ going back to saved point / current field
+ a function to read out unknown packets fully
+ a MUCH faster and smoother server, its running almost 3 times faster than the svn's one (at least at my comp)
+ ammos are decreased when attacking with an ammo weapon
+ tons of bugfixes and improvements
+ muuuchh more i cant remember

Custom Tools:
+ STB2SQL converter, reads a whole stb file and puts it to your MySQL db
+ NewsEditor for news page
+ my very much better database
+ i have the full sourcecode for 100% implementing TriggerVFS.dll (for game data files)
+ some starts of a launcher coded in Borland C++ Builder 6, including lua scripts for updating etc, not complete working though
Well, after that big list, lemme release my storage code...
CODE:
Code:
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
\\########################################################################################//        
//######################################   CaaliSoft-Rose   ######################################\\        
\\########################################################################################//        
//#####################################   (c)2006 by Caali    #####################################\\        
\\########################################################################################//        
//########################################################################################\\        
\\#######################  Description: "This file adds the full support of [MyStorage]."  #########################//        
//########################################################################################\\        
\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//

// -----------------------------------------------------------------------------
// in worldpackets.cpp, add
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// Open [MyStorage] (c)2006 by Caali
// -----------------------------------------------------------------------------
bool CWorldServer::pakOpenStorage(CWorldClient* thisclient, CPacket* P)
{
    unsigned itemcount = 0;
    for(unsigned i=0;i<160;i++){ if( thisclient->storage.items[i].count > 0 ) { itemcount++; } }

    BEGINPACKET( pak, 0x7ad );
    ADDBYTE( pak, 0x00 ); //dunno
    ADDBYTE( pak, itemcount ); //itemcount
    for(unsigned i=0;i<160;i++)
    {
        if( thisclient->storage.items[i].count>0 )
        {
            ADDBYTE( pak, i ); //slot
            ADDDWORD( pak, BuildItemHead( thisclient->storage.items[i] ) ); //head
            ADDDWORD( pak, BuildItemData( thisclient->storage.items[i] ) ); //data
        }
    }
    ADDQWORD( pak, thisclient->storage.zuly ); //zuly
    thisclient->SendPacket( &pak );
    return true;
}
// -----------------------------------------------------------------------------
// Zuly at [MyStorage] (c)2006 by Caali
// -----------------------------------------------------------------------------
bool CWorldServer::pakStorageZuly(CWorldClient* thisclient, CPacket* P)
{
    unsigned char mode = GETBYTE( (*P), 0x00 );
    switch( mode )
    {
        case 0x10: //Deposit Zuly
        {
            long long amount = GETQWORD( (*P), 0x01 );
            if( amount > thisclient->c_zuly ) return true;
            thisclient->c_zuly -= amount;
            thisclient->storage.zuly += amount;

            BEGINPACKET( pak, 0x7da );
            ADDQWORD( pak, thisclient->c_zuly );
            ADDQWORD( pak, thisclient->storage.zuly );
            thisclient->SendPacket( &pak );
        }
        break;
        case 0x11: //Withdraw Zuly
        {
            long long amount = GETQWORD( (*P), 0x01 );
            if( amount > thisclient->storage.zuly ) return true;
            thisclient->c_zuly += amount;
            thisclient->storage.zuly -= amount;

            BEGINPACKET( pak, 0x7da );
            ADDQWORD( pak, thisclient->c_zuly );
            ADDQWORD( pak, thisclient->storage.zuly );
            thisclient->SendPacket( &pak );
        }
        break;
    }
    return true;
}
// -----------------------------------------------------------------------------
// Item at [MyStorage] (c)2006 by Caali
// -----------------------------------------------------------------------------
bool CWorldServer::pakStorageItem(CWorldClient* thisclient, CPacket* P)
{
    unsigned char mode = GETBYTE( (*P), 0x00 ); //00: Deposit 01: Withdraw
    switch( mode )
    {
        case 0x00: //Deposit an item
        {
            unsigned char inventoryslot = GETBYTE( (*P), 0x01 );
            unsigned char storageslot = thisclient->GetNewStorageItemSlot( thisclient->items[inventoryslot] );
            unsigned amount;
            if( thisclient->items[inventoryslot].itemtype < 10 && thisclient->items[inventoryslot].itemtype > 12 )
            {
                amount = 1;
            }
            else
            {
                amount = GETDWORD( (*P), 0x06 );
            }
            if( amount <=  0 ) return true;
            if( amount > 999 ) amount = 1;

            long long storagefee = STB_ITEM[thisclient->items[inventoryslot].itemtype-1].rows[thisclient->items[inventoryslot].itemnum][5]*amount/200;
            if( storagefee > thisclient->c_zuly ) return true;
            if( storageslot == 0xffff ) return true;

            if( thisclient->items[inventoryslot].itemtype >= 10 && thisclient->items[inventoryslot].itemtype <= 12 )
            {
                if( thisclient->storage.items[storageslot].count > 0 )
                {
                    thisclient->storage.items[storageslot].count += amount;
                }
                else
                {
                    thisclient->storage.items[storageslot] = thisclient->items[inventoryslot];
                    thisclient->storage.items[storageslot].count = amount;
                }
                unsigned tmpcount;
                if( thisclient->storage.items[storageslot].count > 999 )
                {
                    tmpcount = thisclient->storage.items[storageslot].count-999;
                    thisclient->storage.items[storageslot].count = 999;
                }
                else
                {
                    tmpcount = 0;
                }
                thisclient->items[inventoryslot].count -= (amount-tmpcount);
            }
            else
            {
                thisclient->storage.items[storageslot] = thisclient->items[inventoryslot];
                thisclient->storage.items[storageslot].count = 1;
                thisclient->items[inventoryslot].count = 0;
            }
            if(thisclient->items[inventoryslot].count <= 0) ClearItem(thisclient->items[inventoryslot]);

            thisclient->c_zuly -= storagefee;

            BEGINPACKET( pak, 0x7ae );
            ADDBYTE( pak, inventoryslot ); //inventory-slot
            ADDBYTE( pak, 0x00 ); //??
            ADDBYTE( pak, storageslot ); //storage-slot
            ADDBYTE( pak, 0x00 ); //??
            ADDDWORD( pak, BuildItemHead( thisclient->items[inventoryslot] ) ); //inventory-itemhead
            ADDDWORD( pak, BuildItemData( thisclient->items[inventoryslot] ) ); //inventory-amount
            ADDDWORD( pak, BuildItemHead( thisclient->storage.items[storageslot] ) ); //storage-itemhead
            ADDDWORD( pak, BuildItemData( thisclient->storage.items[storageslot] ) ); //storage-amount
            ADDQWORD( pak, thisclient->c_zuly ); //zuly
            thisclient->SendPacket( &pak );
        }
        break;

        case 0x01: //Withdraw an item
        {
            unsigned char storageslot = GETBYTE( (*P), 0x01 );
            unsigned char inventoryslot = thisclient->GetNewItemSlot( thisclient->storage.items[storageslot] );
            if(inventoryslot == 0xffff) return true;
            unsigned amount;
            if( thisclient->storage.items[storageslot].itemtype < 10 && thisclient->storage.items[storageslot].itemtype > 12 )
            {
                amount = 1;
            }
            else
            {
                amount = GETDWORD( (*P), 0x06 );
            }
            if( amount <= 0 ) return true;
            if( amount > 999 ) amount = 1;

            if( thisclient->storage.items[storageslot].itemtype >= 10 && thisclient->storage.items[storageslot].itemtype <= 12 )
            {
                if( thisclient->items[inventoryslot].count > 0 )
                {
                    thisclient->items[inventoryslot].count += amount;
                }
                else
                {
                    thisclient->items[inventoryslot] = thisclient->storage.items[storageslot];
                    thisclient->items[inventoryslot].count = amount;
                }
                unsigned tmpcount;
                if( thisclient->items[inventoryslot].count > 999 )
                {
                    tmpcount = thisclient->items[inventoryslot].count-999;
                    thisclient->items[inventoryslot].count = 999;
                }
                else
                {
                    tmpcount = 0;
                }
                thisclient->storage.items[storageslot].count -= (amount-tmpcount);
            }
            else
            {
                thisclient->items[inventoryslot] = thisclient->storage.items[storageslot];
                thisclient->items[inventoryslot].count = 1;
                thisclient->storage.items[storageslot].count = 0;
            }
            if(thisclient->items[inventoryslot].count > 999) thisclient->items[inventoryslot].count = 999;
            if(thisclient->storage.items[storageslot].count <= 0) ClearItem(thisclient->storage.items[storageslot]);

            BEGINPACKET( pak, 0x7ae );
            ADDBYTE( pak, inventoryslot ); //inventory-slot
            ADDBYTE( pak, 0x00 ); //??
            ADDBYTE( pak, storageslot ); //storage-slot
            ADDBYTE( pak, 0x00 ); //??
            ADDDWORD( pak, BuildItemHead( thisclient->items[inventoryslot] ) ); //inventory-itemhead
            ADDDWORD( pak, BuildItemData( thisclient->items[inventoryslot] ) ); //inventory-amount
            ADDDWORD( pak, BuildItemHead( thisclient->storage.items[storageslot] ) ); //storage-itemhead
            ADDDWORD( pak, BuildItemData( thisclient->storage.items[storageslot] ) ); //storage-amount
            ADDQWORD( pak, thisclient->c_zuly ); //zuly
            thisclient->SendPacket( &pak );
        }
        break;
    }

    return true;
}


// -----------------------------------------------------------------------------
// in datatypes.h, add
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// A player-storage (c)2006 by Caali
// -----------------------------------------------------------------------------
struct CStorage {
    long long zuly;
    CItem items[160]; //40 per page
};


// -----------------------------------------------------------------------------
// in WorldServer.cpp, at OnRecievePacket, add
// -----------------------------------------------------------------------------

        case 0x07ad: return pakOpenStorage      ((CWorldClient*)thisclient, P); 
        case 0x07ae: return pakStorageItem    ((CWorldClient*)thisclient, P); 
        case 0x07da: return pakStorageZuly      ((CWorldClient*)thisclient, P);

// -----------------------------------------------------------------------------
// in worldsockets.h, find
// -----------------------------------------------------------------------------

    unsigned GetNewItemSlot( CItem thisitem );

// -----------------------------------------------------------------------------
// after, add
// -----------------------------------------------------------------------------

    unsigned GetNewStorageItemSlot( CItem thisitem );
    bool platinum;
    CStorage storage;

// -----------------------------------------------------------------------------
// in worldsockets.h, find
// -----------------------------------------------------------------------------

     void pakCreate71b        ( CWorldClient *thisclient );

// -----------------------------------------------------------------------------
// after, add
// -----------------------------------------------------------------------------

    bool pakOpenStorage        ( CWorldClient* thisclient, CPacket* P );
    bool pakStorageZuly        ( CWorldClient* thisclient, CPacket* P ); 
    bool pakStorageItem        ( CWorldClient* thisclient, CPacket* P );

// -----------------------------------------------------------------------------
// in worldclient.cpp, go to CWorldClient::loaddata()
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// at the functions bottom, add
// -----------------------------------------------------------------------------

    ParentServer->DoSQL("SELECT storage_zuly,platinum FROM accounts WHERE id=%i", userid );
    result = mysql_store_result( ParentServer->mysql );
    row = mysql_fetch_row( result );

    storage.zuly = atoi( row[0] );
    switch(atoi(row[1]))
    {
        case 0: platinum = false;
        case 1: platinum = true;
        default: platinum = false;
    }
    
    mysql_free_result(result);

    ParentServer->DoSQL("SELECT slotnum, itemnum, itemtype, refine, durability, lifespan, count, stats, socketed, appraised FROM storage WHERE accountid=%i", userid );
    result = mysql_store_result( ParentServer->mysql );

    while(row = mysql_fetch_row(result)) {
        unsigned slotnum = atoi(row[0]);
        storage.items[slotnum].itemnum = atoi(row[1]);
        storage.items[slotnum].itemtype = atoi(row[2]);
        storage.items[slotnum].refine = atoi(row[3]);
        storage.items[slotnum].durability = atoi(row[4]);
        storage.items[slotnum].lifespan = atoi(row[5]);
        storage.items[slotnum].count = atoi(row[6]);
        storage.items[slotnum].stats = atoi(row[7]);
        storage.items[slotnum].socketed = (atoi(row[8])==1)?true:false;
        storage.items[slotnum].appraised = (atoi(row[9])==1)?true:false;
    }
    mysql_free_result(result);

// -----------------------------------------------------------------------------
// in worldclient.cpp, go to CWorldClient::savedata()
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// at the functions bottom, add
// -----------------------------------------------------------------------------

    ParentServer->DoSQL("UPDATE accounts SET storage_zuly=%llu WHERE id=%i", this->storage.zuly, this->userid );
    ParentServer->DoSQL("DELETE FROM storage WHERE accountid=%i", this->userid );
    for(unsigned i=0;i<160;i++) {
        if (this->storage.items[i].itemtype != 0) {
            ParentServer->DoSQL("INSERT INTO storage (accountid,itemnum,itemtype,refine,durability,lifespan, \
            slotnum,count,stats,socketed,appraised) VALUES(%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i)", \
            this->userid, this->storage.items[i].itemnum, this->storage.items[i].itemtype,this->storage.items[i].refine, this->storage.items[i].durability, \
            this->storage.items[i].lifespan, i, this->storage.items[i].count, this->storage.items[i].stats, (this->storage.items[i].socketed?1:0), (this->storage.items[i].appraised?1:0));
        }
    }

// -----------------------------------------------------------------------------
// in worldclient.cpp, go to the end of file and add
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// Returns the id of an empty storage slot based on item type, 0xffff if no such slot exists (c)2006 by Caali
// -----------------------------------------------------------------------------
unsigned CWorldClient::GetNewStorageItemSlot(CItem thisitem)
{
    char itemtypes[15] = {4,0,0,0,0,0,0,0,0,0,1,2,2,4,3};
    unsigned char itemtab = itemtypes[thisitem.itemtype];

    if (itemtab >= 4) return 0xffff;
    if (thisitem.itemtype >= 10 && thisitem.itemtype <= 13) //Stackable 
    {
        for(unsigned j = 0; j < 160; j++) 
        {
            if ((storage.items[j].itemnum == thisitem.itemnum && storage.items[j].itemtype == thisitem.itemtype && storage.items[j].count < 999))
            {
                if( j < 120 || (j > 119 && platinum) )
                    return j;
            }
        }
    }
    for(unsigned j = 0; j < 160; j++) 
    {
        if (storage.items[j].itemnum == 0)
        {
            if( j < 120 || (j > 119 && platinum) )
                return j;
        }
    }
    return 0xffff;
}
DATABASE:
Code:
//---------------------------------------------------------------------------------------------
//                                         DATABASE
//---------------------------------------------------------------------------------------------

DROP TABLE IF EXISTS `storage`;
CREATE TABLE `storage` (
  `accountid` int(11) NOT NULL,
  `slotnum` int(11) NOT NULL,
  `itemnum` int(11) NOT NULL,
  `itemtype` int(11) NOT NULL,
  `refine` int(11) NOT NULL,
  `durability` int(11) NOT NULL,
  `lifespan` int(11) NOT NULL,
  `count` int(11) NOT NULL,
  `stats` int(11) NOT NULL,
  `socketed` tinyint(4) NOT NULL,
  `appraised` tinyint(4) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


in the account table, add this:

ALTER TABLE `accounts` 
ADD `storage_zuly` INT UNSIGNED NOT NULL DEFAULT '0',
ADD `platinum` INT UNSIGNED NOT NULL DEFAULT '0';
Do with it what you want, but dont remove my credits.

FYI:
It is possible that some variables are wrong, its because i almost rewrote my database structure and my server structure, thats why its so much smoother and faster now. You'll have to correct them, unless you are gonna wait for me to release the rest of my source.

P.S.:
Guys, have fun with it.
 
lol, now you tell me. I was about 75% done. That was a big waste of time. I could have been working on homework. lol. Thanks Caali.
 
+ full clan system (except clan skills&points)
+ custom clan images (upload and download)
+ AoE skills
+ learning and lvling skills
+ non-attacking mob movement
+ full drop table
+ private shops almost 100% done, only selling an item to a shop doesnt work yet, but its almost done, quitted when i was coding this =P (its pretty easy to finish it though)
+ party chat
+ clan chat
+ buddy system 100% working
+ party system has some coded things, not done though, but better than the svns one
+ dance scrolls
+ private shop and clan info visibility at pakSpawnChar
+ some starts to the arrow/bullet packet, its working, but buggy
+ many more useful gm commands
+ saving respawn point
+ going back to saved point / current field
+ a function to read out unknown packets fully
+ a MUCH faster and smoother server, its running almost 3 times faster than the svn's one (at least at my comp)
+ ammos are decreased when attacking with an ammo weapon
+ tons of bugfixes and improvements
+ muuuchh more i cant remember

OMFG Caali i'm sooooo impressed!
 
lol, now you tell me. I was about 75% done. That was a big waste of time. I could have been working on homework. lol. Thanks Caali.

well, this packet is damn easy :) it took me about 30min to code all that ****, including understanding what which byte means =P

e.g. , clan system is MUCH more :)

@nGage: thats not much, only about a month... (1,5 weeks for getting and understanding the code, the rest for getting&understanding packets, coding takes like some minutes...)
 
Last edited:
well, this packet is damn easy :) it took me about 30min to code all that ****, including understanding what which byte means =P

Yeah thats about how long i've been working on it too. But I'm also watching Scrubs. I fixed some things in your code and will post it on the SVN (with credits to you). Kudos.
 
there is nothing to teach.

it requires

1) Knowledge of C++
2) A brain & logical thinking.

[no_offense_,_but]
when i read your posts, it seems to me you have neither 1) nor 2), so you should nvm...
[/no_offense_,_but]
 
Last edited:
you're right caali but i learn fast and i'm reading books etc so give me some time =P
if you're reading books, as i said thousands of times, start with eaiser projects.

and no, im not going to open a server, i left rose some months ago, just releasing some **** now
 
Back