void SqlCustDataSource::populateQuery(string query, Sqf::Parameters& params, CustomDataQueue& queue) { for (int i = 0; i < params.size(); i++) { query = boost::algorithm::replace_nth_copy(query, "?", i, Sqf::GetStringAny(params.at(i))); } auto custRes = getDB()->queryParams(query.c_str()); while (custRes->fetchRow()) { Sqf::Parameters custParams; for (int i = 0; i < custRes->numFields(); i++) { int val = custRes->at(i).getInt32(); if (val == 0 && custRes->at(i).getString() != "0") { custParams.push_back(custRes->at(i).getString()); } else { custParams.push_back(val); } } queue.push(custParams); } }
Sqf::Value SqlCharDataSource::fetchObjectId( Int64 objectIdent ) { Sqf::Parameters retVal; //get details from db auto charDetRes = getDB()->queryParams( "SELECT `ObjectID` FROM `Object_DATA` WHERE `ObjectUID`=%lld", objectIdent); if (charDetRes && charDetRes->fetchRow()) { int objectid = 0; //get stuff from row objectid = charDetRes->at(0).getInt32(); if(objectid != 0) { retVal.push_back(string("PASS")); retVal.push_back(lexical_cast<string>(objectid)); } else { retVal.push_back(string("ERROR")); } } else { retVal.push_back(string("ERROR")); } return retVal; }
void Database::populateHouses(std::queue<Sqf::Parameters>& queue) { try { Poco::Data::Statement stmt((*activeSession)); stmt << "select `player_id`, `unique_id`, `building_id`, `building_name`, `worldspace`, `lock`, `explosive`, `reinforcement` from `buildings` where `instance_id` = ?", use(serverID), now; Poco::Data::RecordSet rs(stmt); if (rs.columnCount() >= 1) { bool more = rs.moveFirst(); while (more) { Sqf::Parameters objParams; objParams.push_back(string("HOUSE")); string playerID = rs[0].convert<std::string>(); objParams.push_back(playerID); string uniqueID = rs[1].convert<std::string>(); objParams.push_back(uniqueID); string buildingID = rs[2].convert<std::string>(); objParams.push_back(buildingID); string buildingName = rs[3].convert<std::string>(); objParams.push_back(buildingName); try { string worldSpace = rs[4].convert<std::string>(); Sqf::Value worldSpaceArray = lexical_cast<Sqf::Value>(worldSpace); objParams.push_back(worldSpaceArray); } catch (boost::bad_lexical_cast) { console->log("Invalid Worldspace for House: " + buildingID); } string lock = rs[5].convert<std::string>(); objParams.push_back(lock); bool explosive = rs[6].convert<bool>(); objParams.push_back(explosive); int reinforcement = rs[7].convert<int>(); objParams.push_back(reinforcement); queue.push(objParams); more = rs.moveNext(); }; }; } catch (std::exception& ex) { std::cout << ex.what() << std::endl; }; };
void SqlAntiHackDataSource::fetchAntiHackWhitelist( AntiHackQueue& queue ) { auto antiHackRes = getDB()->queryParams( "SELECT antihack_whitelist.playerID FROM antihack_whitelist"); if (!antiHackRes) { _logger.error("Failed to fetch whitelist from database"); return; } string banId; while (antiHackRes->fetchRow()) { Sqf::Parameters ahParams; auto row = antiHackRes->fields(); //ahParams.push_back(string("BANS")); try { banId = row[0].getString(); //objectId should be stringified ahParams.push_back(banId); _logger.information("Pushed whitelists (" + lexical_cast<string>(banId) + ")"); } catch (const bad_lexical_cast&) { _logger.error("Skipping whitelist " + lexical_cast<string>(banId) + " load because of invalid data in db"); continue; } queue.push(ahParams); } }
void SqlAntiHackDataSource::fetchAntiHackAdmins( int serverId, int adminlevel, AntiHackQueue& queue ) { auto antiHackRes = getDB()->queryParams( "SELECT antihack_admins.playerID FROM antihack_admins WHERE antihack_admins.instance = %d and antihack_admins.adminlevel = %d", serverId, adminlevel); if (!antiHackRes) { _logger.error("Failed to fetch admins from database"); return; } string adminId; while (antiHackRes->fetchRow()) { Sqf::Parameters ahParams; auto row = antiHackRes->fields(); try { adminId = row[0].getString(); //objectId should be stringified ahParams.push_back(adminId); _logger.information("Pushed Admin (" + lexical_cast<string>(adminId) + ")"); } catch (const bad_lexical_cast&) { _logger.error("Skipping Admin " + lexical_cast<string>(adminId) + " load because of invalid data in db"); continue; } queue.push(ahParams); } }
void Database::populateTraps(std::queue<Sqf::Parameters>& queue) { try { Poco::Data::Statement stmt((*activeSession)); stmt << "select `unique_id`, `classname`, `worldspace` from `instance_traps` where `instance_id` = ?", use(serverID); stmt.execute(); Poco::Data::RecordSet rs(stmt); if (rs.columnCount() >= 1) { bool more = rs.moveFirst(); while (more) { Sqf::Parameters objParams; objParams.push_back(string("TRAP")); string uniqueID = rs[0].convert<std::string>(); objParams.push_back(uniqueID); string classname = rs[1].convert<std::string>(); objParams.push_back(classname); try { string worldSpace = rs[2].convert<std::string>(); Sqf::Value worldSpaceArray = lexical_cast<Sqf::Value>(worldSpace); objParams.push_back(worldSpaceArray); } catch (boost::bad_lexical_cast) { console->log("Invalid Worldspace for Trap: " + uniqueID); } queue.push(objParams); more = rs.moveNext(); }; }; } catch (std::exception& ex) { std::cout << ex.what() << std::endl; }; };
Sqf::Value Database::killCharacter(int characterID) { //Update Stats Profile { Poco::Data::Statement stmt((*activeSession)); stmt << "update `profile` p inner join `survivor` s on s.`unique_id` = p.`unique_id` set p.`survival_attempts` = p.`survival_attempts` + 1, p.`total_survivor_kills` = p.`total_survivor_kills` + s.`survivor_kills`, p.`total_zombie_kills` = p.`total_zombie_kills` + s.`zombie_kills`, p.`total_headshots` = p.`total_headshots` + s.`headshots`, p.`total_survival_time` = p.`total_survival_time` + s.`survival_time` where s.`id` = ? and s.`is_dead` = 0", use(characterID), now; } //Kill Character Poco::Data::Statement stmt((*activeSession)); stmt << "update `survivor` set `is_dead` = 1 where `id` = ?", use(characterID), now; //Return Success Sqf::Parameters retVal; retVal.push_back(string("PASS")); retVal.push_back(lexical_cast<string>(characterID)); return retVal; };
Sqf::Parameters HiveExtApp::booleanReturn( bool isGood ) { Sqf::Parameters retVal; string retStatus = "PASS"; if (!isGood) retStatus = "ERROR"; retVal.push_back(retStatus); return retVal; }
Sqf::Value HiveExtApp::loadTraderDetails( Sqf::Parameters params ) { if (_srvObjects.empty()) { int characterId = Sqf::GetIntAny(params.at(0)); _objData->populateTraderObjects(characterId, _srvObjects); Sqf::Parameters retVal; retVal.push_back(string("ObjectStreamStart")); retVal.push_back(static_cast<int>(_srvObjects.size())); return retVal; } else { Sqf::Parameters retVal = _srvObjects.front(); _srvObjects.pop(); return retVal; } }
void SqlObjDataSource::populateTraderObjects( int characterId, ServerObjectsQueue& queue ) { auto worldObjsRes = getDB()->queryParams("SELECT `id`, `item`, `qty`, `buy`, `sell`, `order`, `tid`, `afile` FROM `Traders_DATA` WHERE `tid`=%d", characterId); while (worldObjsRes->fetchRow()) { auto row = worldObjsRes->fields(); Sqf::Parameters objParams; objParams.push_back(row[0].getInt32()); // `item` varchar(255) NOT NULL COMMENT '[Class Name,1 = CfgMagazines | 2 = Vehicle | 3 = Weapon]', // `qty` int(8) NOT NULL COMMENT 'amount in stock available to buy', // `buy` varchar(255) NOT NULL COMMENT '[[Qty,Class,Type],]', // `sell` varchar(255) NOT NULL COMMENT '[[Qty,Class,Type],]', // `order` int(2) NOT NULL DEFAULT '0' COMMENT '# sort order for addAction menu', // `tid` int(8) NOT NULL COMMENT 'Trader Menu ID', // `afile` varchar(64) NOT NULL DEFAULT 'trade_items', //get stuff from row objParams.push_back(lexical_cast<Sqf::Value>(row[1].getString())); // item objParams.push_back(row[2].getInt32()); // qty objParams.push_back(lexical_cast<Sqf::Value>(row[3].getString())); // buy objParams.push_back(lexical_cast<Sqf::Value>(row[4].getString())); // sell objParams.push_back(row[5].getInt32()); // order objParams.push_back(row[6].getInt32()); // tid objParams.push_back(row[7].getString()); // afile queue.push(objParams); } }
Sqf::Value HiveExtApp::streamObjects( Sqf::Parameters params ) { if (_srvObjects.empty()) { int serverId = boost::get<int>(params.at(0)); setServerId(serverId); _objData->populateObjects(getServerId(), _srvObjects); Sqf::Parameters retVal; retVal.push_back(string("ObjectStreamStart")); retVal.push_back(static_cast<int>(_srvObjects.size())); return retVal; } else { Sqf::Parameters retVal = _srvObjects.front(); _srvObjects.pop(); return retVal; } }
Sqf::Value HiveExtApp::streamCustom( Sqf::Parameters params ) { if (_custQueue.empty()) { string query = Sqf::GetStringAny(params.at(0)); //if (!Sqf::IsNull(params.at(1))) Sqf::Parameters rawParams = boost::get<Sqf::Parameters>(params.at(1)); _custData->populateQuery(query, rawParams, _custQueue); Sqf::Parameters retVal; retVal.push_back(string("CustomStreamStart")); retVal.push_back(static_cast<int>(_custQueue.size())); return retVal; } else { Sqf::Parameters retVal = _custQueue.front(); _custQueue.pop(); return retVal; } }
void Database::populateHackData(int requestID, std::queue<Sqf::Parameters>& queue) { Poco::Data::Statement stmt((*activeSession)); switch (requestID) { //Weapons case 1: { stmt << "select `weapon` from `hack_weapons` where 1"; break; } //Magazines case 2: { stmt << "select `magazine` from `hack_magazines` where 1"; break; } //Vars case 3: { stmt << "select `var` from `hack_vars` where 1"; break; } //Scripts case 4: { stmt << "select `script` from `hack_scripts` where 1"; break; } } stmt.execute(); Poco::Data::RecordSet rs(stmt); if (rs.columnCount() >= 1) { bool more = rs.moveFirst(); while (more) { Sqf::Parameters objParams; string str = rs[0].convert<std::string>(); objParams.push_back(str); queue.push(objParams); more = rs.moveNext(); }; }; };
Sqf::Value HiveExtApp::getDateTime( Sqf::Parameters params ) { namespace pt=boost::posix_time; pt::ptime now = pt::second_clock::universal_time() + _timeOffset; Sqf::Parameters retVal; retVal.push_back(string("PASS")); { Sqf::Parameters dateTime; dateTime.push_back(static_cast<int>(now.date().year())); dateTime.push_back(static_cast<int>(now.date().month())); dateTime.push_back(static_cast<int>(now.date().day())); dateTime.push_back(static_cast<int>(now.time_of_day().hours())); dateTime.push_back(static_cast<int>(now.time_of_day().minutes())); retVal.push_back(dateTime); } return retVal; }
Sqf::Value SqlCharDataSource::fetchCharacterInitial( string playerId, int serverId, const string& playerName, int characterSlot ) { bool newPlayer = false; //make sure player exists in db { auto playerRes(getDB()->queryParams(("SELECT `PlayerName`, `PlayerSex` FROM `Player_DATA` WHERE `" + _idFieldName + "`='%s'").c_str(), getDB()->escape(playerId).c_str())); if (playerRes && playerRes->fetchRow()) { newPlayer = false; //update player name if not current if (playerRes->at(0).getString() != playerName) { auto stmt = getDB()->makeStatement(_stmtChangePlayerName, "UPDATE `Player_DATA` SET `PlayerName`=? WHERE `" + _idFieldName + "`=?"); stmt->addString(playerName); stmt->addString(playerId); bool exRes = stmt->execute(); poco_assert(exRes == true); _logger.information("Changed name of player " + playerId + " from '" + playerRes->at(0).getString() + "' to '" + playerName + "'"); } } else { newPlayer = true; //insert new player into db auto stmt = getDB()->makeStatement(_stmtInsertPlayer, "INSERT INTO `Player_DATA` (`" + _idFieldName + "`, `PlayerName`) VALUES (?, ?)"); stmt->addString(playerId); stmt->addString(playerName); bool exRes = stmt->execute(); poco_assert(exRes == true); _logger.information("Created a new player " + playerId + " named '" + playerName + "'"); } } //get characters from db auto charsRes = getDB()->queryParams( ("SELECT `CharacterID`, `" + _wsFieldName + "`, `Inventory`, `Backpack`, " "TIMESTAMPDIFF(MINUTE,`Datestamp`,`LastLogin`) as `SurvivalTime`, " "TIMESTAMPDIFF(MINUTE,`LastAte`,NOW()) as `MinsLastAte`, " "TIMESTAMPDIFF(MINUTE,`LastDrank`,NOW()) as `MinsLastDrank`, " "`Model` FROM `Character_DATA` WHERE `" + _idFieldName + "` = '%s' AND `Slot` = %d AND `Alive` = 1 ORDER BY `CharacterID` DESC LIMIT 1").c_str(), getDB()->escape(playerId).c_str(), characterSlot); int infected = 0; bool newChar = false; //not a new char int characterId = -1; //invalid charid Sqf::Value worldSpace = Sqf::Parameters(); //empty worldspace Sqf::Value inventory = lexical_cast<Sqf::Value>("[]"); //empty inventory Sqf::Value backpack = lexical_cast<Sqf::Value>("[]"); //empty backpack Sqf::Value survival = lexical_cast<Sqf::Value>("[0,0,0]"); //0 mins alive, 0 mins since last ate, 0 mins since last drank string model = ""; //empty models will be defaulted by scripts if (charsRes && charsRes->fetchRow()) { newChar = false; characterId = charsRes->at(0).getInt32(); try { worldSpace = lexical_cast<Sqf::Value>(charsRes->at(1).getString()); } catch (bad_lexical_cast) { _logger.warning("Invalid Worldspace for CharacterID(" + lexical_cast<string>(characterId)+"): " + charsRes->at(1).getString()); } if (!charsRes->at(2).isNull()) //inventory can be null { try { inventory = lexical_cast<Sqf::Value>(charsRes->at(2).getString()); try { SanitiseInv(boost::get<Sqf::Parameters>(inventory)); } catch (const boost::bad_get&) {} } catch (bad_lexical_cast) { _logger.warning("Invalid Inventory for CharacterID(" + lexical_cast<string>(characterId)+"): " + charsRes->at(2).getString()); } } if (!charsRes->at(3).isNull()) //backpack can be null { try { backpack = lexical_cast<Sqf::Value>(charsRes->at(3).getString()); } catch (bad_lexical_cast) { _logger.warning("Invalid Backpack for CharacterID(" + lexical_cast<string>(characterId)+"): " + charsRes->at(3).getString()); } } //set survival info { Sqf::Parameters& survivalArr = boost::get<Sqf::Parameters>(survival); survivalArr[0] = charsRes->at(4).getInt32(); survivalArr[1] = charsRes->at(5).getInt32(); survivalArr[2] = charsRes->at(6).getInt32(); } try { model = boost::get<string>(lexical_cast<Sqf::Value>(charsRes->at(7).getString())); } catch (...) { model = charsRes->at(7).getString(); } //update last login { //update last character login auto stmt = getDB()->makeStatement(_stmtUpdateCharacterLastLogin, "UPDATE `Character_DATA` SET `LastLogin` = CURRENT_TIMESTAMP WHERE `CharacterID` = ?"); stmt->addInt32(characterId); bool exRes = stmt->execute(); poco_assert(exRes == true); } } else //inserting new character { newChar = true; int generation = 1; int humanity = 2500; //try getting previous character info { auto prevCharRes = getDB()->queryParams( ("SELECT `Generation`, `Humanity`, `Model`, `Infected` FROM `Character_DATA` WHERE `" + _idFieldName + "` = '%s' AND `Slot` = %d AND `Alive` = 0 ORDER BY `CharacterID` DESC LIMIT 1").c_str(), getDB()->escape(playerId).c_str(), characterSlot); if (prevCharRes && prevCharRes->fetchRow()) { generation = prevCharRes->at(0).getInt32(); generation++; //apparently this was the correct behaviour all along humanity = prevCharRes->at(1).getInt32(); try { model = boost::get<string>(lexical_cast<Sqf::Value>(prevCharRes->at(2).getString())); } catch (...) { model = prevCharRes->at(2).getString(); } infected = prevCharRes->at(3).getInt32(); } } Sqf::Value medical = Sqf::Parameters(); //script will fill this in if empty //insert new char into db { auto stmt = getDB()->makeStatement(_stmtInsertNewCharacter, "INSERT INTO `Character_DATA` (`" + _idFieldName + "`, `Slot`, `InstanceID`, `" + _wsFieldName + "`, `Inventory`, `Backpack`, `Medical`, `Generation`, `Datestamp`, `LastLogin`, `LastAte`, `LastDrank`, `Humanity`) " "VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, ?)"); stmt->addString(playerId); stmt->addUInt8(characterSlot); stmt->addInt32(serverId); stmt->addString(lexical_cast<string>(worldSpace)); stmt->addString(lexical_cast<string>(inventory)); stmt->addString(lexical_cast<string>(backpack)); stmt->addString(lexical_cast<string>(medical)); stmt->addInt32(generation); stmt->addInt32(humanity); bool exRes = stmt->directExecute(); //need sync as we will be getting the CharacterID right after this if (exRes == false) { _logger.error("Error creating character for playerId " + playerId); Sqf::Parameters retVal; retVal.push_back(string("ERROR")); return retVal; } } //get the new character's id { auto newCharRes = getDB()->queryParams( ("SELECT `CharacterID` FROM `Character_DATA` WHERE `" + _idFieldName + "` = '%s' AND `Alive` = 1 ORDER BY `CharacterID` DESC LIMIT 1").c_str(), getDB()->escape(playerId).c_str()); if (!newCharRes || !newCharRes->fetchRow()) { _logger.error("Error fetching created character for playerId " + playerId); Sqf::Parameters retVal; retVal.push_back(string("ERROR")); return retVal; } characterId = newCharRes->at(0).getInt32(); } _logger.information("Created a new character " + lexical_cast<string>(characterId)+" for player '" + playerName + "' (" + playerId + ")"); } Sqf::Parameters retVal; retVal.push_back(string("PASS")); retVal.push_back(newPlayer); retVal.push_back(lexical_cast<string>(characterId)); if (!newChar) { retVal.push_back(worldSpace); retVal.push_back(inventory); retVal.push_back(backpack); retVal.push_back(survival); } else { retVal.push_back(infected); } retVal.push_back(model); //hive interface version retVal.push_back(0.96f); return retVal; }
void SqlObjDataSource::populateObjects( int serverId, ServerObjectsQueue& queue ) { if (_cleanupPlacedDays >= 0) { string commonSql = "FROM `"+_objTableName+"` WHERE `Instance` = " + lexical_cast<string>(serverId) + " AND `ObjectUID` <> 0 AND `CharacterID` <> 0" + " AND `Datestamp` < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL "+lexical_cast<string>(_cleanupPlacedDays)+" DAY)" + " AND ( (`Inventory` IS NULL) OR (`Inventory` = '[]') )"; int numCleaned = 0; { auto numObjsToClean = getDB()->query(("SELECT COUNT(*) "+commonSql).c_str()); if (numObjsToClean && numObjsToClean->fetchRow()) numCleaned = numObjsToClean->at(0).getInt32(); } if (numCleaned > 0) { _logger.information("Removing " + lexical_cast<string>(numCleaned) + " empty placed objects older than " + lexical_cast<string>(_cleanupPlacedDays) + " days"); auto stmt = getDB()->makeStatement(_stmtDeleteOldObject, "DELETE "+commonSql); if (!stmt->directExecute()) _logger.error("Error executing placed objects cleanup statement"); } } auto worldObjsRes = getDB()->queryParams("SELECT `ObjectID`, `Classname`, `CharacterID`, `Worldspace`, `Inventory`, `Hitpoints`, `Fuel`, `Damage` FROM `%s` WHERE `Instance`=%d AND `Classname` IS NOT NULL", _objTableName.c_str(), serverId); if (!worldObjsRes) { _logger.error("Failed to fetch objects from database"); return; } while (worldObjsRes->fetchRow()) { auto row = worldObjsRes->fields(); Sqf::Parameters objParams; objParams.push_back(string("OBJ")); int objectId = row[0].getInt32(); objParams.push_back(lexical_cast<string>(objectId)); //objectId should be stringified try { objParams.push_back(row[1].getString()); //classname objParams.push_back(lexical_cast<string>(row[2].getInt32())); //ownerId should be stringified Sqf::Value worldSpace = lexical_cast<Sqf::Value>(row[3].getString()); if (_vehicleOOBReset && row[2].getInt32() == 0) // no owner = vehicle { PositionInfo posInfo = FixOOBWorldspace(worldSpace); if (posInfo.is_initialized()) _logger.information("Reset ObjectID " + lexical_cast<string>(objectId) + " (" + row[1].getString() + ") from position " + lexical_cast<string>(*posInfo)); } objParams.push_back(worldSpace); //Inventory can be NULL { string invStr = "[]"; if (!row[4].isNull()) invStr = row[4].getString(); objParams.push_back(lexical_cast<Sqf::Value>(invStr)); } objParams.push_back(lexical_cast<Sqf::Value>(row[5].getCStr())); objParams.push_back(row[6].getDouble()); objParams.push_back(row[7].getDouble()); } catch (const bad_lexical_cast&) { _logger.error("Skipping ObjectID " + lexical_cast<string>(objectId) + " load because of invalid data in db"); continue; } queue.push(objParams); } }
Sqf::Value SqlCharDataSource::fetchCharacters( string playerId ) { //get characters from db (dead or alive) auto charsRes = getDB()->queryParams( ("SELECT `CharacterID`, `Slot`, `" + _wsFieldName + "`, `Alive`, `Generation`, `Humanity`, `KillsZ`, `HeadshotsZ`, `KillsH`, `KillsB`, `DistanceFoot`, `Model`, `Infected`, " "TIMESTAMPDIFF(MINUTE,`LastLogin`,NOW()) as `LastLoginDiff`, " "TIMESTAMPDIFF(MINUTE,`Datestamp`,`LastLogin`) as `SurvivalTime` " "FROM `Character_DATA` `cd1` " "INNER JOIN (SELECT MAX(`CharacterID`) `MaxCharacterID` FROM `Character_DATA` WHERE `" + _idFieldName + "` = '%s' GROUP BY `Slot`) `cd2` " "ON `cd1`.`CharacterID` = `cd2`.`MaxCharacterID` " "ORDER BY `Slot`").c_str(), getDB()->escape(playerId).c_str()); /* //get characters from db auto charsRes = getDB()->queryParams( ("SELECT `CharacterID`, `Slot`, `"+_wsFieldName+"`, `Generation`, `Humanity`, `KillsZ`, `HeadshotsZ`, `KillsH`, `KillsB`, `DistanceFoot`, `Model`, `Infected`, " "TIMESTAMPDIFF(MINUTE,`LastLogin`,NOW()) as `LastLoginDiff`, " "TIMESTAMPDIFF(MINUTE,`Datestamp`,`LastLogin`) as `SurvivalTime` " "FROM `Character_DATA` " "WHERE `"+_idFieldName+"` = '%s' AND `Alive` = 1 " "ORDER BY `Slot`").c_str(), getDB()->escape(playerId).c_str()); */ Sqf::Parameters retVal; Sqf::Parameters charsData; if (charsRes) { retVal.push_back(string("PASS")); while (charsRes->fetchRow()) { int characterId = charsRes->at(0).getUInt32(); int slot = charsRes->at(1).getUInt8(); Sqf::Value worldSpace = Sqf::Parameters(); //empty worldspace try { worldSpace = lexical_cast<Sqf::Value>(charsRes->at(2).getString()); } catch (bad_lexical_cast) { _logger.warning("Invalid Worldspace for CharacterID(" + lexical_cast<string>(characterId)+"): " + charsRes->at(2).getString()); } int alive = charsRes->at(3).getUInt8(); int generation = charsRes->at(4).getUInt32(); int humanity = charsRes->at(5).getInt32(); int killsZ = charsRes->at(6).getUInt32(); int headshotsZ = charsRes->at(7).getUInt32(); int killsH = charsRes->at(8).getUInt32(); int killsB = charsRes->at(9).getUInt32(); int distanceFoot = charsRes->at(10).getInt32(); string model = ""; try { model = boost::get<string>(lexical_cast<Sqf::Value>(charsRes->at(11).getString())); } catch (...) { model = charsRes->at(11).getString(); } int infected = charsRes->at(12).getInt8(); int lastLoginDiff = charsRes->at(13).getInt32(); int survivalTime = charsRes->at(14).getInt32(); Sqf::Parameters stats; stats.push_back(killsZ); stats.push_back(headshotsZ); stats.push_back(killsH); stats.push_back(killsB); Sqf::Parameters charData; charData.push_back(lexical_cast<string>(characterId)); charData.push_back(slot); charData.push_back(worldSpace); charData.push_back(alive); charData.push_back(generation); charData.push_back(humanity); charData.push_back(stats); charData.push_back(distanceFoot); charData.push_back(model); charData.push_back(infected); charData.push_back(lastLoginDiff); charData.push_back(survivalTime); charsData.push_back(charData); } } else { retVal.push_back(string("ERROR")); } retVal.push_back(charsData); //hive interface version retVal.push_back(0.96f); return retVal; }
Sqf::Value SqlCharDataSource::fetchCharacterDetails( int characterId ) { Sqf::Parameters retVal; //get details from db auto charDetRes = getDB()->queryParams( "SELECT `%s`, `Medical`, `Generation`, `KillsZ`, `HeadshotsZ`, `KillsH`, `KillsB`, `CurrentState`, `Humanity`, `InstanceID` " "FROM `Character_DATA` WHERE `CharacterID`=%d", _wsFieldName.c_str(), characterId); if (charDetRes && charDetRes->fetchRow()) { Sqf::Value worldSpace = Sqf::Parameters(); //empty worldspace Sqf::Value medical = Sqf::Parameters(); //script will fill this in if empty int generation = 1; Sqf::Value stats = lexical_cast<Sqf::Value>("[0,0,0,0]"); //killsZ, headZ, killsH, killsB Sqf::Value currentState = Sqf::Parameters(); //empty state (aiming, etc) int humanity = 2500; int instance = 1; //get stuff from row { try { worldSpace = lexical_cast<Sqf::Value>(charDetRes->at(0).getString()); } catch(bad_lexical_cast) { _logger.warning("Invalid Worldspace (detail load) for CharacterID("+lexical_cast<string>(characterId)+"): "+charDetRes->at(0).getString()); } try { medical = lexical_cast<Sqf::Value>(charDetRes->at(1).getString()); } catch(bad_lexical_cast) { _logger.warning("Invalid Medical (detail load) for CharacterID("+lexical_cast<string>(characterId)+"): "+charDetRes->at(1).getString()); } generation = charDetRes->at(2).getInt32(); //set stats { Sqf::Parameters& statsArr = boost::get<Sqf::Parameters>(stats); statsArr[0] = charDetRes->at(3).getInt32(); statsArr[1] = charDetRes->at(4).getInt32(); statsArr[2] = charDetRes->at(5).getInt32(); statsArr[3] = charDetRes->at(6).getInt32(); } try { currentState = lexical_cast<Sqf::Value>(charDetRes->at(7).getString()); } catch(bad_lexical_cast) { _logger.warning("Invalid CurrentState (detail load) for CharacterID("+lexical_cast<string>(characterId)+"): "+charDetRes->at(7).getString()); } humanity = charDetRes->at(8).getInt32(); instance = charDetRes->at(9).getInt32(); } retVal.push_back(string("PASS")); retVal.push_back(medical); retVal.push_back(stats); retVal.push_back(currentState); retVal.push_back(worldSpace); retVal.push_back(humanity); retVal.push_back(instance); } else { retVal.push_back(string("ERROR")); } return retVal; }
Sqf::Value SqlCharDataSource::fetchTraderObject( int traderObjectId, int action) { Sqf::Parameters retVal; //get details from db if(action == 0) { auto charDetRes = getDB()->queryParams( "SELECT `qty` FROM `Traders_DATA` WHERE `id`=%d", traderObjectId); if (charDetRes && charDetRes->fetchRow()) { int qty = 0; //get stuff from row qty = charDetRes->at(0).getInt32(); if(qty != 0) { auto stmt = getDB()->makeStatement(_stmtTradeObjectBuy, "UPDATE `Traders_DATA` SET qty = qty - 1 WHERE `id`= ?"); stmt->addInt32(traderObjectId); bool exRes = stmt->directExecute(); if(exRes == true) { retVal.push_back(string("PASS")); return retVal; } else { retVal.push_back(string("ERROR")); return retVal; } } else { retVal.push_back(string("ERROR")); return retVal; } } else { retVal.push_back(string("ERROR")); return retVal; } } else { auto stmt = getDB()->makeStatement(_stmtTradeObjectSell, "UPDATE `Traders_DATA` SET qty = qty + 1 WHERE `id`= ?"); stmt->addInt32(traderObjectId); bool exRes = stmt->directExecute(); if(exRes == true) { retVal.push_back(string("PASS")); return retVal; } else { retVal.push_back(string("ERROR")); return retVal; } } }
Sqf::Value Database::fetchCharacterDetails(int characterID) { try { Poco::Data::Statement stmt((*activeSession)); stmt << "select s.`worldspace`, s.`medical`, s.`zombie_kills`, s.`headshots`, s.`survivor_kills`, s.`state`, s.`class`, p.`ranger`, p.`outlaw`, p.`hunter`, p.`nomad`, p.`survivalist`, p.`engineer`, p.`undead`, p.`total_survivor_kills`, p.`clan` " << "from `survivor` s join `profile` p on s.`unique_id` = p.`unique_id` where s.`id` = ?", use(characterID), now; Sqf::Parameters retVal; Poco::Data::Statement updateInstance((*activeSession)); updateInstance << "update `survivor` set `lastserver` = ?, `activeserver` = ? where `id` = ?", use(serverID), use(serverID), use(characterID); updateInstance.executeAsync(); Poco::Data::RecordSet rs(stmt); if (rs.rowCount() > 0 && rs.columnCount() >= 1) { Sqf::Value worldSpace = Sqf::Parameters(); //empty worldspace Sqf::Value medical = Sqf::Parameters(); //script will fill this in if empty Sqf::Value stats = lexical_cast<Sqf::Value>("[0,0,0]"); //killsZ, headZ, killsH Sqf::Value currentState = Sqf::Parameters(); //empty state (aiming, etc) int myClass = 0; int ranger = 0; int outlaw = 0; int hunter = 0; int nomad = 0; int survivalist = 0; int engineer = 0; int undead = 0; int humanKills = 0; string clan = "0"; //Get Worldspace try { string ws = rs[0].convert<std::string>(); worldSpace = lexical_cast<Sqf::Value>(ws); } catch (boost::bad_lexical_cast) { console->log("Invalid Worldspace for Character: " + characterID); } //Get Medical try { string med = rs[1].convert<std::string>(); medical = lexical_cast<Sqf::Value>(med); } catch (boost::bad_lexical_cast) { console->log("Invalid Medical for Character: " + characterID); } //Get Stats try { Sqf::Parameters& statsArr = boost::get<Sqf::Parameters>(stats); int i; i = rs[2].convert<int>(); statsArr[0] = i; i = rs[3].convert<int>(); statsArr[1] = i; i = rs[4].convert<int>(); statsArr[2] = i; } catch (boost::bad_lexical_cast) { console->log("Invalid Stats for Character: " + characterID); } //Get Current State try { string state = rs[5].convert<std::string>(); currentState = lexical_cast<Sqf::Value>(state); } catch (boost::bad_lexical_cast) { console->log("Invalid State for Character: " + characterID); } myClass = rs[6].convert<int>(); ranger = rs[7].convert<int>(); outlaw = rs[8].convert<int>(); hunter = rs[9].convert<int>(); nomad = rs[10].convert<int>(); survivalist = rs[11].convert<int>(); engineer = rs[12].convert<int>(); undead = rs[13].convert<int>(); humanKills = rs[14].convert<int>(); clan = rs[15].convert<string>(); retVal.push_back(string("PASS")); retVal.push_back(medical); retVal.push_back(stats); retVal.push_back(currentState); retVal.push_back(worldSpace); retVal.push_back(myClass); retVal.push_back(ranger); retVal.push_back(outlaw); retVal.push_back(hunter); retVal.push_back(nomad); retVal.push_back(survivalist); retVal.push_back(engineer); retVal.push_back(undead); retVal.push_back(clan); //Wait for Async Update Player Model / Instance to finish updateInstance.wait(); } else { retVal.push_back(string("ERROR")); } return retVal; } catch (Poco::Exception const& ex) { Sqf::Parameters retVal; retVal.push_back(string("ERROR")); console->log(ex.what()); return retVal; } catch (boost::bad_lexical_cast const& ex) { Sqf::Parameters retVal; retVal.push_back(string("ERROR")); console->log(ex.what()); return retVal; } catch (boost::bad_get const& ex) { Sqf::Parameters retVal; retVal.push_back(string("ERROR")); console->log(ex.what()); return retVal; } catch (std::exception const& ex) { Sqf::Parameters retVal; retVal.push_back(string("ERROR")); console->log(ex.what()); return retVal; } };
Sqf::Value Database::fetchCharacterInitial(string playerID, string playerName) { try { bool newPlayer = false; std::string guid = VAC::convertSteamIDtoBEGUID(playerID); //Make Sure Player Exists in the Database { Poco::Data::Statement stmt((*activeSession)); stmt << "select `name` from `profile` WHERE `unique_id` = ?", use(playerID), now; Poco::Data::RecordSet rs(stmt); if (rs.rowCount() > 0 && rs.columnCount() >= 1) { std::string dbName = rs[0].convert<std::string>(); if (playerName != dbName) { Poco::Data::Statement name_stmt((*activeSession)); name_stmt << "update `profile` set `name` = ? where `unique_id` = ?", use(playerName), use(playerID), now; }; } else { newPlayer = true; Poco::Data::Statement profile_stmt((*activeSession)); profile_stmt << "insert into `profile` (`unique_id`, `name`, `guid`) values (?, ?, ?)", use(playerID), use(playerName), use(guid), now; } } //Get Characters From Database Poco::Data::Statement character_stmt((*activeSession)); character_stmt << "select s.`id`, s.`lastserver`, s.`activeserver`, s.`inventory`, s.`backpack`, " "timestampdiff(minute, s.`start_time`, s.`last_updated`) as `SurvivalTime`, " "timestampdiff(minute, s.`last_updated`, NOW()) as `MinsLastUpdate`, " //"timestampdiff(minute, s.`last_drank`, NOW()) as `MinsLastDrank`, " "s.`dog` from `survivor` s join `instance` i on s.`world_id` = i.`world_id` and i.`id` = ? where s.`unique_id` = ? and s.`is_dead` = 0", use(serverID), use(playerID), now; Poco::Data::RecordSet rs(character_stmt); bool newChar = false; //not a new char int characterID = -1; //invalid charid int lastServer = 0; int activeServer = 0; Sqf::Value inventory = lexical_cast<Sqf::Value>("[]"); //empty inventory Sqf::Value backpack = lexical_cast<Sqf::Value>("[]"); //empty backpack Sqf::Value survival = lexical_cast<Sqf::Value>("[0,0,0]"); //0 mins alive, 0 mins since last ate, 0 mins since last drank Sqf::Value medical = lexical_cast<Sqf::Value>("[false,false,false,false,false,false,false,0,12000,[],[0,0],0]"); string model = ""; //empty models will be defaulted by scripts Sqf::Value dog = lexical_cast<Sqf::Value>("[]"); //dog class id, dog hunger, dog thirst if (rs.rowCount() > 0 && rs.columnCount() >= 1) { characterID = rs[0].convert<int>(); lastServer = rs[1].convert<int>(); activeServer = rs[2].convert<int>(); string inv = rs[3].convert<std::string>(); inventory = lexical_cast<Sqf::Value>(inv); string bpk = rs[4].convert<std::string>(); backpack = lexical_cast<Sqf::Value>(bpk); { Sqf::Parameters& survivalArr = boost::get<Sqf::Parameters>(survival); int i; i = rs[5].convert<int>(); survivalArr[0] = i; i = rs[6].convert<int>(); survivalArr[1] = i; } string dg = rs[7].convert<std::string>(); dog = lexical_cast<Sqf::Value>(dg); } else { newChar = true; //Insert New Char into DB Poco::Data::Statement stmt((*activeSession)); stmt << "insert into `survivor` (`unique_id`, `world_id`) select ?, i.`world_id` from `instance` i where i.`id` = ?", use(playerID), use(serverID), now; //Get The New Character's ID { Poco::Data::Statement stmt((*activeSession)); stmt << "select s.`id` from `survivor` s join `instance` i on s.world_id = i.world_id and i.id = ? where s.`unique_id` = ? and s.`is_dead` = 0", use(serverID), use(playerID), now; Poco::Data::RecordSet rs(stmt); if (rs.rowCount() > 0 && rs.columnCount() >= 1) { characterID = rs[0].convert<int>(); } else { Sqf::Parameters retVal; retVal.push_back(string("ERROR")); return retVal; } } } //Always Push Back Full Login Details Sqf::Parameters retVal; retVal.push_back(string("PASS")); retVal.push_back(newChar); retVal.push_back(lexical_cast<string>(characterID)); retVal.push_back(inventory); retVal.push_back(survival); retVal.push_back(lastServer); retVal.push_back(activeServer); retVal.push_back(dog); retVal.push_back(guid); return retVal; } catch (Poco::Exception const& ex) { Sqf::Parameters retVal; retVal.push_back(string("ERROR")); console->log(ex.what()); return retVal; } catch (boost::bad_lexical_cast const& ex) { Sqf::Parameters retVal; retVal.push_back(string("ERROR")); console->log(ex.what()); return retVal; } catch (boost::bad_get const& ex) { Sqf::Parameters retVal; retVal.push_back(string("ERROR")); console->log(ex.what()); return retVal; } catch (std::exception const& ex) { Sqf::Parameters retVal; retVal.push_back(string("ERROR")); console->log(ex.what()); return retVal; } }
void Database::populateObjects(std::queue<Sqf::Parameters>& queue) { try { //Reset Ghosting Timer (Server Restart) for this instance Poco::Data::Statement ghostingStmt((*activeSession)); ghostingStmt << "UPDATE `survivor` SET `lastserver` = '0', `activeserver` = '0' WHERE `lastserver` = ? OR `activeserver` = ?", use(serverID), use(serverID); //Fetch Objects For This Instance Poco::Data::Statement stmt((*activeSession)); stmt << "select id.`unique_id`, d.`class_name`, id.`owner_id`, id.`player_id`, id.`worldspace`, id.`inventory`, id.`lock`, id.`building_id` from `instance_deployable` id inner join `deployable` d on id.`deployable_id` = d.`id` where id.`instance_id` = ? AND `deployable_id` IS NOT NULL", use(serverID); stmt.execute(); //Execute Ghosting Async ghostingStmt.executeAsync(); //Process Objects Data Set Poco::Data::RecordSet rs(stmt); if (rs.columnCount() >= 1) { bool more = rs.moveFirst(); while (more) { Sqf::Value worldSpace = Sqf::Parameters(); //[] Sqf::Value inventory = Sqf::Parameters(); //[] Sqf::Value parts = Sqf::Parameters(); //[] Sqf::Parameters objParams; objParams.push_back(string("OBJ")); string objectID = rs[0].convert<std::string>(); objParams.push_back(objectID); string classname = rs[1].convert<std::string>(); objParams.push_back(classname); string ownerID = rs[2].convert<std::string>(); objParams.push_back(ownerID); string playerID = rs[3].convert<std::string>(); objParams.push_back(playerID); try { string worldSpaceStr = rs[4].convert<std::string>(); worldSpace = lexical_cast<Sqf::Value>(worldSpaceStr); } catch (boost::bad_lexical_cast) { console->log("Invalid Worldspace for ObjectID: " + objectID); } objParams.push_back(worldSpace); try { string inventoryStr = rs[5].convert<std::string>(); inventory = lexical_cast<Sqf::Value>(inventoryStr); } catch (boost::bad_lexical_cast) { console->log("Invalid Inventory for ObjectID: " + objectID); } objParams.push_back(inventory); string lock = rs[6].convert<std::string>(); objParams.push_back(lock); string buildingID = rs[7].convert<std::string>(); objParams.push_back(buildingID); queue.push(objParams); more = rs.moveNext(); } } //Wait For Async Ghosting Timer Statement ghostingStmt.wait(); } catch (boost::bad_lexical_cast& ex) { console->log(ex.what()); } catch (boost::exception&) { console->log("unknown boost exception"); } catch (Data::MySQL::StatementException& ex) { console->log(ex.message()); } catch (Data::MySQL::TransactionException& ex) { console->log(ex.message()); } catch (std::exception& ex) { console->log(ex.what()); } }
void Database::populateVehicles(std::queue<Sqf::Parameters>& queue) { try { Poco::Data::Statement stmt((*activeSession)); stmt << "select `unique_id`, `classname`, `worldspace`, `inventory`, `parts`, `fuel`, `damage` from `instance_vehicle` where `instance_id` = ?", use(serverID), now; Poco::Data::RecordSet rs(stmt); if (rs.columnCount() >= 1) { bool more = rs.moveFirst(); while (more) { Sqf::Value worldSpace = Sqf::Parameters(); //[] Sqf::Value inventory = Sqf::Parameters(); //[] Sqf::Value parts = Sqf::Parameters(); //[] Sqf::Parameters objParams; objParams.push_back(string("VEH")); string uniqueID = rs[0].convert<std::string>(); objParams.push_back(uniqueID); string classname = rs[1].convert<std::string>(); objParams.push_back(classname); try { string worldSpaceStr = rs[2].convert<std::string>(); worldSpace = lexical_cast<Sqf::Value>(worldSpaceStr); } catch (boost::bad_lexical_cast) { console->log("Invalid Worldspace for ObjectID: " + uniqueID); } objParams.push_back(worldSpace); try { string inventoryStr = rs[3].convert<std::string>(); inventory = lexical_cast<Sqf::Value>(inventoryStr); } catch (boost::bad_lexical_cast) { console->log("Invalid Inventory for ObjectID: " + uniqueID); } objParams.push_back(inventory); try { string partsStr = rs[4].convert<std::string>(); parts = lexical_cast<Sqf::Value>(partsStr); } catch (boost::bad_lexical_cast) { console->log("Invalid Parts for ObjectID: " + uniqueID); } objParams.push_back(parts); double fuel = rs[5].convert<double>(); objParams.push_back(fuel); double damage = rs[6].convert<double>(); objParams.push_back(damage); queue.push(objParams); more = rs.moveNext(); } } } catch (boost::bad_lexical_cast& ex) { console->log(ex.what()); } catch (boost::exception&) { console->log("unknown boost exception"); } catch (Data::MySQL::StatementException& ex) { console->log(ex.message()); } catch (Data::MySQL::TransactionException& ex) { console->log(ex.message()); } catch (std::exception& ex) { console->log(ex.what()); } }