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 HiveExtApp::loadPlayer( Sqf::Parameters params ) { string playerId = Sqf::GetStringAny(params.at(0)); string playerName = Sqf::GetStringAny(params.at(2)); return _charData->fetchCharacterInitial(playerId,getServerId(),playerName); }
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; }
Sqf::Value HiveExtApp::playerDeath( Sqf::Parameters params ) { int characterId = Sqf::GetIntAny(params.at(0)); int duration = static_cast<int>(Sqf::GetDouble(params.at(1))); return booleanReturn(_charData->killCharacter(characterId,duration)); }
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::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; }; };
Sqf::Value HiveExtApp::recordCharacterLogin( Sqf::Parameters params ) { string playerId = Sqf::GetStringAny(params.at(0)); int characterId = Sqf::GetIntAny(params.at(1)); int action = Sqf::GetIntAny(params.at(2)); //TODO: Get survivor ID return booleanReturn(_charData->recordLogEntry(playerId,0,getServerId(),action)); }
Sqf::Value HiveExtApp::playerInit( Sqf::Parameters params ) { int characterId = Sqf::GetIntAny(params.at(0)); Sqf::Value inventory = boost::get<Sqf::Parameters>(params.at(1)); Sqf::Value backpack = boost::get<Sqf::Parameters>(params.at(2)); return booleanReturn(_charData->initCharacter(characterId,inventory,backpack)); }
Sqf::Value HiveExtApp::recordCharacterLogin( Sqf::Parameters params ) { string playerId = Sqf::GetStringAny(params.at(0)); int characterId = Sqf::GetIntAny(params.at(1)); int action = Sqf::GetIntAny(params.at(2)); return booleanReturn(_charData->recordLogin(playerId,characterId,action)); }
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::objectInventory( Sqf::Parameters params, bool byUID /*= false*/ ) { Int64 objectIdent = Sqf::GetBigInt(params.at(0)); Sqf::Value inventory = boost::get<Sqf::Parameters>(params.at(1)); if (objectIdent != 0) //all the vehicles have objectUID = 0, so it would be bad to update those return booleanReturn(_objData->updateObjectInventory(getServerId(),objectIdent,byUID,inventory)); return booleanReturn(true); }
Sqf::Value HiveExtApp::vehicleMoved( Sqf::Parameters params ) { Int64 objectIdent = Sqf::GetBigInt(params.at(0)); Sqf::Value worldspace = boost::get<Sqf::Parameters>(params.at(1)); double fuel = Sqf::GetDouble(params.at(2)); if (objectIdent > 0) //sometimes script sends this with object id 0, which is bad return booleanReturn(_objData->updateVehicleMovement(getServerId(),objectIdent,worldspace,fuel)); return booleanReturn(true); }
Sqf::Value HiveExtApp::vehicleDamaged( Sqf::Parameters params ) { Int64 objectIdent = Sqf::GetBigInt(params.at(0)); Sqf::Value hitPoints = boost::get<Sqf::Parameters>(params.at(1)); double damage = Sqf::GetDouble(params.at(2)); if (objectIdent > 0) //sometimes script sends this with object id 0, which is bad return booleanReturn(_objData->updateVehicleStatus(getServerId(),objectIdent,hitPoints,damage)); return booleanReturn(true); }
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(); }; }; };
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; }; };
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::objectDelete( Sqf::Parameters params, bool byUID /*= false*/ ) { Int64 objectIdent = Sqf::GetBigInt(params.at(0)); if (objectIdent != 0) //all the vehicles have objectUID = 0, so it would be bad to delete those return booleanReturn(_objData->deleteObject(getServerId(),objectIdent,byUID)); return booleanReturn(true); }
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::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; } }
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; }
bool SqlCustDataSource::customExecute(string query, Sqf::Parameters& params) { static SqlStatementID stmtId; auto stmt = getDB()->makeStatement(stmtId, query); for (int i = 0; i < params.size(); i++) { try { stmt->addInt32(lexical_cast<int>(params.at(i))); } catch (bad_lexical_cast) { stmt->addString(lexical_cast<string>(params.at(i))); } } bool exRes = stmt->execute(); poco_assert(exRes == true); return exRes; }
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; } }
Sqf::Value HiveExtApp::objectPublish( Sqf::Parameters params ) { string className = boost::get<string>(params.at(1)); double damage = Sqf::GetDouble(params.at(2)); int characterId = Sqf::GetIntAny(params.at(3)); Sqf::Value worldSpace = boost::get<Sqf::Parameters>(params.at(4)); Sqf::Value inventory = boost::get<Sqf::Parameters>(params.at(5)); Sqf::Value hitPoints = boost::get<Sqf::Parameters>(params.at(6)); double fuel = Sqf::GetDouble(params.at(7)); Int64 uniqueId = Sqf::GetBigInt(params.at(8)); return booleanReturn(_objData->createObject(getServerId(),className,damage,characterId,worldSpace,inventory,hitPoints,fuel,uniqueId)); }
Sqf::Value HiveExtApp::objectPublish( Sqf::Parameters params ) { /*int serverId = boost::get<int>(params.at(0)); string className = boost::get<string>(params.at(1)); string characterId = Sqf::GetIntAny(params.at(2)); Sqf::Value worldSpace = boost::get<Sqf::Parameters>(params.at(3)); Int64 uniqueId = Sqf::GetBigInt(params.at(4)); */ int serverId = boost::get<int>(params.at(0)); string className = boost::get<string>(params.at(1)); double damage = Sqf::GetDouble(params.at(2)); int characterId = Sqf::GetIntAny(params.at(3)); Sqf::Value worldSpace = boost::get<Sqf::Parameters>(params.at(4)); Sqf::Value inventory = boost::get<Sqf::Parameters>(params.at(5)); Sqf::Value hitPoints = boost::get<Sqf::Parameters>(params.at(6)); double fuel = Sqf::GetDouble(params.at(7)); Int64 uniqueId = Sqf::GetBigInt(params.at(8)); //return booleanReturn(_objData->createObject(serverId,className,characterId,worldSpace,uniqueId)); //1:TentStorage:0:3:[329,[11173,3155.13,0.00391388]]:[]:[]:0:111730315510329:| return booleanReturn(_objData->createObject(serverId,className,damage,characterId,worldSpace,inventory,hitPoints,fuel,uniqueId)); }
Sqf::Value HiveExtApp::loadCharacterDetails( Sqf::Parameters params ) { int characterId = Sqf::GetIntAny(params.at(0)); return _charData->fetchCharacterDetails(characterId); }
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 HiveExtApp::customExecute( Sqf::Parameters params ) { string query = Sqf::GetStringAny(params.at(0)); Sqf::Parameters rawParams = boost::get<Sqf::Parameters>(params.at(1)); return _custData->customExecute(query, rawParams); }
Sqf::Value HiveExtApp::playerUpdate( Sqf::Parameters params ) { int characterId = Sqf::GetIntAny(params.at(0)); CharDataSource::FieldsType fields; try { if (!Sqf::IsNull(params.at(1))) { Sqf::Parameters worldSpaceArr = boost::get<Sqf::Parameters>(params.at(1)); if (worldSpaceArr.size() > 0) { Sqf::Value worldSpace = worldSpaceArr; fields["worldspace"] = worldSpace; } } if (!Sqf::IsNull(params.at(2))) { Sqf::Parameters inventoryArr = boost::get<Sqf::Parameters>(params.at(2)); if (inventoryArr.size() > 0) { Sqf::Value inventory = inventoryArr; fields["inventory"] = inventory; } } if (!Sqf::IsNull(params.at(3))) { Sqf::Parameters backpackArr = boost::get<Sqf::Parameters>(params.at(3)); if (backpackArr.size() > 0) { Sqf::Value backpack = backpackArr; fields["backpack"] = backpack; } } if (!Sqf::IsNull(params.at(4))) { Sqf::Parameters medicalArr = boost::get<Sqf::Parameters>(params.at(4)); if (medicalArr.size() > 0) { for (size_t i=0;i<medicalArr.size();i++) { if (Sqf::IsAny(medicalArr[i])) { logger().warning("update.medical["+lexical_cast<string>(i)+"] changed from any to []"); medicalArr[i] = Sqf::Parameters(); } } Sqf::Value medical = medicalArr; fields["medical"] = medical; } } if (!Sqf::IsNull(params.at(5))) { bool justAte = boost::get<bool>(params.at(5)); if (justAte) fields["just_ate"] = true; } if (!Sqf::IsNull(params.at(6))) { bool justDrank = boost::get<bool>(params.at(6)); if (justDrank) fields["just_drank"] = true; } if (!Sqf::IsNull(params.at(7))) { int moreKillsZ = boost::get<int>(params.at(7)); if (moreKillsZ > 0) fields["zombie_kills"] = moreKillsZ; } if (!Sqf::IsNull(params.at(8))) { int moreKillsH = boost::get<int>(params.at(8)); if (moreKillsH > 0) fields["headshots"] = moreKillsH; } if (!Sqf::IsNull(params.at(9))) { int distanceWalked = static_cast<int>(Sqf::GetDouble(params.at(9))); if (distanceWalked > 0) fields["DistanceFoot"] = distanceWalked; } if (!Sqf::IsNull(params.at(10))) { int durationLived = static_cast<int>(Sqf::GetDouble(params.at(10))); if (durationLived > 0) fields["survival_time"] = durationLived; } if (!Sqf::IsNull(params.at(11))) { Sqf::Parameters currentStateArr = boost::get<Sqf::Parameters>(params.at(11)); if (currentStateArr.size() > 0) { Sqf::Value currentState = currentStateArr; fields["state"] = currentState; } } if (!Sqf::IsNull(params.at(12))) { int moreKillsHuman = boost::get<int>(params.at(12)); if (moreKillsHuman > 0) fields["survivor_kills"] = moreKillsHuman; } if (!Sqf::IsNull(params.at(13))) { int moreKillsBandit = boost::get<int>(params.at(13)); if (moreKillsBandit > 0) fields["bandit_kills"] = moreKillsBandit; } if (!Sqf::IsNull(params.at(14))) { string newModel = boost::get<string>(params.at(14)); fields["model"] = newModel; } if (!Sqf::IsNull(params.at(15))) { int humanityDiff = static_cast<int>(Sqf::GetDouble(params.at(15))); if (humanityDiff != 0) fields["humanity"] = humanityDiff; } } catch (const std::out_of_range&) { logger().warning("Update of character " + lexical_cast<string>(characterId) + " only had " + lexical_cast<string>(params.size()) + " parameters out of 16"); } if (fields.size() > 0) return booleanReturn(_charData->updateCharacter(characterId,fields)); return booleanReturn(true); }