2017-08-08 13:53:47 +02:00
|
|
|
#include "SapphireAPI.h"
|
2018-03-06 22:22:19 +01:00
|
|
|
#include <Crypt/base64.h>
|
2017-08-08 13:53:47 +02:00
|
|
|
#include "Session.h"
|
|
|
|
#include "PlayerMinimal.h"
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#define BOOST_SPIRIT_THREADSAFE
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2017-08-08 13:53:47 +02:00
|
|
|
#include <boost/property_tree/ptree.hpp>
|
|
|
|
#include <boost/property_tree/xml_parser.hpp>
|
|
|
|
#include <boost/property_tree/json_parser.hpp>
|
|
|
|
#include <boost/foreach.hpp>
|
2017-10-26 12:16:34 +02:00
|
|
|
|
2018-10-26 19:57:39 +11:00
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
|
2018-03-06 22:22:19 +01:00
|
|
|
#include <Database/DatabaseDef.h>
|
2017-08-08 13:53:47 +02:00
|
|
|
|
|
|
|
Core::Network::SapphireAPI::SapphireAPI()
|
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Core::Network::SapphireAPI::~SapphireAPI()
|
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Core::Network::SapphireAPI::login( const std::string& username, const std::string& pass, std::string& sId )
|
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
std::string query =
|
|
|
|
"SELECT account_id FROM accounts WHERE account_name = '" + username + "' AND account_pass = '" + pass + "';";
|
|
|
|
|
|
|
|
// check if a user with that name / password exists
|
|
|
|
auto pQR = g_charaDb.query( query );
|
|
|
|
// found?
|
|
|
|
if( !pQR->next() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// user found, proceed
|
|
|
|
uint32_t accountId = pQR->getUInt( 1 );
|
|
|
|
|
|
|
|
// session id string generation
|
|
|
|
srand( ( uint32_t ) time( NULL ) + 42 );
|
|
|
|
uint8_t sid[58];
|
|
|
|
|
|
|
|
for( int32_t i = 0; i < 56; i += 4 )
|
|
|
|
{
|
|
|
|
short number = 0x1111 + rand() % 0xFFFF;
|
|
|
|
sprintf( ( char* ) sid + i, "%04hx", number );
|
|
|
|
}
|
|
|
|
|
|
|
|
// create session for the new sessionid and store to sessionlist
|
2018-10-25 12:44:51 +11:00
|
|
|
auto pSession = std::make_shared< Session >();
|
2018-08-29 21:40:59 +02:00
|
|
|
pSession->setAccountId( accountId );
|
|
|
|
pSession->setSessionId( sid );
|
|
|
|
|
|
|
|
std::stringstream ss;
|
|
|
|
|
|
|
|
for( size_t i = 0; i < 56; i++ )
|
|
|
|
{
|
|
|
|
ss << std::hex << sid[ i ];
|
|
|
|
}
|
|
|
|
m_sessionMap[ ss.str() ] = pSession;
|
|
|
|
sId = ss.str();
|
|
|
|
|
|
|
|
return true;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-08-08 22:55:02 +02:00
|
|
|
|
|
|
|
bool Core::Network::SapphireAPI::insertSession( const uint32_t& accountId, std::string& sId )
|
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
// create session for the new sessionid and store to sessionlist
|
2018-10-25 12:44:51 +11:00
|
|
|
auto pSession = std::make_shared< Session >();
|
2018-08-29 21:40:59 +02:00
|
|
|
pSession->setAccountId( accountId );
|
|
|
|
pSession->setSessionId( ( uint8_t* ) sId.c_str() );
|
2017-08-08 22:55:02 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
m_sessionMap[ sId ] = pSession;
|
2017-08-08 22:55:02 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return true;
|
2017-08-08 22:55:02 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-08-08 13:53:47 +02:00
|
|
|
bool Core::Network::SapphireAPI::createAccount( const std::string& username, const std::string& pass, std::string& sId )
|
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
// get account from login name
|
|
|
|
auto pQR = g_charaDb.query( "SELECT account_id FROM accounts WHERE account_name = '" + username + "';" );
|
|
|
|
// found?
|
|
|
|
if( pQR->next() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// we are clear and can create a new account
|
|
|
|
// get the next free account id
|
|
|
|
pQR = g_charaDb.query( "SELECT MAX(account_id) FROM accounts;" );
|
|
|
|
if( !pQR->next() )
|
|
|
|
return false;
|
|
|
|
uint32_t accountId = pQR->getUInt( 1 ) + 1;
|
|
|
|
|
|
|
|
// store the account to the db
|
|
|
|
g_charaDb.directExecute( "INSERT INTO accounts (account_Id, account_name, account_pass, account_created) VALUE( " +
|
|
|
|
std::to_string( accountId ) + ", '" +
|
|
|
|
username + "', '" +
|
|
|
|
pass + "', " +
|
|
|
|
std::to_string( time( nullptr ) ) + ");" );
|
|
|
|
|
|
|
|
|
|
|
|
if( !login( username, pass, sId ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
int
|
|
|
|
Core::Network::SapphireAPI::createCharacter( const int& accountId, const std::string& name, const std::string& infoJson,
|
|
|
|
const int& gmRank )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
Core::PlayerMinimal newPlayer;
|
|
|
|
|
|
|
|
newPlayer.setAccountId( accountId );
|
|
|
|
newPlayer.setId( getNextCharId() );
|
|
|
|
newPlayer.setContentId( getNextContentId() );
|
|
|
|
newPlayer.setName( name.c_str() );
|
|
|
|
|
|
|
|
boost::property_tree::ptree pt;
|
|
|
|
|
2018-10-26 19:57:39 +11:00
|
|
|
auto json = nlohmann::json::parse( infoJson );
|
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
std::stringstream ss;
|
|
|
|
ss << infoJson;
|
|
|
|
|
|
|
|
boost::property_tree::read_json( ss, pt );
|
|
|
|
|
|
|
|
const char* ptr = infoJson.c_str() + 50;
|
|
|
|
|
|
|
|
std::string lookPart( ptr );
|
|
|
|
int32_t pos = lookPart.find_first_of( "]" );
|
|
|
|
if( pos != std::string::npos )
|
|
|
|
{
|
|
|
|
lookPart = lookPart.substr( 0, pos + 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector< int32_t > tmpVector;
|
|
|
|
std::vector< int32_t > tmpVector2;
|
|
|
|
|
|
|
|
BOOST_FOREACH( boost::property_tree::ptree::value_type& v, pt.get_child( "content" ) )
|
|
|
|
{
|
|
|
|
boost::property_tree::ptree subtree1 = v.second;
|
|
|
|
BOOST_FOREACH( boost::property_tree::ptree::value_type& vs, subtree1 )
|
|
|
|
{
|
|
|
|
boost::property_tree::ptree subtree2 = vs.second;
|
|
|
|
//std::cout << vs.second.data();
|
|
|
|
tmpVector.push_back( std::stoi( vs.second.data() ) );
|
|
|
|
}
|
|
|
|
if( !v.second.data().empty() )
|
|
|
|
tmpVector2.push_back( std::stoi( v.second.data() ) );
|
|
|
|
}
|
|
|
|
std::vector< int32_t >::iterator it = tmpVector.begin();
|
|
|
|
for( int32_t i = 0; it != tmpVector.end(); ++it, i++ )
|
|
|
|
{
|
|
|
|
newPlayer.setLook( i, *it );
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string rest = infoJson.substr( pos + 53 );
|
|
|
|
|
|
|
|
newPlayer.setVoice( tmpVector2.at( 0 ) );
|
|
|
|
newPlayer.setGuardianDeity( tmpVector2.at( 1 ) );
|
|
|
|
newPlayer.setBirthDay( tmpVector2.at( 3 ), tmpVector2.at( 2 ) );
|
|
|
|
newPlayer.setClass( tmpVector2.at( 4 ) );
|
|
|
|
newPlayer.setTribe( tmpVector2.at( 5 ) );
|
|
|
|
newPlayer.setGmRank( gmRank );
|
|
|
|
|
|
|
|
newPlayer.saveAsNew();
|
|
|
|
|
|
|
|
return newPlayer.getAccountId();
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Network::SapphireAPI::deleteCharacter( std::string name, uint32_t accountId )
|
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
PlayerMinimal deletePlayer;
|
|
|
|
auto charList = getCharList( accountId );
|
|
|
|
for( uint32_t i = 0; i < charList.size(); i++ )
|
|
|
|
{
|
|
|
|
PlayerMinimal tmpPlayer = charList.at( i );
|
|
|
|
|
|
|
|
if( tmpPlayer.getName() == name )
|
|
|
|
{
|
|
|
|
deletePlayer = tmpPlayer;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t id = deletePlayer.getId();
|
|
|
|
|
|
|
|
g_charaDb.execute( "DELETE FROM charainfo WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
|
|
|
|
g_charaDb.execute( "DELETE FROM characlass WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
|
|
|
|
g_charaDb.execute( "DELETE FROM charaglobalitem WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
|
|
|
|
g_charaDb.execute( "DELETE FROM charainfoblacklist WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
|
|
|
|
g_charaDb.execute( "DELETE FROM charainfofriendlist WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
|
|
|
|
g_charaDb.execute( "DELETE FROM charainfolinkshell WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
|
|
|
|
g_charaDb.execute( "DELETE FROM charainfosearch WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
|
|
|
|
g_charaDb.execute( "DELETE FROM charaitemcrystal WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
|
|
|
|
g_charaDb.execute( "DELETE FROM charaiteminventory WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
|
|
|
|
g_charaDb.execute( "DELETE FROM charaitemgearset WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
|
|
|
|
g_charaDb.execute( "DELETE FROM charaquestnew WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
2017-10-26 12:16:34 +02:00
|
|
|
std::vector< Core::PlayerMinimal > Core::Network::SapphireAPI::getCharList( uint32_t accountId )
|
2017-08-08 13:53:47 +02:00
|
|
|
{
|
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
std::vector< Core::PlayerMinimal > charList;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
auto pQR = g_charaDb.query(
|
|
|
|
"SELECT CharacterId, ContentId FROM charainfo WHERE AccountId = " + std::to_string( accountId ) + ";" );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
while( pQR->next() )
|
|
|
|
{
|
|
|
|
Core::PlayerMinimal player;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
uint32_t charId = pQR->getUInt( 1 );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
player.load( charId );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
charList.push_back( player );
|
|
|
|
}
|
|
|
|
return charList;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Core::Network::SapphireAPI::checkNameTaken( std::string name )
|
|
|
|
{
|
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
g_charaDb.escapeString( name );
|
|
|
|
std::string query = "SELECT * FROM charainfo WHERE Name = '" + name + "';";
|
|
|
|
|
|
|
|
auto pQR = g_charaDb.query( query );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( !pQR->next() )
|
|
|
|
return false;
|
|
|
|
else
|
|
|
|
return true;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Core::Network::SapphireAPI::getNextCharId()
|
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
uint32_t charId = 0;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
auto pQR = g_charaDb.query( "SELECT MAX(CharacterId) FROM charainfo" );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( !pQR->next() )
|
|
|
|
return 0x00200001;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
charId = pQR->getUInt( 1 ) + 1;
|
|
|
|
if( charId < 0x00200001 )
|
|
|
|
return 0x00200001;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return charId;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t Core::Network::SapphireAPI::getNextContentId()
|
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
uint64_t contentId = 0;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
auto pQR = g_charaDb.query( "SELECT MAX(ContentId) FROM charainfo" );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( !pQR->next() )
|
|
|
|
return 0x0040000001000001;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
contentId = pQR->getUInt64( 1 ) + 1;
|
|
|
|
if( contentId < 0x0040000001000001 )
|
|
|
|
return 0x0040000001000001;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return contentId;
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int Core::Network::SapphireAPI::checkSession( const std::string& sId )
|
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
auto it = m_sessionMap.find( sId );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( it == m_sessionMap.end() )
|
|
|
|
return -1;
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return it->second->getAccountId();
|
2017-08-08 13:53:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Core::Network::SapphireAPI::removeSession( const std::string& sId )
|
|
|
|
{
|
2018-08-29 21:40:59 +02:00
|
|
|
auto it = m_sessionMap.find( sId );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
if( it != m_sessionMap.end() )
|
|
|
|
m_sessionMap.erase( sId );
|
2017-08-08 13:53:47 +02:00
|
|
|
|
2018-08-29 21:40:59 +02:00
|
|
|
return true;
|
2017-09-13 11:46:17 +02:00
|
|
|
}
|