// Ryzom - MMORPG Framework
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
/*
author : Fabien Houlmann - houlmann@nevrax.com
date : 13/10/2005
named2csv: convert named_items.txt to .csv format and convert it back
to named_items.txt after changes.
use: named2csv named_items.txt filter.script (to generate a .csv based on filter)
named2csv named_items.txt named_items.csv (to modify .txt with .csv)
*/
#include "nel/misc/common.h"
#include "nel/misc/debug.h"
#include "nel/misc/sstring.h"
#include "nel/misc/path.h"
#include "nel/misc/file.h"
#include
using namespace NLMISC;
using namespace std;
// function declaration
int verifItemsFile (const char *filename);
int verifCsvFile (const char *filename);
void processItemLine (const string &s);
int getItemsFromFile (const char *filename);
int getFieldsFromFile(const char *filename);
int getNbItemFromFile(const char *filename);
int exportCsv (const char *filename);
int importCsv (const char *filename);
void getItemBounds (const CVectorSString &lines, uint num, uint &a, uint &b);
void updateItemField (CVectorSString &lines, uint itemIndex, uint fieldIndex, uint &a, uint &b);
void addNewItem (CVectorSString &lines, uint itemIndex);
int updateItems (const char *filename);
// global access
CVectorSString fields;
vector items;
// check the items file (locSlot and item number coherence)
int verifItemsFile (const char *filename)
{
FILE *f = nlfopen(filename, "r");
if (f == NULL)
nlerror("Can't open file : %s", filename);
char buffer[1024];
while (fgets(buffer, 1024, f))
{
string s(buffer);
// null or comment
if (s.empty() || s.find("//") == 0)
continue;
if (s.find("_LocSlot") == string::npos)
continue;
// get item numbers
int n1, n2;
sscanf(buffer, "_Items#%d._LocSlot=%d", &n1, &n2);
// check
if (n1 != n2)
nlerror("item number (%d) and _LocSlot(%d) don't match !", n1, n2);
}
fclose(f);
return 0;
}
// check csv file (locSlot and item number coherence)
int verifCsvFile (const char *filename)
{
FILE *f = nlfopen(filename, "r");
if (f == NULL)
nlerror("Can't open file : %s", filename);
uint prevId = -1;
char buffer[1024];
// skip first line
fgets(buffer, 1024, f);
while (fgets(buffer, 1024, f))
{
uint id = atoi(buffer);
if (id-1 != prevId)
nlerror("item number (%d) and previous item (%d) don't match !", id, prevId);
prevId = id;
}
fclose(f);
return 0;
}
// parse a line from source file
void processItemLine(const string &s)
{
// null or comment
if (s.empty() || s.find("//") == 0)
return;
// other stuff
if (s.find("_Items#") == string::npos)
return;
// get item number
int n;
sscanf(s.c_str(), "_Items#%d", &n);
// check fields
for (uint i=0 ; i max)
max = n;
}
fclose(f);
return max;
}
// generate .csv file based on actual filled structure
int exportCsv(const char *filename)
{
nlassert(fields.size() != 0);
uint i, j;
FILE *f = nlfopen(filename, "w");
if (f == NULL)
nlerror("Can't open file : %s", filename);
// print fields name
for (i=0 ; i items.size())
items.resize(n+1);
// add item id
items[n].push_back(val);
// add others
do
{
val = s.splitTo(';', true);
items[n].push_back(val);
}
while (!s.empty());
}
fclose(f);
return 0;
}
// compute item boundary in the file (min and max lines)
void getItemBounds(const CVectorSString &lines, uint num, uint &a, uint &b)
{
a = b = 0;
uint i = -1;
bool ok = false;
while (++i < lines.size() && !ok)
{
if (lines[i].empty() || lines[i].find("//") != string::npos)
continue;
// get item number
uint n;
if (sscanf(lines[i].c_str(), "_Items#%d", &n) == 0)
continue;
// find it
if (n == num)
{
// frist line
if (a == 0)
a = b = i+1;
// more line
else
b++;
}
else
{
// end
if (a != 0)
ok = true;
}
}
// found it ?
if (a != 0)
{
ok = true;
b++;
}
}
// update an item field with a new value
void updateItemField(CVectorSString &lines, uint itemIndex, uint fieldIndex, uint &a, uint &b)
{
string field = fields[fieldIndex];
string val = items[itemIndex][fieldIndex];
string s = "_Items#";
s += toString(itemIndex);
s += ".";
s += field;
// remove jump
val = CSString(val).strtok("\n");
uint craftLine = 0;
bool found = false;
uint i = a-1;
// first pass to check if param have changed
for (i=a ; i= items[itemIndex].size());
cout << "Updating item " << itemIndex << endl;
uint a, b;
getItemBounds(lines, itemIndex, a, b);
// no bound found, it's a new item
if (b == 0)
{
addNewItem(lines, itemIndex);
getItemBounds(lines, itemIndex, a, b);
}
for (uint fieldIndex=0 ; fieldIndex