[DEV] Shop Packet Development - DFlyFF

Status
Not open for further replies.
Joined
Sep 9, 2008
Messages
1,947
Reaction score
390
Alright. Its dev time people. I know a lot of you are working on the dragon source but not a lot are sharing what they have accompllished. Whether or not its because people might steal your work, I think I should point out that this is open source so its work from everyone. A lot of people have contributed so why not you. Thats why I am starting this thread so everyone can get some shops going.

The main problem is getting a container that can expand and deflate normally without memory leakage. The next step is loading it from an outside file like a text file or MySQL (which I don't recommend).

After that we need to pick a place to load it. Would you like you load at server startup or when you click the NPC and open the shop.

My earlier attempts at this result in a memory leak and eventual crash due to the container staying in memory and not emptying on exit.

So now I am going to repost the packet structure for the Shop. many have seen this but a lot are clueless on this part.

[5e]

[INT-Length]

[00 FF FF FF]

[01 00]

[03 00 00 00] --> NPC Spawn ID (I think it tells what shop to open)

[14 00] ---> Call Shop window Command

[00 00 00 00]

[01 -> 63 00 00 00] ------> 01 00 00 00 to 63 00 00 00 changing the first byte consecutively in hex

[NUMBER OF SLOTS SHORT-INT] -----> Determins how many slots for items on the page

[00 00 00 00] --> Unknown possibly slot number?

[INT-ITEM ID] --> ID of the item (1D = Petal Sword)

[00] x 8

[INT-Quantity] --> I believe this is how many items are in the slot

[NOTE #1] --> This two byte int is an ID for the item type. in this case DD 6D represents Mercenary Sword (I think)

[00] x 40

[01] ---> Next slot
so this is a basic structure. Thus MUST loop for every item on each page. each page is separated by the 00-63 ints loops.

check back often as this will be updated as I get farther and/or people donate their two cents into this development.

once the system is established I am going to write a simple editor for the shops.

C# structure by Adidishen

Code:
[COLOR=#000000][COLOR=#0000bb]Packet pak [/COLOR][COLOR=#007700]= new [/COLOR][COLOR=#0000bb]Packet[/COLOR][COLOR=#007700]();
            [/COLOR][COLOR=#0000bb]pak[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]StartNewMergedPacket[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]npc_moverid[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]PAK_NPC_SHOP[/COLOR][COLOR=#007700]); [/COLOR][COLOR=#ff8000]// PAK_NPC_SHOP = 0x0014
            [/COLOR][COLOR=#007700]for ([/COLOR][COLOR=#0000bb]int tab [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]0[/COLOR][COLOR=#007700]; [/COLOR][COLOR=#0000bb]tab [/COLOR][COLOR=#007700]< [/COLOR][COLOR=#0000bb]4[/COLOR][COLOR=#007700]; [/COLOR][COLOR=#0000bb]tab[/COLOR][COLOR=#007700]++)
            {
                for ([/COLOR][COLOR=#0000bb]int i [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]0[/COLOR][COLOR=#007700]; [/COLOR][COLOR=#0000bb]i [/COLOR][COLOR=#007700]< [/COLOR][COLOR=#0000bb]100[/COLOR][COLOR=#007700]; [/COLOR][COLOR=#0000bb]i[/COLOR][COLOR=#007700]++)
                    [/COLOR][COLOR=#0000bb]pak[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Addint[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]i[/COLOR][COLOR=#007700]);
                [/COLOR][COLOR=#0000bb]pak[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Addbyte[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]nsd[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]tabinfo[/COLOR][COLOR=#007700][[/COLOR][COLOR=#0000bb]tab[/COLOR][COLOR=#007700]]); [/COLOR][COLOR=#ff8000]// amount of items.
                [/COLOR][COLOR=#007700]if ([/COLOR][COLOR=#0000bb]nsd[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]shopitems[/COLOR][COLOR=#007700][[/COLOR][COLOR=#0000bb]tab[/COLOR][COLOR=#007700]] != [/COLOR][COLOR=#0000bb]null[/COLOR][COLOR=#007700])
                {
                    for ([/COLOR][COLOR=#0000bb]int i [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]0[/COLOR][COLOR=#007700]; [/COLOR][COLOR=#0000bb]i [/COLOR][COLOR=#007700]< [/COLOR][COLOR=#0000bb]nsd[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]shopitems[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Length[/COLOR][COLOR=#007700]; [/COLOR][COLOR=#0000bb]i[/COLOR][COLOR=#007700]++)
                    {
                        if ([/COLOR][COLOR=#0000bb]nsd[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]shopitems[/COLOR][COLOR=#007700][[/COLOR][COLOR=#0000bb]tab[/COLOR][COLOR=#007700]][[/COLOR][COLOR=#0000bb]i[/COLOR][COLOR=#007700]] == [/COLOR][COLOR=#0000bb]null[/COLOR][COLOR=#007700])
                            continue;
                        [/COLOR][COLOR=#0000bb]NPCShopItem si [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]nsd[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]shopitems[/COLOR][COLOR=#007700][[/COLOR][COLOR=#0000bb]tab[/COLOR][COLOR=#007700]][[/COLOR][COLOR=#0000bb]i[/COLOR][COLOR=#007700]];
                        [/COLOR][COLOR=#0000bb]Item item [/COLOR][COLOR=#007700]= new [/COLOR][COLOR=#0000bb]Item[/COLOR][COLOR=#007700]();
                        [/COLOR][COLOR=#0000bb]item[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]itemid [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]si[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]id[/COLOR][COLOR=#007700];
                        [/COLOR][COLOR=#0000bb]item[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]quantity [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]si[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]quantity[/COLOR][COLOR=#007700];
                        [/COLOR][COLOR=#0000bb]pak[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Addbyte[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]i[/COLOR][COLOR=#007700]);
                        [/COLOR][COLOR=#0000bb]pak[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Addint[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]i[/COLOR][COLOR=#007700]);
                        [/COLOR][COLOR=#0000bb]pak[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]AddItemData[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]item[/COLOR][COLOR=#007700]);
                    }
                }
                for ([/COLOR][COLOR=#0000bb]int i [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]0[/COLOR][COLOR=#007700]; [/COLOR][COLOR=#0000bb]i [/COLOR][COLOR=#007700]< [/COLOR][COLOR=#0000bb]100[/COLOR][COLOR=#007700]; [/COLOR][COLOR=#0000bb]i[/COLOR][COLOR=#007700]++)
                    [/COLOR][COLOR=#0000bb]pak[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Addint[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]i[/COLOR][COLOR=#007700]);
            }
            [/COLOR][COLOR=#0000bb]pak[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000bb]Send[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]this[/COLOR][COLOR=#007700]);  [/COLOR][/COLOR]
C++ structure by DFlyFF - GlaphanKing
Code:
for (int tab = 0; tab < 4; tab++)
    {
        for(i=0; i <100; i++)
            pak.addInt(i);

        for(unsigned int k=0; k < shopTabs[tab].size(); k++)
        {
            // process each tab
            if(shopTabs[tab].empty())
                continue;
            printf("Element %d\n", shopTabs[tab]);
            ItemBank* shopItem = ItemBanks::getItemBankById(shopTabs[tab].at(k));
            printf("Item created: %d Max Items: %d Endurance: %d\n", shopItem->id, shopItem->maxItems, shopItem->endurance);
            pak.addByte(k);
            pak.addInt(k);
            pak.addInt(shopItem->id);
            pak.addInt(0);
            pak.addInt(0);
            pak.addInt(shopItem->maxItems);
            pak.addInt(shopItem->endurance);
            pak.addInt64(0);
            pak.addInt64(0);
            pak.addInt64(0);
            pak.addInt64(0);
            pak.addInt(0);
            pak.addByte(0);
            pak.addShort(0);

        }
    }

I changed out the code for this one. I hope its the right structure.

--------------------------

So we have the structure which is easy to disect. Now we need to work on a container to hold the data. I am writing a file reader for the NPC shops and I will post it later. After we read the data it needs a container.

I was throwing some ideas around like multi arrays and vector of vector arrays, map hashes and the like. So far the easiest would have to be multi-dimensional arrays.

For example,

Code:
npcShop.ShopItems[i][j]
As you can see the element would be tab and [j] is the item id for the ItemBank to read from. So now here is a question to brood on: Is there an easier way? My answer is yes. If so, How can it be done? My answer is, you'll have to answer for yourself.

One point I want to make is I am not tailoring everything to the C++ server. i want it to be cross-platform compatible. I am not going to force one version on anyone. There is always a language more suited to you, so you would have a better time on your language once you have a guide to work on.

=============Upadate #2=======================

OK. so I wrote a little test program to parse a text file for each NPC that has a shop. First let me show you the text file.

Code:
7 21 23 25 81 27 61 83
11 510 506 502 500 511 507 503 514 520 518 516
The first number indicates the size of the container. after that is the id of the item. For now I am going to be only using the id number for a clean item. We will get more into the custom ones later. One thing to point out is there should be no whitespace after the last number or on the line below. It causes a crash that I am not going to fix yet as this seems to work for now.

Here is the parser. I am going to integrate it into the code for the shop packet. Bear in mind this is a first test and there can be some unexpected glitches and bugs. Bear with me.

Code:
// Check these stdlibs.
#include "windows.h"
#include <string>
#include "tchar.h"
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int strval(char* buf){
    return atoi(buf);
}

void main()
{
    int count=0;
    string line;
    char* next_token;
    char* name;
    char filename[50]="NPC.txt";
    ifstream myfile;
    int i, j, slots, linenum = 0;
    myfile.open(filename);

    vector<int> tab1;
    vector<int> tab2;
    vector<int> tab3;
    vector<int> tab4;
    // If the file cannot be opened for some reason.
    if (myfile.fail())
    {
        printf("%s couldn't be read\n",filename);
        //system("pause");
        //exit(1);
    }
    else
    {
        // If the file is open start parsing the text line by line.
        if (myfile.is_open())
        {
            i=0;
            linenum++;
            while(!myfile.eof()) 
            {
                getline (myfile,line);
                slots = atoi(strtok_s((char*)line.c_str(), " ", &next_token));
                //strtok_s(NULL, " ", &next_token);
                switch(linenum)
                {
                case 1: 
                    for(j = 0; j<slots;j++)
                    {
                        tab1.push_back(strval(strtok_s(NULL, " ", &next_token)));
                    }
                    linenum++;
                    break;
                case 2: 
                    for(j = 0; j<slots;j++)
                    {
                        tab2.push_back(strval(strtok_s(NULL, " ", &next_token)));
                    }
                    linenum++;
                    break;
                case 3: 
                    for(j = 0; j<slots;j++)
                    {
                        tab3.push_back(strval(strtok_s(NULL, " ", &next_token)));
                    }
                    linenum++;
                    break;
                case 4: 
                    for(j = 0; j<slots;j++)
                    {
                        tab4.push_back(strval(strtok_s(NULL, " ", &next_token)));
                    }
                    break;
                }
            }
            
        }

        myfile.close();
    }
    for(i=0;i<tab1.size();i++)
    {
        printf("%d ",tab1.at(i));
        printf("\n");
    }
    for(i=0;i<tab2.size();i++)
    {
        printf("%d ",tab2.at(i));
        printf("\n");
    }

    // clear vectors from memory
    tab1.clear();
    tab2.clear();
}
As you can see the code will run through the text file. expand the vectors according to the first number and then add the item ids into them one by one. when it reaches the end of the line it goes to the next until EOF (end of file). Experiment with the code and see if it works for you. Once I get the code integrated, I will begin to test the code live in the server. I will post the results then.

'Til next time. This is GlaphanKing signing off.
 
Last edited:
Would you like you load at server startup or when you click the NPC and open the shop
______________
loading from a file at runtime with lots of things to execute wouldnt be good.
In my opnion the best would be:
- Load everything, including the shops, we can think in a structure for it
- After everything load, open for players to login
- When someone clicks an npc shop, find the npc id at the shops and then shows for the player.
 
I'm pretty sure loading at startup would be a pretty bad idea.

Why not be idiotic and not make a loop, but do each slot manually. =D

Edit: Revisited the source, 4 slots? :(
 
PHP:
            Packet pak = new Packet();
            pak.StartNewMergedPacket(npc_moverid, PAK_NPC_SHOP); // PAK_NPC_SHOP = 0x0014
            for (int tab = 0; tab < 4; tab++)
            {
                for (int i = 0; i < 100; i++)
                    pak.Addint(i);
                pak.Addbyte(nsd.tabinfo[tab]); // amount of items.
                if (nsd.shopitems[tab] != null)
                {
                    for (int i = 0; i < nsd.shopitems.Length; i++)
                    {
                        if (nsd.shopitems[tab][i] == null)
                            continue;
                        NPCShopItem si = nsd.shopitems[tab][i];
                        Item item = new Item();
                        item.itemid = si.id;
                        item.quantity = si.quantity;
                        pak.Addbyte(i);
                        pak.Addint(i);
                        pak.AddItemData(item);
                    }
                }
                for (int i = 0; i < 100; i++)
                    pak.Addint(i);
            }
            pak.Send(this);

Have fun
 
PHP:
            Packet pak = new Packet();
            pak.StartNewMergedPacket(npc_moverid, PAK_NPC_SHOP); // PAK_NPC_SHOP = 0x0014
            for (int tab = 0; tab < 4; tab++)
            {
                for (int i = 0; i < 100; i++)
                    pak.Addint(i);
                pak.Addbyte(nsd.tabinfo[tab]); // amount of items.
                if (nsd.shopitems[tab] != null)
                {
                    for (int i = 0; i < nsd.shopitems.Length; i++)
                    {
                        if (nsd.shopitems[tab][i] == null)
                            continue;
                        NPCShopItem si = nsd.shopitems[tab][i];
                        Item item = new Item();
                        item.itemid = si.id;
                        item.quantity = si.quantity;
                        pak.Addbyte(i);
                        pak.Addint(i);
                        pak.AddItemData(item);
                    }
                }
                for (int i = 0; i < 100; i++)
                    pak.Addint(i);
            }
            pak.Send(this);

Have fun

Shouldn't you use :

PHP:
            Packet pak = new Packet();
            pak.StartNewMergedPacket(npc_moverid, PAK_NPC_SHOP); // PAK_NPC_SHOP = 0x0014
            for (int tab = 0; tab < 4; tab++)
            {
                for (int i = 0; i < 100; i++)
                    pak.Addint(i);
                pak.Addbyte(nsd.tabinfo[tab]); // amount of items.
                if (nsd.shopitems[tab] != null)
                {
                    for (int i = 0; i < nsd.shopitems.Length; i++)
                    {
                        if (nsd.shopitems[tab][i] == null)
                            continue;
                        NPCShopItem si = nsd.shopitems[tab][i];
                        Item item = new Item();
                        item.itemid = si.id;
                        item.quantity = si.quantity;
                        pak.Addbyte(i);
                        pak.Addint(i);
                        pak.AddItemData(item);
                       delete item; //here i avoid memory leak
                    }
                }
                for (int i = 0; i < 100; i++)
                    pak.Addint(i);
            }
            pak.Send(this);
delete pak;  //here i avoid memory leak

Have fun

For avoid memory leak ?
Thanks for your post ^^
 
Wait, so you can send that structure over and over again on the same packet and the client will read it?
 
[INT-ITEM ID] --> ID of the item (1D = Petal Sword)



hey glaphan king (this is because im clueless how these work but ho should it be sent out like ?

[INT-ITEM ID(id goes here)] or somthing like that ive seen you guys post these packet structures b4 but im not entirely sure what it should look like when actualy in use a structure is nice but I would probably need an example :[


like in the end what is sends out it say ?????(whatever goes here)??????(whatever goes here)

sorry to bug you guys but id like to understand more of what im working with :( im clueless how it works but I want to learn how just im clueless about all of it if i could figure out how this worked I could spend alot more time acomplishing more
 
lol I may not be good at starting from scratch but when I hav e somthing to work with let all hell break loose :D im no pro at anything but it is my best subject as far as codeing ^^

too bad I cnat get time to code tille end of the week or next week ~_~ due to an ideotic history teacher who "accidentaly" deleted everyones grades and I didnt have any backups of my work due my storage unit the school provided is defective it loses everythign daily
 
OK.

I finally figured out the structure for the packet to display shops.

Code:
[COLOR="SeaGreen"]begin tab loop[/COLOR]
00->63 loop
[COLOR="SeaGreen"]begin items loop on current tab[/COLOR]
02                             [COLOR="SeaGreen"]// Number of items on current tab[/COLOR]
00                            [COLOR="SeaGreen"] // next slot[/COLOR]
00 00 00 00             [COLOR="SeaGreen"]//  current slot[/COLOR]
EA 07 00 00           [COLOR="SeaGreen"] //  item id[/COLOR]
00 00 00 00            [COLOR="SeaGreen"]// unknown[/COLOR]
00 00 00 00           [COLOR="SeaGreen"]// unknown[/COLOR]
0f 27                     [COLOR="SeaGreen"]// max items[/COLOR]
00                         [COLOR="SeaGreen"]// unknown[/COLOR]
ff ff ff ff               [COLOR="SeaGreen"]// endurance. if 0 then put this int, if not display the endurance.[/COLOR]
00 00 00 00         [COLOR="SeaGreen"]// x10 of these ints (10 in total)[/COLOR]

00-63 loop         [COLOR="SeaGreen"]<---------- Start Page 2[/COLOR]

I want to point out that you MUST have an if statement for the endurance int. failure to do so will result in your server crashing because the shop packet size will be off.

Now that that is done there is another matter. I am getting an access violation when the shop closes which in turn shuts down my server.

I have found where the error occurs here:
Code:
bool PacketHandler::handle (Selector* selector, int socket) {
	if (bytesInBuffer < HEADER_LEN) {
		// read header
		int l = recv(socket, (char*)(buffer + bytesInBuffer), HEADER_LEN - bytesInBuffer, 0);
		if (l <= 0) {
			player->setConnect(false);
			return false;
		}
		bytesInBuffer += l;
	}

	if (bytesInBuffer >= HEADER_LEN) {
		int packetSize = *(unsigned*)&buffer[5];
		int l = recv(socket, (char*)(buffer + bytesInBuffer), HEADER_LEN + packetSize - bytesInBuffer, 0);
		if (l <= 0) {
			player->setConnect(false);
			return false;
		}
		bytesInBuffer += l;
		
		[COLOR="Red"]if (bytesInBuffer == packetSize + HEADER_LEN){
			try
			{
				[B][I][COLOR="Blue"]player->handleRequest(buffer + HEADER_LEN, packetSize);[/COLOR][/I][/B]
			
				bytesInBuffer = 0;
			} catch (...) {
				Log(MSG_ERROR,"Exception in PacketHandler::handle()\n");
			}		
		}[/COLOR]

		
	}
	return true;
}

All the codes like the world packet and such pass through here with no error. But when I close the shop I get this error. Modifying the code will hang your server and eventually crash it, so that's out of the question. I am not sure as to the full extent of the error.

Someone with experience with these kinds of errors, would you give some insight please?
 
Hey glaphanking, here is the shop packet I have:
Code:
//tab loop starts, repeat 4 times(4 tabs)
	[byte]00 ~ 63		// from 0 to 99 , total of 100 , max number of items per tab
	[byte]02            // Number of items on current tab
	//this part will reapeat for the number of items above, not more, not less
		[byte]00            // next slot
		[int]00 00 00 00    // same number as above, but int
		[int]EA 07 00 00    // item id
		[int]00 00 00 00    // unknown
		[int]00 00 00 00    // unknown
		[short]0f 27        // max items
		[byte]00            // unknown
		[int]ff ff ff ff    // endurance. if 0 then put this int, if not display the endurance.
		[byte]00	    // unknown
		[int]00 00 00 00    // unknown
		[int]00 00 00 00    // refine, how many + is the weapon
		[int]00 00 00 00    // unknown
		[byte]00            // element of the weapon, 0 = none, 1 = fire, ...
		[int]00 00 00 00    // element refine, how many + of the element it have
		[int]00 00 00 00    // unknown
		[byte]00            // number of slots(at v11, for suits and ultimate more then +6, works on other thought
		// after this, shorts with what the slots have, if there is no slot, put nothing, if there is one slot, one short, 2 slots, two shorts and so on
		4x[int]00 00 00 00  // unknown
		[byte]00	    // unknown
	//end of items loop
	[byte]00 ~ 63		// from 0 to 99 , total of 100 , max number of items per tab
//end of tab loop
 
You should post your shopPacket function. I would like to compare them together because something is throwing an error after the shop closes.


One important question, does the shop open and close for you without no problems?

Well, Im not working at dragon source so my shoppacket function wouldnt work for you, I based mine from adidishen's one, just took it hardcoded because I didnt make anything to load it from somewhere yet. The source I have dont spawn npc yet so I made it like a GM command, it loads and close perfectly.
 
oooo. never thought of it being a GM Command. I'm gonna try that one.



EDIT


Upon looking more into the packet. I am noticing a few things. I coded a GM command and the shop loads, you can buy things, and close it. BUT.... ANYTHING else that get sent to the client throws and error. Chatting, moving the player, etc. I think the buffer needs cleaned out or something. It needs more attention.
 
oooo. never thought of it being a GM Command. I'm gonna try that one.

Yeah, Im working everything(almost) as a GM command first, my guess is that Caali files have so many commands because he made like this, in my opnion its better because you know that the packet is working, then you can move on.


edit:
EDIT
Upon looking more into the packet. I am noticing a few things. I coded a GM command and the shop loads, you can buy things, and close it. BUT.... ANYTHING else that get sent to the client throws and error. Chatting, moving the player, etc. I think the buffer needs cleaned out or something. It needs more attention.
Mine works just fine, it opens the shop and I can chat, it doesnt crash.

edit 2:
looking at your code from the first post:
Code:
for (int tab = 0; tab < 4; tab++)
    {
        for(i=0; i <100; i++)
            pak.addInt(i);

        for(unsigned int k=0; k < shopTabs[tab].size(); k++)
        {
            // process each tab
            if(shopTabs[tab].empty())
                continue;
            printf("Element %d\n", shopTabs[tab]);
            ItemBank* shopItem = ItemBanks::getItemBankById(shopTabs[tab].at(k));
            printf("Item created: %d Max Items: %d Endurance: %d\n", shopItem->id, shopItem->maxItems, shopItem->endurance);
            pak.addByte(k);
            pak.addInt(k);
            pak.addInt(shopItem->id);
            pak.addInt(0);
            pak.addInt(0);
            pak.addInt(shopItem->maxItems);
            pak.addInt(shopItem->endurance);
            pak.addInt64(0);
            pak.addInt64(0);
            pak.addInt64(0);
            pak.addInt64(0);
            pak.addInt(0);
            pak.addByte(0);
            pak.addShort(0);

        }
    }

I see that you missed the last for from 0 to 100 after the add item and it doenst send items number.
 
Status
Not open for further replies.
Back