Update of /cvsroot/wpdev/wolfpack
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17873
Modified Files:
basechar.cpp basechar.h basics.cpp basics.h corpse.cpp
corpse.h customtags.cpp customtags.h items.cpp items.h
multi.cpp multi.h npc.cpp npc.h player.cpp player.h server.cpp
timers.cpp uobject.cpp uobject.h wolfpack.vcproj world.cpp
world.h
Log Message:
Incomplete Binary Save Driver
Index: world.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/world.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** world.h 27 Jul 2004 06:35:22 -0000 1.16
--- world.h 9 Aug 2004 20:30:22 -0000 1.17
***************
*** 37,40 ****
--- 37,42 ----
#include "server.h"
+ class cBufferedReader;
+
class cCharIterator
{
***************
*** 75,78 ****
--- 77,81 ----
SERIAL _lastCharSerial, _lastItemSerial;
unsigned int _playerCount, _npcCount;
+ void loadTag(cBufferedReader &reader, unsigned int version);
public:
Index: uobject.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/uobject.cpp,v
retrieving revision 1.170
retrieving revision 1.171
diff -C2 -d -r1.170 -r1.171
*** uobject.cpp 7 Aug 2004 15:52:12 -0000 1.170
--- uobject.cpp 9 Aug 2004 20:30:22 -0000 1.171
***************
*** 152,157 ****
Performs persistency layer loads.
*/
! void cUObject::load( char** result, UINT16& offset )
! {
name_ = ( result[offset] == 0 ) ? QString::null : QString::fromUtf8( result[offset] );
offset++;
--- 152,156 ----
Performs persistency layer loads.
*/
! void cUObject::load(char** result, UINT16& offset) {
name_ = ( result[offset] == 0 ) ? QString::null : QString::fromUtf8( result[offset] );
offset++;
***************
*** 223,226 ****
--- 222,247 ----
}
+ void cUObject::save(cBufferedWriter &writer, unsigned int version) {
+ writer.writeUtf8(name_);
+ writer.writeInt(serial_);
+ writer.writeInt(multi_ ? multi_->serial() : INVALID_SERIAL);
+ writer.writeShort(pos_.x);
+ writer.writeShort(pos_.y);
+ writer.writeByte(pos_.z);
+ writer.writeByte(pos_.map);
+ writer.writeUtf8(eventList());
+ }
+
+ void cUObject::load(cBufferedReader &reader, unsigned int version) {
+ name_ = reader.readUtf8();
+ serial_ = reader.readInt();
+ setMulti(dynamic_cast<cMulti*>(World::instance()->findItem(reader.readInt())));
+ pos_.x = reader.readShort();
+ pos_.y = reader.readShort();
+ pos_.z = reader.readByte();
+ pos_.map = reader.readByte();
+ setEventList(reader.readUtf8());
+ }
+
/*!
Performs persistency layer deletion.
***************
*** 1038,1039 ****
--- 1059,1073 ----
}
}
+
+ void cUObject::save(cBufferedWriter &writer) {
+ writer.setObjectCount(writer.objectCount() + 1);
+ writer.writeByte(getClassid());
+
+ unsigned int length = writer.position();
+ save(writer, writer.version());
+ length = writer.position() - length;
+ writer.setSkipSize(getClassid(), length);
+
+ // Save tags for this object
+ tags_.save(serial_, writer);
+ }
Index: uobject.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/uobject.h,v
retrieving revision 1.100
retrieving revision 1.101
diff -C2 -d -r1.100 -r1.101
*** uobject.h 20 Jul 2004 11:35:37 -0000 1.100
--- uobject.h 9 Aug 2004 20:30:22 -0000 1.101
***************
*** 29,32 ****
--- 29,33 ----
#define __UOBJECT_H__
+ #include "exceptions.h"
#include "platform.h"
#include "typedefs.h"
***************
*** 59,62 ****
--- 60,66 ----
class cMulti;
+ class cBufferedReader;
+ class cBufferedWriter;
+
#pragma pack(1)
class cUObject : public PersistentObject, public cDefinable, public cPythonScriptable
***************
*** 124,127 ****
--- 128,140 ----
bool del();
+ // Wrapper
+ virtual void load(cBufferedReader &reader) = 0;
+ virtual void save(cBufferedWriter &reader);
+
+ // "Real" ones
+ virtual void load(cBufferedReader &reader, unsigned int version);
+ virtual void save(cBufferedWriter &reader, unsigned int version);
+ virtual void postload(unsigned int version) = 0;
+
// Utility Methods
void effect( UINT16 id, UINT8 speed = 10, UINT8 duration = 5, UINT16 hue = 0, UINT16 renderMode = 0 ); // Moving with this character
***************
*** 163,166 ****
--- 176,180 ----
// Getter Methods
virtual QCString bindmenu() = 0;
+ virtual unsigned char getClassid() = 0;
QString name() const
***************
*** 227,234 ****
{
public:
! void registerSqlQuery( const QString& type, const QString& query )
! {
sql_queries.insert( std::make_pair( type, query ) );
sql_keys.push_back( type );
}
--- 241,258 ----
{
public:
! cUObjectFactory() {
! lastid = 0;
! }
!
! unsigned int registerSqlQuery( const QString& type, const QString& query ) {
sql_queries.insert( std::make_pair( type, query ) );
sql_keys.push_back( type );
+
+ if (lastid + 1 < lastid) {
+ throw wpException("Only 256 types can be registered with the UObject factory.");
+ }
+
+ typemap.insert(lastid, type);
+ return lastid++;
}
***************
*** 248,254 ****
--- 272,284 ----
}
+ const QMap<unsigned char, QString> &getTypemap() {
+ return typemap;
+ }
+
private:
std::map<QString, QString> sql_queries;
+ QMap<unsigned char, QString> typemap;
QStringList sql_keys;
+ unsigned char lastid;
};
Index: timers.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/timers.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** timers.cpp 4 Aug 2004 23:17:37 -0000 1.5
--- timers.cpp 9 Aug 2004 20:30:21 -0000 1.6
***************
*** 345,348 ****
--- 345,349 ----
}
+ QPtrList<cTimer> eraselist;
std::vector<cTimer*>::iterator i = teffects.begin();
for ( i = teffects.begin(); i != teffects.end(); i++ )
***************
*** 357,364 ****
( *i )->Dispel( pSource, silent );
! teffects.erase( i );
}
! std::make_heap( teffects.begin(), teffects.end(), cTimers::ComparePredicate() );
}
--- 358,368 ----
( *i )->Dispel( pSource, silent );
! eraselist.append(*i);
}
! for ( cTimer*effect = eraselist.first(); effect; effect = eraselist.next() )
! {
! erase( effect );
! }
}
Index: basics.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/basics.cpp,v
retrieving revision 1.30
retrieving revision 1.31
diff -C2 -d -r1.30 -r1.31
*** basics.cpp 2 Jun 2004 15:04:03 -0000 1.30
--- basics.cpp 9 Aug 2004 20:30:21 -0000 1.31
***************
*** 29,39 ****
--- 29,44 ----
#include "basics.h"
#include "coord.h"
+ #include "exceptions.h"
+ #include "uobject.h"
// Library Includes
#include <qstring.h>
#include <qstringlist.h>
+ #include <qfile.h>
#include <math.h>
#include <stdlib.h>
+ #include <cstdio>
+ #include <algorithm>
#if defined( Q_OS_WIN32 )
***************
*** 180,181 ****
--- 185,689 ----
return getPlatformTime() - startTime;
}
+
+ // Swap the value in place
+ inline void swapBytes(unsigned int &data) {
+ data = ((data & 0xFF) << 24) | ((data & 0xFF00) << 8) | ((data & 0xFF0000) >> 8) | ((data & 0xFF000000) >> 24);
+ }
+
+ inline void swapBytes(double &value) {
+ unsigned char *ptr = (unsigned char*)&value;
+ std::swap(ptr[0], ptr[7]);
+ std::swap(ptr[1], ptr[6]);
+ std::swap(ptr[2], ptr[5]);
+ std::swap(ptr[3], ptr[4]);
+ }
+
+ inline void swapBytes(int &data) {
+ data = ((data & 0xFF) << 24) | ((data & 0xFF00) << 8) | ((data & 0xFF0000) >> 8) | ((data & 0xFF000000) >> 24);
+ }
+
+ inline void swapBytes(unsigned short &data) {
+ data = ((data & 0xFF00) >> 8) | ((data & 0xFF) << 8);
+ }
+
+ inline void swapBytes(short &data) {
+ data = ((data & 0xFF00) >> 8) | ((data & 0xFF) << 8);
+ }
+
+ class cBufferedWriterPrivate {
+ public:
+ QFile file;
+ unsigned int version;
+ QCString magic;
+ bool needswap;
+ QByteArray buffer;
+ unsigned int bufferpos;
+ QMap<QCString, unsigned int> dictionary;
+ QMap<unsigned char, unsigned int> skipmap;
+ QMap<unsigned char, QString> typemap;
+ unsigned int lastStringId;
+ unsigned int objectCount;
+ };
+
+ #define BUFFERSIZE 4096
+
+ cBufferedWriter::cBufferedWriter(const QCString &magic, unsigned int version) {
+ d = new cBufferedWriterPrivate;
+ d->version = version;
+ d->magic = magic;
+ d->buffer.resize(BUFFERSIZE);
+ d->bufferpos = 0;
+ d->lastStringId = 0;
+ d->objectCount = 0;
+ d->dictionary.insert(QCString(), 0); // Empty String
+
+ // Check Endianess
+ int wordSize;
+ qSysInfo(&wordSize, &d->needswap);
+ }
+
+ cBufferedWriter::~cBufferedWriter() {
+ close();
+ delete d;
+ }
+
+ void cBufferedWriter::setObjectCount(unsigned int count) {
+ d->objectCount = count;
+ }
+
+ unsigned int cBufferedWriter::objectCount() {
+ return d->objectCount;
+ }
+
+ void cBufferedWriter::open(const QString &filename) {
+ close();
+
+ d->file.setName(filename);
+ if (!d->file.open(IO_Raw|IO_WriteOnly|IO_Truncate)) {
+ throw wpException(QString("Couldn't open file %1 for writing.").arg(filename));
+ }
+
+ // Reserve space for magic, filesize, version, dictionary offset, objectcount (in that order)
+ unsigned int headerSize = d->magic.length() + 1 + sizeof(unsigned int) * 4;
+
+ QByteArray header(headerSize);
+ d->file.writeBlock(header);
+
+ // Start writing the object type list
+ const QMap<unsigned char, QString> &typemap = UObjectFactory::instance()->getTypemap();
+ QMap<unsigned char, QString>::const_iterator it;
+
+ d->skipmap.clear();
+ writeByte(typemap.size());
+ for (it = typemap.begin(); it != typemap.end(); ++it) {
+ writeByte(it.key());
+ writeInt(0); // SkipSize
+ writeAscii(it.data().latin1()); // Preinsert into the dictionary
+ d->skipmap.insert(it.key(), 0);
+ d->typemap.insert(it.key(), it.data());
+ }
+ }
+
+ void cBufferedWriter::close() {
+ if (d->file.isOpen()) {
+ unsigned int dictionary = position();
+
+ // Flush the string dictionary at the end of the save
+ writeInt(d->dictionary.count());
+
+ QMap<QCString, unsigned int>::iterator it;
+ for (it = d->dictionary.begin(); it != d->dictionary.end(); ++it) {
+ writeInt(it.data());
+ writeInt(it.key().length() + 1); // Counted Strings
+ if (it.key().data() == 0) {
+ writeByte(0);
+ } else {
+ writeRaw(it.key().data(), it.key().length() + 1);
+ }
+ }
+
+ flush();
+
+ // Seek to the beginning and write the file header
+ d->file.at(0);
+ writeRaw(d->magic.data(), d->magic.length() + 1, true);
+ writeInt(d->file.size(), true);
+ writeInt(d->version, true);
+ writeInt(dictionary, true);
+ writeInt(d->objectCount, true);
+
+ // Write new object type table
+ QMap<unsigned char, QString>::const_iterator tit;
+
+ writeByte(d->typemap.size(), true);
+ for (tit = d->typemap.begin(); tit != d->typemap.end(); ++tit) {
+ writeByte(tit.key(), true);
+
+ unsigned int size = 0;
+ if (d->skipmap.contains(tit.key())) {
+ size = d->skipmap[tit.key()];
+ }
+
+ writeInt(size, true); // SkipSize
+
+ QCString type = tit.data().latin1();
+ writeInt(d->dictionary[type], true);
+ }
+
+ d->file.close();
+ }
+ }
+
+ void cBufferedWriter::writeInt(unsigned int data, bool unbuffered) {
+ // Inplace Swapping (data is a copy anyway)
+ if (d->needswap) {
+ swapBytes(data);
+ }
+
+ writeRaw(&data, sizeof(data), unbuffered);
+ }
+
+ void cBufferedWriter::writeShort(unsigned short data, bool unbuffered) {
+ // Inplace Swapping (data is a copy anyway)
+ if (d->needswap) {
+ swapBytes(data);
+ }
+
+ writeRaw(&data, sizeof(data), unbuffered);
+ }
+
+ void cBufferedWriter::writeByte(unsigned char data, bool unbuffered) {
+ if (unbuffered) {
+ flush();
+ d->file.writeBlock((const char*)&data, sizeof(data));
+ } else {
+ if (d->bufferpos + sizeof(data) >= BUFFERSIZE) {
+ flush(); // Flush buffer to file
+ }
+
+ *(unsigned char*)(d->buffer.data() + d->bufferpos) = data;
+ d->bufferpos += sizeof(data);
+ }
+ }
+
+ void cBufferedWriter::flush() {
+ d->file.writeBlock(d->buffer.data(), d->bufferpos);
+ d->bufferpos = 0;
+ }
+
+ void cBufferedWriter::writeUtf8(const QString &data, bool unbuffered) {
+ QCString utf8 = data.utf8();
+ writeAscii(utf8, unbuffered);
+ }
+
+ void cBufferedWriter::writeAscii(const QCString &data, bool unbuffered) {
+ QMap<QCString, unsigned int>::iterator it = d->dictionary.find(data);
+
+ if (it != d->dictionary.end()) {
+ writeInt(it.data(), unbuffered);
+ } else {
+ d->dictionary.insert(data, ++d->lastStringId);
+ writeInt(d->lastStringId, unbuffered);
+ }
+ }
+
+ void cBufferedWriter::writeRaw(const void *data, unsigned int size, bool unbuffered) {
+ if (unbuffered) {
+ flush();
+ d->file.writeBlock((const char*)data, size);
+ } else {
+ // Flush out entire blocks if neccesary until we dont
+ // overflow the buffer anymore, then just append
+ unsigned int pos = 0;
+
+ while (d->bufferpos + size >= BUFFERSIZE) {
+ unsigned int bspace = BUFFERSIZE - d->bufferpos;
+
+ // Try putting in some bytes of the remaining data
+ if (bspace != 0) {
+ memcpy(d->buffer.data() + d->bufferpos, (unsigned char*)data + pos, bspace);
+ d->bufferpos = BUFFERSIZE;
+ pos += bspace;
+ size -= bspace;
+ }
+
+ flush();
+ }
+
+ // There are still some remaining bytes of our data
+ if (size != 0) {
+ memcpy(d->buffer.data() + d->bufferpos, (unsigned char*)data + pos, size);
+ d->bufferpos += size;
+ }
+ }
+ }
+
+ unsigned int cBufferedWriter::position() {
+ return d->file.size() + d->bufferpos;
+ }
+
+ unsigned int cBufferedWriter::version() {
+ return d->version;
+ }
+
+ void cBufferedWriter::writeDouble(double value, bool unbuffered) {
+ if (d->needswap) {
+ swapBytes(value);
+ }
+
+ writeRaw(&value, sizeof(value), unbuffered);
+ }
+
+ void cBufferedWriter::setSkipSize(unsigned char type, unsigned int skipsize) {
+ d->skipmap.insert(type, skipsize, true);
+ }
+
+ class cBufferedReaderPrivate {
+ public:
+ QFile file;
+ unsigned int version;
+ QCString magic;
+ bool needswap;
+ QByteArray buffer;
+ unsigned int bufferpos;
+ unsigned int buffersize;
+ QMap<unsigned char, QCString> typemap;
+ QMap<unsigned char, unsigned int> sizemap;
+ QMap<unsigned int, QCString> dictionary;
+ unsigned int objectCount;
+ };
+
+ cBufferedReader::cBufferedReader(const QCString &magic, unsigned int version) {
+ d = new cBufferedReaderPrivate;
+ d->buffer.resize(BUFFERSIZE);
+ d->bufferpos = 0;
+ d->buffersize = 0; // Current amount of data in buffer
+ d->magic = magic;
+ d->version = version;
+ d->objectCount = 0;
+
+ // Check Endianess
+ int wordSize;
+ qSysInfo(&wordSize, &d->needswap);
+ }
+
+ cBufferedReader::~cBufferedReader() {
+ close();
+ delete d;
+ }
+
+ unsigned int cBufferedReader::version() {
+ return d->version;
+ }
+
+ void cBufferedReader::open(const QString &filename) {
+ close();
+
+ d->file.setName(filename);
+ if (!d->file.open(IO_Raw|IO_ReadOnly)) {
+ throw wpException(QString("Couldn't open file %1 for reading.").arg(filename));
+ }
+
+ // Calculate minimum header size (includes typemap count)
+ unsigned int headerSize = d->magic.length() + 1 + sizeof(unsigned int) * 4 + 1;
+
+ if (d->file.size() < headerSize) {
+ throw wpException(QString("File doesn't have minimum size of %1 byte.").arg(headerSize));
+ }
+
+ // Check the file magic
+ QCString magic = readAscii(true);
+ if (magic != d->magic) {
+ throw wpException(QString("File had unexpected magic '%1'. Expected: '%2'.").arg(magic).arg(d->magic));
+ }
+
+ // Check if the file has been truncated or garbage has been appended
+ unsigned int filesize = readInt();
+ if (filesize != d->file.size()) {
+ throw wpException(QString("The filesize in the header doesn't match. Expected size is %1 byte.").arg(filesize));
+ }
+
+ // Check if the worldsave is newer than we can process
+ unsigned int version = readInt();
+ if (version > d->version) {
+ throw wpException(QString("The file version exceeds the maximum version: %1.").arg(version));
+ }
+ d->version = version; // Save file version
+
+ unsigned int dictionary = readInt();
+
+ if (!dictionary || dictionary + 4 > d->file.size()) {
+ throw wpException("Invalid dictionary.");
+ }
+
+ d->objectCount = readInt();
+
+ unsigned int dataStart = position();
+
+ // Seek to the dictionary and read it
+ d->bufferpos = 0;
+ d->buffersize = 0;
+ d->file.at(dictionary);
+
+ unsigned int entries = readInt();
+ unsigned int i;
+ for (i = 0; i < entries; ++i) {
+ unsigned int id = readInt();
+ unsigned int size = readInt();
+ if (size <= 1) {
+ readByte();
+ d->dictionary.insert(id, QCString());
+ } else {
+ QCString data(size);
+ readRaw(data.data(), size);
+ d->dictionary.insert(id, data);
+ }
+ }
+
+ d->bufferpos = 0;
+ d->buffersize = 0;
+ d->file.at(dataStart);
+
+ // Read the object type list
+ unsigned char count = readByte();
+
+ for (i = 0; i < count; ++i) {
+ unsigned char id = readByte();
+ unsigned int size = readInt();
+ QCString type = readAscii();
+
+ d->typemap.insert(id, type);
+ d->sizemap.insert(id, size);
+ }
+ }
+
+ void cBufferedReader::close() {
+ if (d->file.isOpen()) {
+ d->file.close();
+ }
+ }
+
+ unsigned int cBufferedReader::readInt() {
+ unsigned int result;
+ readRaw(&result, sizeof(result));
+
+ if (d->needswap) {
+ swapBytes(result);
+ }
+
+ return result;
+ }
+
+ double cBufferedReader::readDouble() {
+ double result;
+ readRaw(&result, sizeof(result));
+
+ if (d->needswap) {
+ swapBytes(result);
+ }
+
+ return result;
+ }
+
+ unsigned short cBufferedReader::readShort() {
+ unsigned short result;
+ readRaw(&result, sizeof(result));
+
+ if (d->needswap) {
+ swapBytes(result);
+ }
+
+ return result;
+ }
+
+ unsigned char cBufferedReader::readByte() {
+ unsigned char result;
+ readRaw(&result, sizeof(result));
+ return result;
+ }
+
+ QString cBufferedReader::readUtf8() {
+ QCString data = readAscii();
+
+ if (data.length() == 0 || data.data() == 0 || *(data.data()) == 0) {
+ return QString::null;
+ } else {
+ return QString::fromUtf8(data);
+ }
+ }
+
+ QCString cBufferedReader::readAscii(bool nodictionary) {
+ if (nodictionary) {
+ unsigned char c;
+ QCString result;
+ do {
+ c = readByte();
+ if (c != 0) {
+ result.insert(result.length(), c);
+ }
+ } while (c != 0);
+ return result;
+ } else {
+ unsigned int id = readInt();
+
+ QMap<unsigned int, QCString>::iterator it = d->dictionary.find(id);
+
+ if (it != d->dictionary.end()) {
+ return it.data();
+ } else {
+ return QCString();
+ }
+ }
+ }
+
+ void cBufferedReader::readRaw(void *data, unsigned int size) {
+ unsigned int pos = 0;
+
+ // Repeat this
+ do {
+ unsigned int available = d->buffersize - d->bufferpos;
+ unsigned int needed = QMIN(available, size);
+
+ // Get as much data as possible
+ if (needed != 0) {
+ memcpy(((unsigned char*)data) + pos, d->buffer.data() + d->bufferpos, needed);
+ size -= needed;
+ available -= needed;
+ pos += needed;
+ d->bufferpos += needed;
+ }
+
+ // Refill buffer if required
+ if (available == 0) {
+ unsigned int read = d->file.readBlock(d->buffer.data(), BUFFERSIZE);
+
+ // We will never be able to statisfy the request
+ if (read != BUFFERSIZE && read < size) {
+ throw wpException(QString("Unexpected end of file while reading."));
+ }
+
+ d->bufferpos = 0;
+ d->buffersize = read;
+ }
+ } while (size > 0);
+ }
+
+ unsigned int cBufferedReader::position() {
+ return (d->file.at() - d->buffersize) + d->bufferpos;
+ }
+
+ const QMap<unsigned char, QCString> &cBufferedReader::typemap() {
+ return d->typemap;
+ }
+
+ unsigned int cBufferedReader::getSkipSize(unsigned char type) {
+ if (!d->sizemap.contains(type)) {
+ return 0;
+ } else {
+ return d->sizemap[type];
+ }
+ }
+
+ unsigned int cBufferedReader::objectCount() {
+ return d->objectCount;
+ }
Index: multi.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/multi.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** multi.cpp 20 Jul 2004 11:35:37 -0000 1.10
--- multi.cpp 9 Aug 2004 20:30:21 -0000 1.11
***************
*** 159,165 ****
QString sqlString = QString( "SELECT %1 FROM uobjectmap,%2 WHERE uobjectmap.type = 'cMulti' AND %3" ).arg( fields.join( "," ) ).arg( tables.join( "," ) ).arg( conditions.join( " AND " ) );
UObjectFactory::instance()->registerType( "cMulti", productCreator );
! UObjectFactory::instance()->registerSqlQuery( "cMulti", sqlString );
}
cMulti* cMulti::find( const Coord_cl& pos )
{
--- 159,167 ----
QString sqlString = QString( "SELECT %1 FROM uobjectmap,%2 WHERE uobjectmap.type = 'cMulti' AND %3" ).arg( fields.join( "," ) ).arg( tables.join( "," ) ).arg( conditions.join( " AND " ) );
UObjectFactory::instance()->registerType( "cMulti", productCreator );
! classid = UObjectFactory::instance()->registerSqlQuery( "cMulti", sqlString );
}
+ unsigned char cMulti::classid;
+
cMulti* cMulti::find( const Coord_cl& pos )
{
***************
*** 186,187 ****
--- 188,199 ----
return multi;
}
+
+ void cMulti::save(cBufferedWriter &writer) {
+ cItem::save(writer);
+
+ // Save objects within this multi *after* the multi
+ cUObject* object;
+ for (object = objects.first(); object; object = objects.next()) {
+ object->save(writer);
+ }
+ }
Index: items.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/items.cpp,v
retrieving revision 1.428
retrieving revision 1.429
diff -C2 -d -r1.428 -r1.429
*** items.cpp 4 Aug 2004 23:17:35 -0000 1.428
--- items.cpp 9 Aug 2004 20:30:21 -0000 1.429
***************
*** 534,537 ****
--- 534,588 ----
}
+ void cItem::save(cBufferedWriter &writer, unsigned int version) {
+ cUObject::save(writer, version);
+
+ writer.writeShort(id_);
+ writer.writeShort(color_);
+ writer.writeInt(container_ ? container_->serial() : INVALID_SERIAL);
+ writer.writeByte(layer_);
+ writer.writeShort(amount_);
+ writer.writeShort(hp_);
+ writer.writeShort(maxhp_);
+ writer.writeByte(magic_);
+ writer.writeInt(ownserial_);
+ writer.writeByte(visible_);
+ writer.writeByte(priv_);
+ writer.writeAscii(baseid());
+ }
+
+ void cItem::postload(unsigned int version) {
+ }
+
+ void cItem::load(cBufferedReader &reader, unsigned int version) {
+ cUObject::load(reader, version);
+
+ id_ = reader.readShort();
+ color_ = reader.readShort();
+ // Here we assume that containers are always before us in the save
+ cUObject *container = World::instance()->findObject(reader.readInt());
+ layer_ = reader.readByte();
+ amount_ = reader.readShort();
+ hp_ = reader.readShort();
+ maxhp_ = reader.readShort();
+ magic_ = reader.readByte();
+ ownserial_ = reader.readInt();
+ visible_ = reader.readByte();
+ priv_ = reader.readByte();
+ basedef_ = ItemBaseDefs::instance()->get(reader.readAscii());
+
+ // Add to container and handle weight
+ if (container) {
+ P_ITEM iContainer = dynamic_cast<P_ITEM>(container);
+ if (iContainer) {
+ iContainer->addItem(this, false, true, true);
+ } else {
+ P_CHAR cContainer = dynamic_cast<P_CHAR>(container);
+ if (cContainer) {
+ cContainer->addItem((cBaseChar::enLayer)layer(), this, true, true);
+ }
+ }
+ }
+ }
+
void cItem::save()
{
***************
*** 1458,1464 ****
QString sqlString = QString( "SELECT %1 FROM uobjectmap,%2 WHERE uobjectmap.type = 'cItem' AND %3" ).arg( fields.join( "," ) ).arg( tables.join( "," ) ).arg( conditions.join( " AND " ) );
UObjectFactory::instance()->registerType( "cItem", productCreator );
! UObjectFactory::instance()->registerSqlQuery( "cItem", sqlString );
}
void cItem::load( char** result, UINT16& offset )
{
--- 1509,1517 ----
QString sqlString = QString( "SELECT %1 FROM uobjectmap,%2 WHERE uobjectmap.type = 'cItem' AND %3" ).arg( fields.join( "," ) ).arg( tables.join( "," ) ).arg( conditions.join( " AND " ) );
UObjectFactory::instance()->registerType( "cItem", productCreator );
! classid = UObjectFactory::instance()->registerSqlQuery( "cItem", sqlString );
}
+ unsigned char cItem::classid;
+
void cItem::load( char** result, UINT16& offset )
{
***************
*** 2351,2352 ****
--- 2404,2424 ----
}
+ void cItem::save(cBufferedWriter &writer) {
+ cUObject::save(writer);
+
+ // Save container content
+ ContainerContent::iterator it = content_.begin();
+ for (; it != content_.end(); ++it) {
+ (*it)->save(writer);
+ }
+ }
+
+ void cItem::load(cBufferedReader &reader) {
+ load(reader, reader.version());
+
+ World::instance()->registerObject(this);
+
+ if (!container_) {
+ SectorMaps::instance()->add(this);
+ }
+ }
Index: corpse.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/corpse.cpp,v
retrieving revision 1.60
retrieving revision 1.61
diff -C2 -d -r1.60 -r1.61
*** corpse.cpp 4 Aug 2004 23:17:35 -0000 1.60
--- corpse.cpp 9 Aug 2004 20:30:21 -0000 1.61
***************
*** 30,33 ****
--- 30,34 ----
#include "network/network.h"
#include "network/uotxpackets.h"
+ #include "basics.h"
#include "dbdriver.h"
#include "network/uosocket.h"
***************
*** 39,43 ****
#include <functional>
#include <algorithm>
- #include <map>
using namespace std;
--- 40,43 ----
***************
*** 54,60 ****
QString sqlString = QString( "SELECT %1 FROM uobjectmap,%2 WHERE uobjectmap.type = 'cCorpse' AND %3" ).arg( fields.join( "," ) ).arg( tables.join( "," ) ).arg( conditions.join( " AND " ) );
UObjectFactory::instance()->registerType( "cCorpse", productCreator );
! UObjectFactory::instance()->registerSqlQuery( "cCorpse", sqlString );
}
void cCorpse::buildSqlString( QStringList& fields, QStringList& tables, QStringList& conditions )
{
--- 54,62 ----
QString sqlString = QString( "SELECT %1 FROM uobjectmap,%2 WHERE uobjectmap.type = 'cCorpse' AND %3" ).arg( fields.join( "," ) ).arg( tables.join( "," ) ).arg( conditions.join( " AND " ) );
UObjectFactory::instance()->registerType( "cCorpse", productCreator );
! classid = UObjectFactory::instance()->registerSqlQuery( "cCorpse", sqlString );
}
+ unsigned char cCorpse::classid;
+
void cCorpse::buildSqlString( QStringList& fields, QStringList& tables, QStringList& conditions )
{
***************
*** 66,69 ****
--- 68,116 ----
}
+ void cCorpse::load(cBufferedReader &reader, unsigned int version) {
+ cItem::load(reader, version);
+ bodyId_ = reader.readShort();
+ hairStyle_ = reader.readShort();
+ hairColor_ = reader.readShort();
+ beardStyle_ = reader.readShort();
+ beardColor_ = reader.readShort();
+ direction_ = reader.readByte();
+ charbaseid_ = reader.readAscii();
+ murderer_ = reader.readInt();
+ murdertime_ = reader.readInt();
+
+ // Write a serial for every possible layer (fixed block size)
+ unsigned char layer;
+ for (layer = cBaseChar::SingleHandedWeapon; layer <= cBaseChar::Mount; ++layer) {
+ SERIAL serial = reader.readInt();
+ if (serial != INVALID_SERIAL) {
+ equipment_.insert(layer, serial);
+ }
+ }
+ }
+
+ void cCorpse::save(cBufferedWriter &writer, unsigned int version) {
+ cItem::save(writer, version);
+ writer.writeShort(bodyId_);
+ writer.writeShort(hairStyle_);
+ writer.writeShort(hairColor_);
+ writer.writeShort(beardStyle_);
+ writer.writeShort(beardColor_);
+ writer.writeByte(direction_);
+ writer.writeAscii(charbaseid_);
+ writer.writeInt(murderer_);
+ writer.writeInt(murdertime_);
+
+ // Write a serial for every possible layer (fixed block size)
+ unsigned char layer;
+ for (layer = cBaseChar::SingleHandedWeapon; layer <= cBaseChar::Mount; ++layer) {
+ if (equipment_.contains(layer)) {
+ writer.writeInt(equipment_[layer]);
+ } else {
+ writer.writeInt(INVALID_SERIAL);
+ }
+ }
+ }
+
void cCorpse::load( char** result, UINT16& offset )
{
***************
*** 89,93 ****
// Fetch row-by-row
while ( res.fetchrow() )
! equipment_.insert( make_pair( res.getInt( 0 ), res.getInt( 1 ) ) );
res.free();
--- 136,140 ----
// Fetch row-by-row
while ( res.fetchrow() )
! equipment_.insert( res.getInt( 0 ), res.getInt( 1 ) );
res.free();
***************
*** 119,124 ****
}
! for ( map<UINT8, SERIAL>::iterator it = equipment_.begin(); it != equipment_.end(); ++it )
! PersistentBroker::instance()->executeQuery( QString( "REPLACE INTO corpses_equipment VALUES(%1,%2,%3)" ).arg( serial() ).arg( it->first ).arg( it->second ) );
cItem::save();
--- 166,171 ----
}
! for ( QMap<UINT8, SERIAL>::iterator it = equipment_.begin(); it != equipment_.end(); ++it )
! PersistentBroker::instance()->executeQuery( QString( "REPLACE INTO corpses_equipment VALUES(%1,%2,%3)" ).arg( serial() ).arg( it.key() ).arg( it.data() ) );
cItem::save();
***************
*** 160,170 ****
corpseEquip.setSerial( serial() );
! for ( map<UINT8, SERIAL>::iterator it = equipment_.begin(); it != equipment_.end(); ++it )
{
! P_ITEM pItem = World::instance()->findItem( it->second );
if ( pItem && pItem->container() == this )
{
! corpseEquip.addItem( it->first, it->second );
corpseContent.addItem( pItem );
}
--- 207,217 ----
corpseEquip.setSerial( serial() );
! for ( QMap<UINT8, SERIAL>::iterator it = equipment_.begin(); it != equipment_.end(); ++it )
{
! P_ITEM pItem = World::instance()->findItem( it.data() );
if ( pItem && pItem->container() == this )
{
! corpseEquip.addItem( it.key(), it.data() );
corpseContent.addItem( pItem );
}
***************
*** 242,246 ****
}
! equipment_.insert( make_pair( layer, serial ) );
}
--- 289,293 ----
}
! equipment_.insert(layer, serial);
}
Index: items.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/items.h,v
retrieving revision 1.207
retrieving revision 1.208
diff -C2 -d -r1.207 -r1.208
*** items.h 24 Jul 2004 18:59:56 -0000 1.207
--- items.h 9 Aug 2004 20:30:21 -0000 1.208
***************
*** 165,168 ****
--- 165,169 ----
friend class cBaseChar;
private:
+ static unsigned char classid;
unsigned char changed_ : 1;
cItemBaseDef* basedef_;
***************
*** 174,177 ****
--- 175,182 ----
public:
+ unsigned char getClassid() {
+ return cItem::classid;
+ }
+
typedef QValueVector<cItem*> ContainerContent;
***************
*** 188,191 ****
--- 193,200 ----
bool del();
+ void load(cBufferedReader &reader, unsigned int version);
+ void save(cBufferedWriter &reader, unsigned int version);
+ void postload(unsigned int version);
+
void processContainerNode( const cElement* Tag );
virtual void update( cUOSocket* mSock = NULL );
***************
*** 298,301 ****
--- 307,313 ----
}
+ void save(cBufferedWriter &writer);
+ void load(cBufferedReader &reader);
+
// Basedef Properties
inline bool isWaterSource() {
Index: server.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/server.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** server.cpp 4 Aug 2004 23:17:36 -0000 1.14
--- server.cpp 9 Aug 2004 20:30:21 -0000 1.15
***************
*** 318,322 ****
// Open the Worldsave and Account Database drivers.
! if ( !PersistentBroker::instance()->openDriver( Config::instance()->databaseDriver() ) )
{
Console::instance()->log( LOG_ERROR, QString( "Unknown Worldsave Database Driver '%1', check your wolfpack.xml" ).arg( Config::instance()->databaseDriver() ) );
--- 318,322 ----
// Open the Worldsave and Account Database drivers.
! if ( Config::instance()->databaseDriver() != "binary" && !PersistentBroker::instance()->openDriver( Config::instance()->databaseDriver() ) )
{
Console::instance()->log( LOG_ERROR, QString( "Unknown Worldsave Database Driver '%1', check your wolfpack.xml" ).arg( Config::instance()->databaseDriver() ) );
Index: basechar.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/basechar.h,v
retrieving revision 1.75
retrieving revision 1.76
diff -C2 -d -r1.75 -r1.76
*** basechar.h 27 Jul 2004 06:35:21 -0000 1.75
--- basechar.h 9 Aug 2004 20:30:21 -0000 1.76
***************
*** 119,122 ****
--- 119,127 ----
void save();
bool del();
+ void load(cBufferedReader &reader);
+ void load(cBufferedReader &reader, unsigned int version);
+ void save(cBufferedWriter &writer, unsigned int version);
+ void save(cBufferedWriter &writer);
+ void postload(unsigned int version);
// interface methods
***************
*** 354,358 ****
P_CHAR guarding() const;
short hitpoints() const;
! int hunger() const;
uint hungerTime() const;
short intelligence() const;
--- 359,363 ----
P_CHAR guarding() const;
short hitpoints() const;
! unsigned char hunger() const;
uint hungerTime() const;
short intelligence() const;
***************
*** 433,437 ****
void setGuarding( P_CHAR data );
void setHitpoints( short data );
! void setHunger( int data );
void setHungerTime( uint data );
void setIntelligence( short data );
--- 438,442 ----
void setGuarding( P_CHAR data );
void setHitpoints( short data );
! void setHunger( unsigned char data );
void setHungerTime( uint data );
void setIntelligence( short data );
***************
*** 736,740 ****
// The hunger value of the char. 6 means not hungry, 0 means starving.
// cOldChar::hunger_
! int hunger_;
// Server clocks when next hunger check will be made.
--- 741,745 ----
// The hunger value of the char. 6 means not hungry, 0 means starving.
// cOldChar::hunger_
! unsigned char hunger_;
// Server clocks when next hunger check will be made.
***************
*** 984,993 ****
}
! inline int cBaseChar::hunger() const
{
return hunger_;
}
! inline void cBaseChar::setHunger( int data )
{
hunger_ = data;
--- 989,998 ----
}
! inline unsigned char cBaseChar::hunger() const
{
return hunger_;
}
! inline void cBaseChar::setHunger( unsigned char data )
{
hunger_ = data;
Index: corpse.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/corpse.h,v
retrieving revision 1.25
retrieving revision 1.26
diff -C2 -d -r1.25 -r1.26
*** corpse.h 20 Jul 2004 11:35:36 -0000 1.25
--- corpse.h 9 Aug 2004 20:30:21 -0000 1.26
***************
*** 35,39 ****
// System Includes
! #include <map>
// Forward declarations
--- 35,39 ----
// System Includes
! #include <qmap.h>
// Forward declarations
***************
*** 45,48 ****
--- 45,49 ----
static void buildSqlString( QStringList& fields, QStringList& tables, QStringList& conditions );
bool changed_;
+ static unsigned char classid;
protected:
***************
*** 57,64 ****
QCString charbaseid_;
! std::map<UINT8, SERIAL> equipment_; // Serials of the old equipment
// The meaning of this is that even if the items are inside of the corpse
// they're displayed as equipment
public:
cCorpse(bool init = false);
void setBodyId(UINT16 data);
--- 58,69 ----
QCString charbaseid_;
! QMap<UINT8, SERIAL> equipment_; // Serials of the old equipment
// The meaning of this is that even if the items are inside of the corpse
// they're displayed as equipment
public:
+ unsigned char getClassid() {
+ return cCorpse::classid;
+ }
+
cCorpse(bool init = false);
void setBodyId(UINT16 data);
***************
*** 107,110 ****
--- 112,117 ----
void save();
bool del();
+ void load(cBufferedReader &reader, unsigned int version);
+ void save(cBufferedWriter &reader, unsigned int version);
// abstract cDefinable
Index: player.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/player.h,v
retrieving revision 1.51
retrieving revision 1.52
diff -C2 -d -r1.51 -r1.52
*** player.h 7 Aug 2004 15:32:59 -0000 1.51
--- player.h 9 Aug 2004 20:30:21 -0000 1.52
***************
*** 75,78 ****
--- 75,81 ----
void save();
bool del();
+ void load(cBufferedReader &reader, unsigned int version);
+ void save(cBufferedWriter &writer, unsigned int version);
+ void load(cBufferedReader &reader);
virtual bool send( cUOPacket* packet );
***************
*** 200,205 ****
--- 203,213 ----
const char* className() const;
+ unsigned char getClassid() {
+ return cPlayer::classid;
+ }
+
private:
bool changed_;
+ static unsigned char classid;
protected:
Index: basics.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/basics.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -C2 -d -r1.23 -r1.24
*** basics.h 19 Jun 2004 02:06:51 -0000 1.23
--- basics.h 9 Aug 2004 20:30:21 -0000 1.24
***************
*** 34,37 ****
--- 34,38 ----
#include <functional>
+ #include <qmap.h>
// Forward definitions
***************
*** 61,64 ****
--- 62,121 ----
};
+ class QCString;
+
+ class cBufferedWriter {
+ private:
+ class cBufferedWriterPrivate *d;
+
+ public:
+ cBufferedWriter(const QCString &magic, unsigned int version);
+ ~cBufferedWriter();
+
+ void open(const QString &filename);
+ void close();
+ void flush();
+
+ void writeInt(unsigned int data, bool unbuffered = false);
+ void writeShort(unsigned short data, bool unbuffered = false);
+ void writeByte(unsigned char data, bool unbuffered = false);
+ void writeUtf8(const QString &data, bool unbuffered = false);
+ void writeAscii(const QCString &data, bool unbuffered = false);
+ void writeRaw(const void *data, unsigned int size, bool unbuffered = false);
+ void writeDouble(double data, bool unbuffered = false);
+
+ unsigned int position();
+ unsigned int version();
+ void setSkipSize(unsigned char type, unsigned int skipsize);
+ void setObjectCount(unsigned int count);
+ unsigned int objectCount();
+ };
+
+ class cBufferedReader {
+ private:
+ class cBufferedReaderPrivate *d;
+
+ public:
+ cBufferedReader(const QCString &magic, unsigned int version);
+ ~cBufferedReader();
+
+ void open(const QString &filename);
+ void close();
+ unsigned int version();
+
+ unsigned int readInt();
+ unsigned short readShort();
+ unsigned char readByte();
+ double readDouble();
+ QString readUtf8();
+ QCString readAscii(bool nodictionary = false);
+ void readRaw(void *data, unsigned int size);
+
+ unsigned int position();
+ const QMap<unsigned char, QCString> &typemap();
+ unsigned int getSkipSize(unsigned char type);
+
+ unsigned int objectCount();
+ };
+
#endif
Index: customtags.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/customtags.h,v
retrieving revision 1.30
retrieving revision 1.31
diff -C2 -d -r1.30 -r1.31
*** customtags.h 19 Jun 2004 02:06:51 -0000 1.30
--- customtags.h 9 Aug 2004 20:30:21 -0000 1.31
***************
*** 45,48 ****
--- 45,50 ----
class cVariant;
class Coord_cl;
+ class cBufferedReader;
+ class cBufferedWriter;
class cVariant
***************
*** 77,80 ****
--- 79,85 ----
cVariant( long int );
+ void serialize(cBufferedWriter &writer, unsigned int version);
+ void serialize(cBufferedReader &reader, unsigned int version);
+
Type type() const;
const char* typeName() const;
***************
*** 155,158 ****
--- 160,165 ----
QValueList<cVariant> getValues();
+ void save(SERIAL serial, cBufferedWriter &writer);
+
bool getChanged() const
{
***************
*** 168,172 ****
bool operator==( const cCustomTags& ) const;
bool operator!=( const cCustomTags& ) const;
-
private:
QMap<QString, cVariant>* tags_;
--- 175,178 ----
Index: basechar.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/basechar.cpp,v
retrieving revision 1.123
retrieving revision 1.124
diff -C2 -d -r1.123 -r1.124
*** basechar.cpp 4 Aug 2004 23:17:35 -0000 1.123
--- basechar.cpp 9 Aug 2004 20:30:21 -0000 1.124
***************
*** 161,164 ****
--- 161,291 ----
static void characterRegisterAfterLoading( P_CHAR pc );
+ void cBaseChar::load(cBufferedReader &reader, unsigned int version) {
+ cUObject::load(reader, version);
+
+ orgName_ = reader.readUtf8();
+ title_ = reader.readUtf8();
+ creationDate_ = QDateTime::fromString(reader.readUtf8(), Qt::ISODate);
+ body_ = reader.readShort();
+ orgBody_ = reader.readShort();
+ skin_ = reader.readShort();
+ orgSkin_ = reader.readShort();
+ saycolor_ = reader.readShort();
+ emoteColor_ = reader.readShort();
+ strength_ = reader.readShort();
+ strengthMod_ = reader.readShort();
+ dexterity_ = reader.readShort();
+ dexterityMod_ = reader.readShort();
+ intelligence_ = reader.readShort();
+ intelligenceMod_ = reader.readShort();
+ maxHitpoints_ = reader.readShort();
+ hitpoints_ = reader.readShort();
+ maxStamina_ = reader.readShort();
+ stamina_ = reader.readShort();
+ maxMana_ = reader.readShort();
+ mana_ = reader.readShort();
+ karma_ = reader.readShort();
+ fame_ = reader.readShort();
+ kills_ = reader.readShort();
+ deaths_ = reader.readShort();
+ hunger_ = reader.readByte();
+ poison_ = reader.readByte();
+ murdererTime_ = reader.readInt();
+ if (murdererTime_) {
+ murdererTime_ += Server::instance()->time();
+ }
+ criminalTime_ = reader.readInt();
+ if (criminalTime_) {
+ criminalTime_ += Server::instance()->time();
+ }
+ gender_ = reader.readByte();
+ propertyFlags_ = reader.readInt();
+ murdererSerial_ = reader.readInt();
+ guarding_ = reinterpret_cast<P_CHAR>(reader.readInt()); // PostProcess
+ hitpointsBonus_ = reader.readShort();
+ staminaBonus_ = reader.readShort();
+ manaBonus_ = reader.readShort();
+ strengthCap_ = reader.readByte();
+ dexterityCap_ = reader.readByte();
+ intelligenceCap_ = reader.readByte();
+ statCap_ = reader.readByte();
+ basedef_ = CharBaseDefs::instance()->get( reader.readAscii() );
+ direction_ = reader.readByte();
+
+ // Load Skills
+ unsigned int count = ALLSKILLS;
+ for (unsigned int s = 0; s < count; ++s) {
+ // Read value, cap, lock
+ setSkillValue(s, reader.readShort());
+ setSkillCap(s, reader.readShort());
+ setSkillLock(s, reader.readByte());
+ }
+ }
+
+ void cBaseChar::postload(unsigned int version) {
+ // Resolve the guarding_ value.
+ SERIAL guarding = (SERIAL)guarding_;
+ guarding_ = 0;
+ setGuarding(World::instance()->findChar(guarding));
+
+
+ }
+
+ void cBaseChar::save(cBufferedWriter &writer, unsigned int version) {
+ cUObject::save(writer, version);
+
+ writer.writeUtf8(orgName_);
+ writer.writeUtf8(title_);
+ writer.writeUtf8(creationDate_.toString(Qt::ISODate));
+ writer.writeShort(body_);
+ writer.writeShort(orgBody_);
+ writer.writeShort(skin_);
+ writer.writeShort(orgSkin_);
+ writer.writeShort(saycolor_);
+ writer.writeShort(emoteColor_);
+ writer.writeShort(strength_);
+ writer.writeShort(strengthMod_);
+ writer.writeShort(dexterity_);
+ writer.writeShort(dexterityMod_);
+ writer.writeShort(intelligence_);
+ writer.writeShort(intelligenceMod_);
+ writer.writeShort(maxHitpoints_);
+ writer.writeShort(hitpoints_);
+ writer.writeShort(maxStamina_);
+ writer.writeShort(stamina_);
+ writer.writeShort(maxMana_);
+ writer.writeShort(mana_);
+ writer.writeShort(karma_);
+ writer.writeShort(fame_);
+ writer.writeShort(kills_);
+ writer.writeShort(deaths_);
+ writer.writeByte(hunger_);
+ writer.writeByte(poison_);
+ writer.writeInt(murdererTime_ ? murdererTime_ - Server::instance()->time() : 0);
+ writer.writeInt(criminalTime_ ? criminalTime_ - Server::instance()->time() : 0);
+ writer.writeByte(gender_);
+ writer.writeInt(propertyFlags_);
+ writer.writeInt(murdererSerial_);
+ writer.writeInt(guarding_ ? guarding_->serial() : INVALID_SERIAL);
+ writer.writeShort(hitpointsBonus_);
+ writer.writeShort(staminaBonus_);
+ writer.writeShort(manaBonus_);
+ writer.writeByte(strengthCap_);
+ writer.writeByte(dexterityCap_);
+ writer.writeByte(intelligenceCap_);
+ writer.writeByte(statCap_);
+ writer.writeAscii(baseid());
+ writer.writeByte(direction_);
+
+ // Load Skills
+ unsigned int count = ALLSKILLS;
+ for (unsigned int s = 0; s < count; ++s) {
+ // Read value, cap, lock
+ writer.writeShort(skillValue(s));
+ writer.writeShort(skillCap(s));
+ writer.writeByte(skillLock(s));
+ }
+ }
+
void cBaseChar::load( char** result, UINT16& offset )
{
***************
*** 252,255 ****
--- 379,392 ----
}
+ void cBaseChar::save(cBufferedWriter &writer) {
+ cUObject::save(writer);
+
+ // Save equipment
+ ItemContainer::iterator it = content_.begin();
+ for (; it != content_.end(); ++it) {
+ it.data()->save(writer);
+ }
+ }
+
void cBaseChar::save()
{
***************
*** 3293,3294 ****
--- 3430,3437 ----
cUObject::remove();
}
+
+ void cBaseChar::load(cBufferedReader &reader) {
+ load(reader, reader.version());
+ World::instance()->registerObject(this);
+ SectorMaps::instance()->add(this);
+ }
Index: wolfpack.vcproj
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/wolfpack.vcproj,v
retrieving revision 1.39
retrieving revision 1.40
diff -C2 -d -r1.39 -r1.40
*** wolfpack.vcproj 4 Aug 2004 23:17:37 -0000 1.39
--- wolfpack.vcproj 9 Aug 2004 20:30:22 -0000 1.40
***************
*** 695,698 ****
--- 695,701 ----
</File>
<File
+ RelativePath=".\python\pyspawnregion.cpp">
+ </File>
+ <File
RelativePath=".\python\pytooltip.cpp">
</File>
Index: customtags.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/customtags.cpp,v
retrieving revision 1.50
retrieving revision 1.51
diff -C2 -d -r1.50 -r1.51
*** customtags.cpp 5 Jul 2004 18:33:20 -0000 1.50
--- customtags.cpp 9 Aug 2004 20:30:21 -0000 1.51
***************
*** 630,633 ****
--- 630,747 ----
}
+ void cVariant::serialize(cBufferedWriter &writer, unsigned int version) {
+ writer.writeByte(typ);
+ char skipper[8];
+
+ switch (typ) {
+ case Invalid:
+ writer.writeRaw(skipper, 8);
+ break;
+
+ case String:
+ if (value.ptr) {
+ writer.writeUtf8(*(QString*)value.ptr);
+ } else {
+ writer.writeUtf8(QString::null);
+ }
+ writer.writeRaw(skipper, 4);
+ break;
+
+ case Int:
+ writer.writeInt(value.i);
+ writer.writeRaw(skipper, 4);
+ break;
+
+ case Long:
+ writer.writeInt(value.i);
+ writer.writeRaw(skipper, 4);
+ break;
+
+ case Double:
+ writer.writeDouble(value.d);
+ break;
+
+ case BaseChar:
+ if (value.ptr) {
+ writer.writeInt(((P_CHAR)value.ptr)->serial());
+ } else {
+ writer.writeInt(INVALID_SERIAL);
+ }
+ writer.writeRaw(skipper, 4);
+ break;
+
+ case Item:
+ if (value.ptr) {
+ writer.writeInt(((P_ITEM)value.ptr)->serial());
+ } else {
+ writer.writeInt(INVALID_SERIAL);
+ }
+ writer.writeRaw(skipper, 4);
+ break;
+
+ case Coord:
+ writer.writeShort(((Coord_cl*)(value.ptr))->x);
+ writer.writeShort(((Coord_cl*)(value.ptr))->y);
+ writer.writeByte(((Coord_cl*)(value.ptr))->z);
+ writer.writeByte(((Coord_cl*)(value.ptr))->map);
+ writer.writeRaw(skipper, 2);
+ break;
+ }
+ }
+
+ void cVariant::serialize(cBufferedReader &reader, unsigned int version) {
+ // Only invalid can be loaded
+ if (typ != Invalid) {
+ return;
+ }
+
+ unsigned char type = reader.readByte();
+ typ = (Type)type;
+ switch (typ) {
+ case Invalid:
+ reader.readInt();
+ reader.readInt();
+ break;
+
+ case String:
+ value.ptr = new QString(reader.readUtf8());
+ reader.readInt();
+ break;
+
+ case Int:
+ value.i = reader.readInt();
+ reader.readInt();
+ break;
+
+ case Long:
+ value.i = reader.readInt();
+ reader.readInt();
+ break;
+
+ case Double:
+ value.d = reader.readDouble();
+ break;
+
+ case BaseChar:
+ value.ptr = World::instance()->findChar(reader.readInt());
+ reader.readInt();
+ break;
+
+ case Item:
+ value.ptr = World::instance()->findItem(reader.readInt());
+ reader.readInt();
+ break;
+
+ case Coord:
+ value.ptr = new Coord_cl;
+ ((Coord_cl*)(value.ptr))->x = reader.readShort();
+ ((Coord_cl*)(value.ptr))->y = reader.readShort();
+ ((Coord_cl*)(value.ptr))->z = reader.readByte();
+ ((Coord_cl*)(value.ptr))->map = reader.readByte();
+ reader.readShort();
+ break;
+ }
+ }
+
/*****************************************************************************
cCustomTags member functions
***************
*** 903,904 ****
--- 1017,1041 ----
return !( this->operator == ( cmp ) );
}
+
+ void cCustomTags::save(SERIAL serial, cBufferedWriter &writer) {
+ if (tags_) {
+ QMap<QString, cVariant>::iterator it( tags_->begin() );
+
+ for (; it != tags_->end(); ++it) {
+ // Erase invalid tags.
+ if (!it.data().isValid()) {
+ continue;
+ }
+
+ // Save serial and name
+ writer.writeByte(0xFE);
+ unsigned int length = writer.position();
+ writer.writeInt(serial);
+ writer.writeUtf8(it.key());
+ it.data().serialize(writer, writer.version());
+ length = writer.position() - length;
+
+ writer.setSkipSize(0xFE, length);
+ }
+ }
+ }
Index: npc.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/npc.h,v
retrieving revision 1.52
retrieving revision 1.53
diff -C2 -d -r1.52 -r1.53
*** npc.h 20 Jul 2004 11:35:37 -0000 1.52
--- npc.h 9 Aug 2004 20:30:21 -0000 1.53
***************
*** 91,94 ****
--- 91,98 ----
void save();
bool del();
+ void load(cBufferedReader &reader, unsigned int version);
+ void save(cBufferedWriter &writer, unsigned int version);
+ void postload(unsigned int version);
+ void load(cBufferedReader &reader);
virtual enCharTypes objectType();
***************
*** 193,198 ****
--- 197,207 ----
const char* className() const;
+ unsigned char getClassid() {
+ return cNPC::classid;
+ }
+
private:
bool changed_;
+ static unsigned char classid;
protected:
Index: player.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/player.cpp,v
retrieving revision 1.115
retrieving revision 1.116
diff -C2 -d -r1.115 -r1.116
*** player.cpp 7 Aug 2004 15:32:59 -0000 1.115
--- player.cpp 9 Aug 2004 20:30:21 -0000 1.116
***************
*** 96,102 ****
QString sqlString = QString( "SELECT %1 FROM uobjectmap,%2 WHERE uobjectmap.type = 'cPlayer' AND %3" ).arg( fields.join( "," ) ).arg( tables.join( "," ) ).arg( conditions.join( " AND " ) );
UObjectFactory::instance()->registerType( "cPlayer", productCreator );
! UObjectFactory::instance()->registerSqlQuery( "cPlayer", sqlString );
}
void cPlayer::buildSqlString( QStringList& fields, QStringList& tables, QStringList& conditions )
{
--- 96,104 ----
QString sqlString = QString( "SELECT %1 FROM uobjectmap,%2 WHERE uobjectmap.type = 'cPlayer' AND %3" ).arg( fields.join( "," ) ).arg( tables.join( "," ) ).arg( conditions.join( " AND " ) );
UObjectFactory::instance()->registerType( "cPlayer", productCreator );
! classid = UObjectFactory::instance()->registerSqlQuery( "cPlayer", sqlString );
}
+ unsigned char cPlayer::classid;
+
void cPlayer::buildSqlString( QStringList& fields, QStringList& tables, QStringList& conditions )
{
***************
*** 111,114 ****
--- 113,147 ----
static void playerRegisterAfterLoading( P_PLAYER pc );
+ void cPlayer::load(cBufferedReader &reader) {
+ load(reader, reader.version());
+
+ World::instance()->registerObject(this);
+ SectorMaps::instance()->add(this);
+ }
+
+ void cPlayer::load(cBufferedReader &reader, unsigned int version) {
+ cBaseChar::load(reader, version);
+ setAccount(Accounts::instance()->getRecord(reader.readUtf8()));
+ additionalFlags_ = reader.readInt();
+ visualRange_ = reader.readByte();
+ profile_ = reader.readUtf8();
+ fixedLightLevel_ = reader.readByte();
+ strengthLock_ = reader.readByte();
+ dexterityLock_ = reader.readByte();
+ intelligenceLock_ = reader.readByte();
+ }
+
+ void cPlayer::save(cBufferedWriter &writer, unsigned int version) {
+ cBaseChar::save(writer, version);
+ writer.writeUtf8(account_ ? account_->login() : QString::null);
+ writer.writeInt(additionalFlags_);
+ writer.writeByte(visualRange_);
+ writer.writeUtf8(profile_);
+ writer.writeByte(fixedLightLevel_);
+ writer.writeByte(strengthLock_);
+ writer.writeByte(dexterityLock_);
+ writer.writeByte(intelligenceLock_);
+ }
+
void cPlayer::load( char** result, UINT16& offset )
{
Index: world.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/world.cpp,v
retrieving revision 1.107
retrieving revision 1.108
diff -C2 -d -r1.107 -r1.108
*** world.cpp 4 Aug 2004 23:17:37 -0000 1.107
--- world.cpp 9 Aug 2004 20:30:22 -0000 1.108
***************
*** 81,84 ****
--- 81,85 ----
//
// ONCE AGAIN, DON'T FORGET TO INCREASE THIS VALUE
+ #define DATABASE_VERSION 6
#define WP_DATABASE_VERSION "6"
***************
*** 388,649 ****
}
! void cWorld::load()
! {
! if ( !PersistentBroker::instance()->openDriver( Config::instance()->databaseDriver() ) )
! {
! Console::instance()->log( LOG_ERROR, QString( "Unknown Worldsave Database Driver '%1', check your wolfpack.xml" ).arg( Config::instance()->databaseDriver() ) );
! return;
! }
! if ( !PersistentBroker::instance()->connect( Config::instance()->databaseHost(), Config::instance()->databaseName(), Config::instance()->databaseUsername(), Config::instance()->databasePassword() ) )
! {
! throw QString( "Unable to open the world database." );
}
! QString objectID;
! register unsigned int i = 0;
! while ( tableInfo[i].name )
! {
! if ( !PersistentBroker::instance()->tableExists( tableInfo[i].name ) )
! {
! PersistentBroker::instance()->executeQuery( tableInfo[i].create );
! // create default settings
! if ( !strcmp( tableInfo[i].name, "settings" ) )
! {
! setOption( "db_version", WP_DATABASE_VERSION, false );
! }
! }
! ++i;
! }
! QStringList types = UObjectFactory::instance()->objectTypes();
! for ( uint j = 0; j < types.count(); ++j )
! {
! QString type = types[j];
! cDBResult res = PersistentBroker::instance()->query( QString( "SELECT COUNT(*) FROM uobjectmap WHERE type = '%1'" ).arg( type ) );
! // Find out how many objects of this type are available
! if ( !res.isValid() )
! throw PersistentBroker::instance()->lastError();
! res.fetchrow();
! UINT32 count = res.getInt( 0 );
! res.free();
! if ( count == 0 )
! continue; // Move on...
! Console::instance()->send( "\n" + tr( "Loading " ) + QString::number( count ) + tr( " objects of type " ) + type );
! res = PersistentBroker::instance()->query( UObjectFactory::instance()->findSqlQuery( type ) );
! // Error Checking
! if ( !res.isValid() )
! throw PersistentBroker::instance()->lastError();
! //UINT32 sTime = getNormalizedTime();
! cUObject* object;
! progress_display progress( count );
! // Fetch row-by-row
! PersistentBroker::instance()->driver()->setActiveConnection( CONN_SECOND );
! while ( res.fetchrow() )
{
! unsigned short offset = 0;
! char** row = res.data();
! // do something with data
! object = UObjectFactory::instance()->createObject( type );
! object->load( row, offset );
! ++progress;
! }
! while ( progress.count() < progress.expected_count() )
! ++progress;
! res.free();
! PersistentBroker::instance()->driver()->setActiveConnection();
! }
! // Load Temporary Effects
! Timers::instance()->load();
! // It's not possible to use cItemIterator during postprocessing because it skips lingering items
! ItemMap::iterator iter;
! QPtrList<cItem> deleteItems;
! for ( iter = p->items.begin(); iter != p->items.end(); ++iter )
! {
! P_ITEM pi = iter->second;
! SERIAL contserial = reinterpret_cast<SERIAL>( pi->container() );
! SERIAL multiserial = ( SERIAL ) ( pi->multi() );
! cMulti* multi = dynamic_cast<cMulti*>( findItem( multiserial ) );
! pi->setMulti( multi );
! if ( multi )
! {
! multi->addObject( pi );
! }
! if ( !contserial )
! {
! pi->setUnprocessed( false ); // This is for safety reasons
! int max_x = Maps::instance()->mapTileWidth( pi->pos().map ) * 8;
! int max_y = Maps::instance()->mapTileHeight( pi->pos().map ) * 8;
! if ( pi->pos().x > max_x || pi->pos().y > max_y )
! {
! Console::instance()->log( LOG_ERROR, QString( "Item with invalid position %1,%2,%3,%4.\n" ).arg( pi->pos().x ).arg( pi->pos().y ).arg( pi->pos().z ).arg( pi->pos().map ) );
! deleteItems.append( pi );
! continue;
! }
! else
{
! MapObjects::instance()->add( pi );
}
}
! else
{
! // 1. Handle the Container Value
! if ( isItemSerial( contserial ) )
{
! P_ITEM pCont = FindItemBySerial( contserial );
! if ( pCont )
{
! pCont->addItem( pi, false, true, true );
}
else
{
! Console::instance()->log( LOG_ERROR, QString( "Item with invalid container [0x%1].\n" ).arg( contserial, 0, 16 ) );
! deleteItems.append( pi ); // Queue this item up for deletion
! continue; // Skip further processing
}
}
! else if ( isCharSerial( contserial ) )
{
! P_CHAR pCont = FindCharBySerial( contserial );
!
! if ( pCont )
{
! pCont->addItem( ( cBaseChar::enLayer ) pi->layer(), pi, true, true );
! }
! if ( !pCont || pi->container() != pCont )
{
! Console::instance()->log( LOG_ERROR, QString( "Item with invalid wearer [%1].\n" ).arg( contserial ) );
! deleteItems.append( pi );
! continue;
}
}
! pi->setUnprocessed( false );
}
! pi->flagUnchanged(); // We've just loaded, nothing changes.
! }
!
! // Post Process Characters
! cCharIterator charIter;
! P_CHAR pChar;
! for ( pChar = charIter.first(); pChar; pChar = charIter.next() )
! {
! P_NPC pNPC = dynamic_cast<P_NPC>( pChar );
!
! // Find Owner
! if ( pNPC && pNPC->owner() )
{
! SERIAL owner = pNPC->owner()->serial();
! P_PLAYER pOwner = dynamic_cast<P_PLAYER>( FindCharBySerial( owner ) );
! if ( pOwner )
{
! pNPC->setOwner( pOwner );
! pOwner->addPet( pNPC, true );
}
! else
{
! Console::instance()->send( QString( "The owner of Serial 0x%1 is invalid: %2" ).arg( pNPC->serial(), 0, 16 ).arg( owner, 0, 16 ) );
! pNPC->setOwner( NULL );
}
- }
! // Find Guarding
! if ( pChar->guarding() )
! {
! SERIAL guarding = ( SERIAL ) pChar->guarding();
! P_CHAR pGuarding = FindCharBySerial( guarding );
! if ( pGuarding )
! {
! pChar->setGuarding( pGuarding );
! pGuarding->addGuard( pChar, true );
! }
! else
{
! Console::instance()->send( tr( "The guard target of Serial 0x%1 is invalid: %2" ).arg( pChar->serial(), 16 ).arg( guarding, 16 ) );
! pChar->setGuarding( 0 );
}
- }
-
- cTerritory* region = Territories::instance()->region( pChar->pos().x, pChar->pos().y, pChar->pos().map );
- pChar->setRegion( region );
! SERIAL multiserial = ( SERIAL ) ( pChar->multi() );
! cMulti* multi = dynamic_cast<cMulti*>( findItem( multiserial ) );
! pChar->setMulti( multi );
! if ( multi )
! {
! multi->addObject( pChar );
}
! pChar->flagUnchanged(); // We've just loaded, nothing changes
! }
!
! if ( deleteItems.count() > 0 )
! {
! // Do we have to delete items?
! for ( P_ITEM pItem = deleteItems.first(); pItem; pItem = deleteItems.next() )
! quickdelete( pItem );
!
! Console::instance()->send( QString::number( deleteItems.count() ) + " deleted due to invalid container or position.\n" );
! deleteItems.clear();
! }
! // Load SpawnRegion information
! cDBResult result = PersistentBroker::instance()->query("SELECT spawnregion,serial FROM spawnregions;");
! while (result.fetchrow())
! {
! QString spawnregion = result.getSt...
[truncated message content] |