/* * ObjectManager.cpp * * Created on: 13/11/2009 * Author: victor */ #include "ObjectManager.h" #include "objects.h" #include "server/db/ServerDatabase.h" #include "ObjectMap.h" #include "server/zone/Zone.h" #include "server/zone/ZoneProcessServer.h" #include "server/zone/managers/templates/TemplateManager.h" #include "server/zone/managers/objectcontroller/ObjectController.h" #include "server/zone/templates/SharedObjectTemplate.h" #include "server/chat/ChatManager.h" #include "engine/db/berkley/BTransaction.h" #include "ObjectVersionUpdateManager.h" #include "server/ServerCore.h" #include "server/zone/objects/scene/SceneObjectType.h" #include "DeleteCharactersTask.h" #include "server/conf/ConfigManager.h" #include "server/zone/objects/tangible/wearables/WearableContainerObject.h" using namespace engine::db; ObjectManager::ObjectManager() : DOBObjectManager() { server = NULL; deleteCharactersTask = new DeleteCharactersTask(); databaseManager = ObjectDatabaseManager::instance(); databaseManager->loadDatabases(ServerCore::truncateDatabases()); templateManager = TemplateManager::instance(); templateManager->loadLuaTemplates(); registerObjectTypes(); databaseManager->loadObjectDatabase("clientobjects", true, 0); databaseManager->loadObjectDatabase("sceneobjects", true); databaseManager->loadObjectDatabase("playerstructures", true); databaseManager->loadObjectDatabase("buffs", true); databaseManager->loadObjectDatabase("missionobjectives", true); databaseManager->loadObjectDatabase("missionobservers", true); databaseManager->loadObjectDatabase("cityregions", true); databaseManager->loadObjectDatabase("guilds", true); databaseManager->loadObjectDatabase("spawnareas", true); databaseManager->loadObjectDatabase("spawnobservers", true); databaseManager->loadObjectDatabase("aiobservers", true); ObjectDatabaseManager::instance()->commitLocalTransaction(); databaseManager->setLogLevel(databaseManager->DEBUG); loadLastUsedObjectID(); setLogging(false); setGlobalLogging(true); } ObjectManager::~ObjectManager() { //info("closing databases...", true); //ObjectDatabaseManager::instance()->finalize(); if (updateModifiedObjectsTask->isScheduled()) updateModifiedObjectsTask->cancel(); } void ObjectManager::registerObjectTypes() { info("registering object types"); //objectFactory.registerObject(0); objectFactory.registerObject(6); objectFactory.registerObject(SceneObjectType::LAIR); objectFactory.registerObject(SceneObjectType::FLORA); objectFactory.registerObject(SceneObjectType::FSVILLAGEAREA); objectFactory.registerObject(SceneObjectType::LAIRSPAWNAREA); objectFactory.registerObject(SceneObjectType::ACTIVEAREA); objectFactory.registerObject(SceneObjectType::BADGEAREA); objectFactory.registerObject(SceneObjectType::GARAGEAREA); objectFactory.registerObject(SceneObjectType::MISSIONSPAWNAREA); objectFactory.registerObject(SceneObjectType::MISSIONRECONAREA); objectFactory.registerObject(SceneObjectType::DYNAMICSPAWNAREA); objectFactory.registerObject(SceneObjectType::STATICSPAWNAREA); objectFactory.registerObject(SceneObjectType::CAMPAREA); objectFactory.registerObject(SceneObjectType::REGIONAREA); objectFactory.registerObject(SceneObjectType::STATICOBJECT); objectFactory.registerObject(SceneObjectType::CREATURE); objectFactory.registerObject(SceneObjectType::NPCCREATURE); objectFactory.registerObject(SceneObjectType::JUNKDEALERCREATURE); objectFactory.registerObject(SceneObjectType::DROIDCREATURE); objectFactory.registerObject(SceneObjectType::PROBOTCREATURE); objectFactory.registerObject(SceneObjectType::VENDOR); objectFactory.registerObject(SceneObjectType::PLAYERCREATURE); objectFactory.registerObject(SceneObjectType::INTANGIBLE); objectFactory.registerObject(SceneObjectType::DATA2); objectFactory.registerObject(SceneObjectType::ARMOR); objectFactory.registerObject(SceneObjectType::BODYARMOR); //chest plates objectFactory.registerObject(SceneObjectType::HEADARMOR); objectFactory.registerObject(SceneObjectType::MISCARMOR); // Some Belts Bando's' objectFactory.registerObject(SceneObjectType::LEGARMOR); objectFactory.registerObject(SceneObjectType::ARMARMOR); objectFactory.registerObject(SceneObjectType::HANDARMOR); objectFactory.registerObject(SceneObjectType::FOOTARMOR); objectFactory.registerObject(SceneObjectType::SHIELDGENERATOR); objectFactory.registerObject(SceneObjectType::TOOL); objectFactory.registerObject(SceneObjectType::REPAIRTOOL); objectFactory.registerObject(SceneObjectType::CRAFTINGTOOL); objectFactory.registerObject(SceneObjectType::SURVEYTOOL); objectFactory.registerObject(SceneObjectType::CRAFTINGSTATION); objectFactory.registerObject(SceneObjectType::FURNITURE); objectFactory.registerObject(SceneObjectType::SIGN); objectFactory.registerObject(SceneObjectType::INSTRUMENT); objectFactory.registerObject(SceneObjectType::FOOD); objectFactory.registerObject(SceneObjectType::DRINK); objectFactory.registerObject(SceneObjectType::CONTAINER); objectFactory.registerObject(SceneObjectType::FIREWORK); objectFactory.registerObject(SceneObjectType::ITEM); objectFactory.registerObject(SceneObjectType::GENERICITEM); objectFactory.registerObject(SceneObjectType::WEARABLECONTAINER); objectFactory.registerObject(SceneObjectType::LOOTKIT); objectFactory.registerObject(SceneObjectType::CAMPKIT); objectFactory.registerObject(SceneObjectType::STATICLOOTCONTAINER); objectFactory.registerObject(SceneObjectType::PLAYERLOOTCRATE); objectFactory.registerObject(SceneObjectType::SLICINGTOOL); objectFactory.registerObject(SceneObjectType::FLOWANALYZER); objectFactory.registerObject(SceneObjectType::MOLECULARCLAMP); objectFactory.registerObject(SceneObjectType::WEAPONUPGRADEKIT); objectFactory.registerObject(SceneObjectType::ARMORUPGRADEKIT); objectFactory.registerObject(SceneObjectType::LASERKNIFE); objectFactory.registerObject(SceneObjectType::CELLOBJECT); objectFactory.registerObject(SceneObjectType::PLAYEROBJECT); objectFactory.registerObject(SceneObjectType::WAYPOINT); objectFactory.registerObject(SceneObjectType::JEWELRY); objectFactory.registerObject(SceneObjectType::RING); objectFactory.registerObject(SceneObjectType::BRACELET); objectFactory.registerObject(SceneObjectType::NECKLACE); objectFactory.registerObject(SceneObjectType::EARRING); objectFactory.registerObject(SceneObjectType::ARMORATTACHMENT); objectFactory.registerObject(SceneObjectType::CLOTHINGATTACHMENT); objectFactory.registerObject(SceneObjectType::BUILDING); objectFactory.registerObject(SceneObjectType::CAPITOLBUILDING); objectFactory.registerObject(SceneObjectType::TUTORIALBUILDING); objectFactory.registerObject(SceneObjectType::HOSPITALBUILDING); objectFactory.registerObject(SceneObjectType::TRAVELBUILDING); objectFactory.registerObject(SceneObjectType::RECREATIONBUILDING); objectFactory.registerObject(SceneObjectType::STARPORTBUILDING); objectFactory.registerObject(SceneObjectType::FACTIONBUILDING); objectFactory.registerObject(SceneObjectType::HOTELBUILDING); objectFactory.registerObject(SceneObjectType::THEATERBUILDING); objectFactory.registerObject(SceneObjectType::COMBATBUILDING); objectFactory.registerObject(SceneObjectType::COMMERCEBUILDING); objectFactory.registerObject(SceneObjectType::UNIVERSITYBUILDING); objectFactory.registerObject(SceneObjectType::GARAGEBUILDING); objectFactory.registerObject(SceneObjectType::SALONBUILDING); objectFactory.registerObject(SceneObjectType::INSTALLATION); objectFactory.registerObject(SceneObjectType::GARAGEINSTALLATION); objectFactory.registerObject(SceneObjectType::SHUTTLEINSTALLATION); objectFactory.registerObject(SceneObjectType::HARVESTER); objectFactory.registerObject(SceneObjectType::FACTORY); objectFactory.registerObject(SceneObjectType::GENERATOR); objectFactory.registerObject(SceneObjectType::TURRET); objectFactory.registerObject(SceneObjectType::WEAPON); objectFactory.registerObject(SceneObjectType::MELEEWEAPON); objectFactory.registerObject(SceneObjectType::PISTOL); objectFactory.registerObject(SceneObjectType::RANGEDWEAPON); objectFactory.registerObject(SceneObjectType::ONEHANDMELEEWEAPON); objectFactory.registerObject(SceneObjectType::SPECIALHEAVYWEAPON); objectFactory.registerObject(SceneObjectType::HEAVYWEAPON); objectFactory.registerObject(SceneObjectType::RIFLE); objectFactory.registerObject(SceneObjectType::CARBINE); objectFactory.registerObject(SceneObjectType::POLEARM); objectFactory.registerObject(SceneObjectType::TWOHANDMELEEWEAPON); objectFactory.registerObject(SceneObjectType::MISSIONOBJECT); objectFactory.registerObject(SceneObjectType::TERMINAL); objectFactory.registerObject(SceneObjectType::INSURANCE); objectFactory.registerObject(SceneObjectType::SPACETERMINAL); objectFactory.registerObject(SceneObjectType::SHIPPINGTERMINAL); objectFactory.registerObject(SceneObjectType::INTERACTIVETERMINAL); objectFactory.registerObject(SceneObjectType::MISSIONTERMINAL); objectFactory.registerObject(SceneObjectType::BAZAAR); objectFactory.registerObject(SceneObjectType::BANK); objectFactory.registerObject(SceneObjectType::NEWBIETUTORIALTERMINAL); objectFactory.registerObject(SceneObjectType::CHARACTERBUILDERTERMINAL); objectFactory.registerObject(SceneObjectType::PLAYERTERMINALSTRUCTURE); objectFactory.registerObject(SceneObjectType::TICKETCOLLECTOR); objectFactory.registerObject(SceneObjectType::TRAVELTICKET); objectFactory.registerObject(SceneObjectType::TRAVELTERMINAL); objectFactory.registerObject(SceneObjectType::GUILDTERMINAL); objectFactory.registerObject(SceneObjectType::GAMBLINGTERMINAL); objectFactory.registerObject(SceneObjectType::CLONING); objectFactory.registerObject(SceneObjectType::DEED); objectFactory.registerObject(SceneObjectType::VEHICLEDEED); objectFactory.registerObject(SceneObjectType::BUILDINGDEED); objectFactory.registerObject(SceneObjectType::INSTALLATIONDEED); objectFactory.registerObject(SceneObjectType::RESOURCEDEED); objectFactory.registerObject(SceneObjectType::GROUPOBJECT); objectFactory.registerObject(SceneObjectType::GUILDOBJECT); objectFactory.registerObject(SceneObjectType::STIMPACK); objectFactory.registerObject(SceneObjectType::RANGEDSTIMPACK); objectFactory.registerObject(SceneObjectType::ENHANCEPACK); objectFactory.registerObject(SceneObjectType::CUREPACK); objectFactory.registerObject(SceneObjectType::DOTPACK); objectFactory.registerObject(SceneObjectType::WOUNDPACK); objectFactory.registerObject(SceneObjectType::STATEPACK); objectFactory.registerObject(SceneObjectType::REVIVEPACK); //clothing objectFactory.registerObject(SceneObjectType::CLOTHING); objectFactory.registerObject(SceneObjectType::BANDOLIER); objectFactory.registerObject(SceneObjectType::BELT); objectFactory.registerObject(SceneObjectType::BODYSUIT); objectFactory.registerObject(SceneObjectType::CAPE); objectFactory.registerObject(SceneObjectType::FOOTWEAR); objectFactory.registerObject(SceneObjectType::HEADWEAR); objectFactory.registerObject(SceneObjectType::EYEWEAR); objectFactory.registerObject(SceneObjectType::DRESS); objectFactory.registerObject(SceneObjectType::HANDWEAR); objectFactory.registerObject(SceneObjectType::JACKET); objectFactory.registerObject(SceneObjectType::PANTS); objectFactory.registerObject(SceneObjectType::ROBE); objectFactory.registerObject(SceneObjectType::SHIRT); objectFactory.registerObject(SceneObjectType::VEST); objectFactory.registerObject(SceneObjectType::WOOKIEGARB); objectFactory.registerObject(SceneObjectType::MISCCLOTHING); objectFactory.registerObject(SceneObjectType::SKIRT); //objectFactory.registerObject(SceneObjectType::ITHOGARB); objectFactory.registerObject(SceneObjectType::FISHINGPOLE); objectFactory.registerObject(SceneObjectType::FISHINGBAIT); objectFactory.registerObject(SceneObjectType::FISH); objectFactory.registerObject(SceneObjectType::TANGIBLE); objectFactory.registerObject(SceneObjectType::CLOAK); objectFactory.registerObject(SceneObjectType::TRAP); objectFactory.registerObject(SceneObjectType::CAMOKIT); objectFactory.registerObject(SceneObjectType::LIVESAMPLE); objectFactory.registerObject(SceneObjectType::VEHICLECONTROLDEVICE); objectFactory.registerObject(SceneObjectType::SHIPCONTROLDEVICE); objectFactory.registerObject(SceneObjectType::VEHICLE); objectFactory.registerObject(SceneObjectType::HOVERVEHICLE); objectFactory.registerObject(SceneObjectType::RESOURCESPAWN); objectFactory.registerObject(SceneObjectType::RESOURCECONTAINER); objectFactory.registerObject(SceneObjectType::ENERGYGAS); objectFactory.registerObject(SceneObjectType::ENERGYLIQUID); objectFactory.registerObject(SceneObjectType::ENERGYRADIOACTIVE); objectFactory.registerObject(SceneObjectType::ENERGYSOLID); objectFactory.registerObject(SceneObjectType::INORGANICCHEMICAL); objectFactory.registerObject(SceneObjectType::INORGANICGAS); objectFactory.registerObject(SceneObjectType::INORGANICMINERAL); objectFactory.registerObject(SceneObjectType::WATER); objectFactory.registerObject(SceneObjectType::ORGANICFOOD); objectFactory.registerObject(SceneObjectType::ORGANICHIDE); objectFactory.registerObject(SceneObjectType::ORGANICSTRUCTURAL); objectFactory.registerObject(SceneObjectType::QUESTREOURCE); objectFactory.registerObject(SceneObjectType::DRAFTSCHEMATIC); objectFactory.registerObject(SceneObjectType::MANUFACTURINGSCHEMATIC); objectFactory.registerObject(SceneObjectType::COMPONENT); objectFactory.registerObject(SceneObjectType::ARMORCOMPONENT); objectFactory.registerObject(SceneObjectType::CHEMISTRYCOMPONENT); objectFactory.registerObject(SceneObjectType::CLOTHINGCOMPONENT); objectFactory.registerObject(SceneObjectType::COMMUNITYCRAFTINGCOMPONENT); objectFactory.registerObject(SceneObjectType::DROIDCOMPONENT); objectFactory.registerObject(SceneObjectType::ELECTRONICSCOMPONENT); objectFactory.registerObject(SceneObjectType::GENETICCOMPONENT); objectFactory.registerObject(SceneObjectType::LIGHTSABERCRYSTAL); objectFactory.registerObject(SceneObjectType::MELEEWEAPONCOMPONENT); objectFactory.registerObject(SceneObjectType::MUNITIONCOMPONENT); objectFactory.registerObject(SceneObjectType::RANGEDWEAPONCOMPONENT); objectFactory.registerObject(SceneObjectType::STRUCTURECOMPONENT); objectFactory.registerObject(SceneObjectType::TISSUECOMPONENT); objectFactory.registerObject(SceneObjectType::WEAPONPOWERUP); objectFactory.registerObject(SceneObjectType::MELEEWEAPONPOWERUP); objectFactory.registerObject(SceneObjectType::RANGEDWEAPONPOWERUP); objectFactory.registerObject(SceneObjectType::THROWNWEAPONPOWERUP); objectFactory.registerObject(SceneObjectType::HEAVYWEAPONPOWERUP); objectFactory.registerObject(SceneObjectType::MINEPOWERUP); objectFactory.registerObject(SceneObjectType::SPECIALHEAVYWEAPONPOWERUP); objectFactory.registerObject(SceneObjectType::SHIPATTACHMENT); objectFactory.registerObject(SceneObjectType::SHIPREACTOR); objectFactory.registerObject(SceneObjectType::SHIPENGINE); objectFactory.registerObject(SceneObjectType::SHIPSHIELDGENERATOR); objectFactory.registerObject(SceneObjectType::SHIPARMOR); objectFactory.registerObject(SceneObjectType::SHIPWEAPON); objectFactory.registerObject(SceneObjectType::SHIPWEAPONCAPACITOR); objectFactory.registerObject(SceneObjectType::SHIPBOOSTER); objectFactory.registerObject(SceneObjectType::SHIPDRIODINTERFACE); objectFactory.registerObject(SceneObjectType::SHIPCHASSIS); objectFactory.registerObject(SceneObjectType::SHIPMISSILE); objectFactory.registerObject(SceneObjectType::SHIPCOUNTERMEASURE); objectFactory.registerObject(SceneObjectType::SHIPWEAPONLAUNCHER); objectFactory.registerObject(SceneObjectType::SHIPCOUNTERMEASURELAUNCHER); objectFactory.registerObject(SceneObjectType::FACTORYCRATE); objectFactory.registerObject(SceneObjectType::AIGROUP); objectFactory.registerObject(SceneObjectType::HERDGROUP); objectFactory.registerObject(SceneObjectType::PACKGROUP); objectFactory.registerObject(SceneObjectType::LAIRGROUP); objectFactory.registerObject(SceneObjectType::SHIPFIGHTER); objectFactory.registerObject(SceneObjectType::SHIPSTATION); } void ObjectManager::updateObjectVersion() { if (ObjectVersionUpdateManager::instance()->run() == 0) { ObjectDatabaseManager::instance()->commitLocalTransaction(); ObjectDatabaseManager::instance()->checkpoint(); } } void ObjectManager::loadLastUsedObjectID() { info("loading last used object id"); uint64 storedID = databaseManager->getLastUsedObjectID(); if (!ServerCore::truncateDatabases() && storedID != 0) { info("loading stored id.."); nextObjectID = storedID + 1; info("done loading last used object id 0x" + String::hexvalueOf((int64)nextObjectID).toUpperCase()); return; } info("loading bruteforce id.."); uint64 maxObjectID = 0; uint64 objectID; uint64 nullify = 0x0000FFFF; nullify = (nullify << 32) + 0xFFFFFFFF; for (int i = 0; i < databaseManager->getTotalDatabaseCount(); ++i) { LocalDatabase* database = databaseManager->getDatabase(i); if (!database->isObjectDatabase()) continue; ObjectDatabase* db = cast(database); String dbName; db->getDatabaseName(dbName); ObjectDatabaseIterator iterator(db); while (iterator.getNextKey(objectID)) { objectID = objectID & nullify; if (objectID > maxObjectID) maxObjectID = objectID; } } if (nextObjectID < maxObjectID + 1) nextObjectID = maxObjectID + 1; info("done loading last used object id 0x" + String::hexvalueOf((int64)nextObjectID).toUpperCase()); } void ObjectManager::loadStaticObjects() { Locker _locker(this); info("loading static objects...", true); ObjectDatabase* staticDatabase = databaseManager->loadObjectDatabase("clientobjects", true, 0); ObjectDatabaseIterator iterator(staticDatabase); uint32 serverObjectCRC; uint64 objectID; ObjectInputStream objectData(2000); while (iterator.getNextKeyAndValue(objectID, &objectData)) { SceneObject* object = cast(getObject(objectID)); if (object != NULL) continue; if (!Serializable::getVariable("SceneObject.serverObjectCRC", &serverObjectCRC, &objectData)) { error("unknown scene object in static database"); continue; } if (object == NULL) { object = createObject(serverObjectCRC, 0, "clientobjects", objectID); if (object == NULL) { error("could not load object from static database"); continue; } _locker.release(); String logName = object->getLoggingName(); deSerializeObject(object, &objectData); object->setLoggingName(logName); objectData.reset(); } } } int ObjectManager::updatePersistentObject(DistributedObject* object) { //use a linked list object->_setUpdated(true); return 0; } SceneObject* ObjectManager::loadObjectFromTemplate(uint32 objectCRC) { Locker _locker(this); SceneObject* object = NULL; try { SharedObjectTemplate* templateData = templateManager->getTemplate(objectCRC); if (templateData == NULL) { error("trying to create object with unknown objectcrc 0x" + String::hexvalueOf((int)objectCRC)); return NULL; } uint32 gameObjectType = templateData->getGameObjectType(); object = objectFactory.createObject(gameObjectType); if (object == NULL) { error("creating object unknown gameObjectType " + String::valueOf(gameObjectType)); return NULL; } databaseManager->addTemporaryObject(object); object->setServerObjectCRC(objectCRC); object->loadTemplateData(templateData); } catch (Exception& e) { error("exception caught in SceneObject* ObjectManager::loadObjectFromTemplate(uint32 objectCRC)"); error(e.getMessage()); e.printStackTrace(); } catch (...) { error("unreported exception caught in SceneObject* ObjectManager::loadObjectFromTemplate(uint32 objectCRC)"); throw; } return object; } /*ManagedObject* ObjectManager::cloneManagedObject(ManagedObject* object, bool makeTransient) { ObjectOutputStream objectData(500); object->writeObject(&objectData); objectData.reset(); ObjectInputStream objectInput; objectData.copy(&objectInput, 0); objectInput.reset(); DistributedObjectClassHelper* helper = object->_getClassHelper(); String className = helper->getClassName(); ManagedObject* clonedObject = NULL; ObjectDatabase* database = getTable(object->getObjectID()); String databaseName; if (database != NULL) { database->getDatabaseName(databaseName); } if (makeTransient || !object->isPersistent()) { clonedObject = createObject(className, 0, databaseName); clonedObject->setPersistent(0); } else if (object->isPersistent()) { clonedObject = createObject(className, object->getPersistenceLevel(), databaseName); } Locker locker(clonedObject); clonedObject->readObject(&objectInput); }*/ SceneObject* ObjectManager::cloneObject(SceneObject* object, bool makeTransient) { ObjectOutputStream objectData(500); (cast(object))->writeObject(&objectData); objectData.reset(); ObjectInputStream objectInput; objectData.copy(&objectInput, 0); objectInput.reset(); uint32 serverCRC = object->getServerObjectCRC(); SceneObject* clonedObject = NULL; ObjectDatabase* database = getTable(object->getObjectID()); String databaseName; uint64 oid; if (database != NULL) { database->getDatabaseName(databaseName); oid = getNextObjectID(databaseName); } else oid = getNextFreeObjectID(); clonedObject = instantiateSceneObject(serverCRC, oid, false); if (makeTransient || !object->isPersistent()) { //clonedObject = createObject(serverCRC, 0, databaseName); clonedObject->setPersistent(0); } else if (object->isPersistent()) { //clonedObject = createObject(serverCRC, object->getPersistenceLevel(), databaseName); clonedObject->setPersistent(object->getPersistenceLevel()); } Locker locker(clonedObject); clonedObject->readObject(&objectInput); clonedObject->createComponents(); clonedObject->setParent(NULL); if (clonedObject->isPersistent()) updatePersistentObject(clonedObject); return clonedObject; } void ObjectManager::persistObject(ManagedObject* object, int persistenceLevel, const String& database) { Locker _locker(this); if (object->isPersistent()) { //error("object is already persistent"); return; } if (database.length() > 0) { uint64 objectID = object->_getObjectID(); uint16 tableID = (uint16)(objectID >> 48); uint16 newDatabaseTableID = databaseManager->getDatabaseID(database); if (tableID != newDatabaseTableID) { uint64 newObjectID = getNextObjectID(database); object->_setObjectID(newObjectID); object->deploy(); } } else { throw Exception("no database specified in ObjectManager::persistObject"); } object->setPersistent(persistenceLevel); updatePersistentObject(object); } DistributedObjectStub* ObjectManager::loadPersistentObject(uint64 objectID) { DistributedObjectStub* object = NULL; Locker _locker(this); uint16 tableID = (uint16)(objectID >> 48); /*StringBuffer infoMsg; infoMsg << "trying to get database with table id 0x" << hex << tableID << " with obejct id 0x" << hex << objectID; info(infoMsg.toString(), true);*/ LocalDatabase* db = databaseManager->getDatabase(tableID); if (db == NULL || !db->isObjectDatabase()) return NULL; ObjectDatabase* database = cast( db); // only for debugging proposes DistributedObject* dobject = getObject(objectID); if (dobject != NULL) { //error("different object already in database"); return cast( dobject); } ObjectInputStream objectData(500); if (database->getData(objectID, &objectData)) { return NULL; } uint32 serverObjectCRC = 0; String className; try { if (Serializable::getVariable("SceneObject.serverObjectCRC", &serverObjectCRC, &objectData)) { object = instantiateSceneObject(serverObjectCRC, objectID, true); if (object == NULL) { error("could not load object from database"); return NULL; } _locker.release(); SceneObject* scene = cast(object); String loggingName = scene->getLoggingName(); uint32 templateObjectType = scene->getGameObjectType(); deSerializeObject(scene, &objectData); scene->setGameObjectType(templateObjectType); // we dont want this to be the old one scene->setLoggingName(loggingName); (cast(object))->info("loaded from db"); } else if (Serializable::getVariable("_className", &className, &objectData)) { object = createObject(className, false, "", objectID, false); if (object == NULL) { error("could not load object from database"); return NULL; } _locker.release(); deSerializeObject(cast(object), &objectData); } else { error("could not load object from database, unknown template crc or class name"); } } catch (...) { error("could not load object from database"); throw; } return object; } void ObjectManager::deSerializeObject(ManagedObject* object, ObjectInputStream* data) { Locker _locker(object); try { object->readObject(data); if (object->isPersistent()) object->queueUpdateToDatabaseTask(); // uint32 lastSaveCRC = managedObject->getLastCRCSave(); uint32 currentCRC = BaseProtocol::generateCRC(data); object->setLastCRCSave(currentCRC); object->notifyLoadFromDatabase(); } catch (Exception& e) { error(e.getMessage()); e.printStackTrace(); error("could not deserialize object from DB"); } catch (...) { error("could not deserialize object from DB"); throw; } } SceneObject* ObjectManager::instantiateSceneObject(uint32 objectCRC, uint64 oid, bool createComponents) { SceneObject* object = NULL; Locker _locker(this); object = loadObjectFromTemplate(objectCRC); if (object == NULL) return NULL; object->setZoneProcessServer(server); object->_setObjectID(oid); if (createComponents) object->createComponents(); String logName = object->getLoggingName(); StringBuffer newLogName; newLogName << logName << " 0x" << hex << oid; object->setLoggingName(newLogName.toString()); object->deploy(newLogName.toString()); info("deployed.." + newLogName.toString()); return object; } SceneObject* ObjectManager::createObject(uint32 objectCRC, int persistenceLevel, const String& database, uint64 oid) { SceneObject* object = NULL; loadTable(database, oid); if (oid == 0) { oid = getNextObjectID(database); } object = instantiateSceneObject(objectCRC, oid, true); if (object == NULL) { StringBuffer msg; msg << "could not create object CRC = 0x" << hex << objectCRC << " template:" << templateManager->getTemplateFile(objectCRC); error(msg.toString()); return NULL; } object->initializeTransientMembers(); if (persistenceLevel > 0) { object->setPersistent(persistenceLevel); updatePersistentObject(object); object->queueUpdateToDatabaseTask(); } return object; } ManagedObject* ObjectManager::createObject(const String& className, int persistenceLevel, const String& database, uint64 oid, bool initializeTransientMembers) { ManagedObject* object = NULL; Locker _locker(this); DistributedObjectBroker* broker = DistributedObjectBroker::instance(); object = cast(broker->createObjectStub(className, "")); DistributedObjectServant* servant = broker->createObjectServant(className, object); loadTable(database, oid); if (oid == 0) { oid = getNextObjectID(database); } object->_setObjectID(oid); servant->_serializationHelperMethod(); if (initializeTransientMembers) object->initializeTransientMembers(); object->setPersistent(persistenceLevel); object->deploy(); databaseManager->addTemporaryObject(object); if (persistenceLevel > 0) { updatePersistentObject(object); object->queueUpdateToDatabaseTask(); } return object; } void ObjectManager::createObjectID(const String& name, DistributedObjectStub* object) { Locker _locker(this); uint64 objectid = object->_getObjectID(); if (objectid == 0) { objectid = getNextFreeObjectID(); object->_setObjectID(objectid); } if (name.isEmpty()) { /*if (object->_getName().isEmpty())*/ { StringBuffer orbname; orbname << "_OrbObject" << objectid; object->_setName(orbname.toString()); } } else object->_setName(name); } uint64 ObjectManager::getNextObjectID(const String& database) { uint64 oid = 0; if (database.length() > 0) { uint16 tableID; tableID = databaseManager->getDatabaseID(database); oid += tableID; oid = oid << 48; } oid += getNextFreeObjectID(); return oid; } uint64 ObjectManager::getNextFreeObjectID() { //assert(DistributedObjectBroker::instance()->isRootBroker()); return DOBObjectManager::getNextFreeObjectID(); // its saved every 5min, that should be enough // databaseManager->updateLastUsedObjectID(val); //return nextObjectID; } ObjectDatabase* ObjectManager::loadTable(const String& database, uint64 objectID) { ObjectDatabase* table = NULL; if (database.length() > 0) { if (objectID != 0) { uint16 tableID = (uint16) (objectID >> 48); table = databaseManager->loadObjectDatabase(database, true, tableID); } else { table = databaseManager->loadObjectDatabase(database, true); } } return table; } int ObjectManager::destroyObjectFromDatabase(uint64 objectID) { Locker _locker(this); DistributedObject* obj = getObject(objectID); if (obj != NULL) { //setLogging(true); //info("Marking " + String::valueOf(objectID) + " for deletion deletion"); // setLogging(false); obj->_setMarkedForDeletion(true); } return 1; } void ObjectManager::printInfo() { StringBuffer msg; msg << "total objects in map " << localObjectDirectory.getSize(); info(msg.toString(), true); } String ObjectManager::getInfo() { StringBuffer msg; msg << "total objects in map " << localObjectDirectory.getSize(); return msg.toString(); } void ObjectManager::onUpdateModifiedObjectsToDatabase() { galaxyId = -1; if (server != NULL && server->getZoneServer() != NULL) { galaxyId = server->getZoneServer()->getGalaxyID(); //characters_dirty chars try { charactersSaved = ServerDatabase::instance()->executeQuery("SELECT * FROM characters_dirty WHERE galaxy_id = " + String::valueOf(galaxyId)); } catch (Exception& e) { error(e.getMessage()); } } } void ObjectManager::onCommitData() { if (charactersSaved != NULL) { try { StringBuffer query; query << "REPLACE INTO characters (character_oid, account_id, galaxy_id, firstname, surname, race, gender, template) VALUES"; StringBuffer deleteQuery; deleteQuery << "DELETE FROM characters_dirty WHERE "; bool first = true; int count = 0; while (charactersSaved->next()) { if (!first) { query << ","; deleteQuery << " OR "; } query << "(" << charactersSaved->getUnsignedLong(0) << ", " << charactersSaved->getInt(1) << ", " << charactersSaved->getInt(2) << ", " << "\'" << String(charactersSaved->getString(3)).escapeString() << "\', " << "\'" << String(charactersSaved->getString(4)).escapeString() << "\', " << charactersSaved->getInt(5) << ", " << charactersSaved->getInt(6) << ", \'" << String(charactersSaved->getString(7)).escapeString() << "')"; deleteQuery << "character_oid = " << charactersSaved->getUnsignedLong(0) << " AND galaxy_id = " << galaxyId; first = false; ++count; } if (count > 0) { ServerDatabase::instance()->executeStatement(query.toString()); ServerDatabase::instance()->executeStatement(deleteQuery.toString()); } } catch (Exception& e) { System::out << e.getMessage(); } } //Spawn the delete characters task. if (!deleteCharactersTask->isScheduled()) { deleteCharactersTask->updateDeletedCharacters(); int mins = ConfigManager::instance()->getPurgeDeletedCharacters(); deleteCharactersTask->schedule(mins * 60 * 1000); } }