- 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
C++ structure by DFlyFF - GlaphanKing
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,
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.
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.
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.
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]
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]
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
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();
}
'Til next time. This is GlaphanKing signing off.
Last edited: