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;

};
Exemple #8
0
Sqf::Parameters HiveExtApp::booleanReturn( bool isGood )
{
	Sqf::Parameters retVal;
	string retStatus = "PASS";
	if (!isGood)
		retStatus = "ERROR";

	retVal.push_back(retStatus);
	return retVal;
}
Exemple #9
0
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);
	}
}
Exemple #11
0
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;
	}
}
Exemple #12
0
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();
		};
	};
};
Exemple #14
0
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;
}
Exemple #16
0
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());
	}
}