Server.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. #include "Server.h"
  2. #include <iostream>
  3. #include <Klient.h>
  4. #include <Globals.h>
  5. #include <HttpRequest.h>
  6. #include <JSON.h>
  7. #include <AsynchronCall.h>
  8. // Inhalt der LoginServer Klasse aus LoginServer.h
  9. // Konstruktor
  10. FactoryCraftServer::FactoryCraftServer( InitDatei* zIni )
  11. : ReferenceCounter()
  12. {
  13. Network::Start( 100 );
  14. runningThreads = 0;
  15. klients = new RCArray< FCKlient >();
  16. ini = dynamic_cast<InitDatei*>(zIni->getThis());
  17. id = *zIni->zWert( "ServerId" );
  18. sslServer = new SSLServer();
  19. sslServer->setPrivateKeyPassword( zIni->zWert( "SSLPasswort" )->getText() );
  20. sslServer->setCertificateFile( zIni->zWert( "SSLCert" )->getText() );
  21. std::cout << "using cert file " << zIni->zWert( "SSLCert" )->getText() << "\n";
  22. sslServer->setPrivateKeyFile( zIni->zWert( "SSLKey" )->getText() );
  23. std::cout << "using private key " << zIni->zWert( "SSLKey" )->getText() << "\n";
  24. server = new Server();
  25. std::cout << "Server Port: " << ini->zWert( "Port" )->getText() << "\n";
  26. if( !server->verbinde( (unsigned short)TextZuInt( ini->zWert( "Port" )->getText(), 10 ), 10 ) )
  27. {
  28. std::cout << "Der Server konnte nicht gestartet werden.\n";
  29. exit( 1 );
  30. }
  31. std::cout << "SSL Server Port: " << ini->zWert( "SSLPort" )->getText() << "\n";
  32. if( !sslServer->verbinde( (unsigned short)TextZuInt( ini->zWert( "SSLPort" )->getText(), 10 ), 10 ) )
  33. {
  34. std::cout << "Der SSL Server konnte nicht gestartet werden.\n";
  35. exit( 2 );
  36. }
  37. Game::initialize( zIni->zWert( "World" )->getText(), zIni->zWert( "SaveDir" )->getText() );
  38. new Framework::AsynchronCall( "Server", [this]() {
  39. runningThreads++;
  40. while( server->isConnected() )
  41. {
  42. SKlient* klient = server->getKlient();
  43. if( !klient )
  44. continue;
  45. unsigned short len;
  46. klient->setEmpfangTimeout( 5000 );
  47. klient->getNachricht( (char*)&len, 2 );
  48. char* key = new char[ len ];
  49. klient->getNachricht( (char*)key, len );
  50. bool bg;
  51. klient->getNachricht( (char*)&bg, 1 );
  52. klient->setEmpfangTimeout( 0 );
  53. bool found = 0;
  54. EnterCriticalSection( &cs );
  55. for( FCKlient* client : *klients )
  56. {
  57. if( client->matchAuthKey( key, len ) )
  58. {
  59. if( bg )
  60. client->setBackgroundClient( klient );
  61. else
  62. client->setForegroundClient( klient );
  63. found = 1;
  64. break;
  65. }
  66. }
  67. LeaveCriticalSection( &cs );
  68. if( !found )
  69. klient->release();
  70. }
  71. runningThreads--;
  72. } );
  73. InitializeCriticalSection( &cs );
  74. }
  75. // Destruktor
  76. FactoryCraftServer::~FactoryCraftServer()
  77. {
  78. sslServer->trenne();
  79. server->trenne();
  80. while( runningThreads > 0 )
  81. Sleep( 100 );
  82. sslServer->release();
  83. server->release();
  84. if( klients )
  85. klients->release();
  86. ini->release();
  87. Game::INSTANCE->requestStop();
  88. Game::INSTANCE->release();
  89. DeleteCriticalSection( &cs );
  90. }
  91. // nicht constant
  92. void FactoryCraftServer::run()
  93. {
  94. runningThreads++;
  95. while( sslServer->isConnected() )
  96. {
  97. SSLSKlient* klient = sslServer->getKlient();
  98. if( !klient )
  99. continue;
  100. Framework::getThreadRegister()->cleanUpClosedThreads();
  101. FCKlient* clHandle = new FCKlient( klient, dynamic_cast<FactoryCraftServer*>(getThis()) );
  102. EnterCriticalSection( &cs );
  103. klients->add( clHandle );
  104. LeaveCriticalSection( &cs );
  105. clHandle->start();
  106. }
  107. runningThreads--;
  108. }
  109. void FactoryCraftServer::close()
  110. {
  111. sslServer->trenne();
  112. EnterCriticalSection( &cs );
  113. for( int i = 0; i < klients->getEintragAnzahl(); i++ )
  114. klients->z( i )->absturz();
  115. klients = (RCArray< FCKlient > *)klients->release();
  116. Game::INSTANCE->save();
  117. LeaveCriticalSection( &cs );
  118. }
  119. bool FactoryCraftServer::absturzKlient( int accountId )
  120. {
  121. bool gefunden = 0;
  122. EnterCriticalSection( &cs );
  123. for( int i = 0; i < klients->getEintragAnzahl(); i++ )
  124. {
  125. if( klients->z( i ) && klients->z( i )->getAccountId() == accountId )
  126. {
  127. klients->z( i )->absturz();
  128. klients->remove( i );
  129. gefunden = 1;
  130. break;
  131. }
  132. }
  133. LeaveCriticalSection( &cs );
  134. return gefunden;
  135. }
  136. bool FactoryCraftServer::removeKlient( FCKlient* zKlient )
  137. {
  138. bool gefunden = 0;
  139. EnterCriticalSection( &cs );
  140. for( int i = 0; i < klients->getEintragAnzahl(); i++ )
  141. {
  142. if( klients->z( i ) == zKlient )
  143. {
  144. klients->remove( i );
  145. gefunden = 1;
  146. break;
  147. }
  148. }
  149. LeaveCriticalSection( &cs );
  150. return gefunden;
  151. }
  152. bool FactoryCraftServer::hatClients() const
  153. {
  154. return klients->hat( 0 );
  155. }
  156. int FactoryCraftServer::getUnencryptedPort() const
  157. {
  158. return server->getPort();
  159. }
  160. char* randomKey( int& len )
  161. {
  162. len = 1024 + (int)(((double)rand() / RAND_MAX - 0.5) * 512);
  163. char* key = new char[ len ];
  164. for( int i = 0; i < len; i++ )
  165. key[ i ] = (char)(((double)rand() / RAND_MAX) * 256);
  166. return key;
  167. }
  168. // Inhalt der LSKlient aus LoginServer.h
  169. // Konstruktor
  170. FCKlient::FCKlient( SSLSKlient* klient, FactoryCraftServer* ls )
  171. : Thread()
  172. {
  173. this->klient = klient;
  174. background = 0;
  175. foreground = 0;
  176. accountId = 0;
  177. this->ls = ls;
  178. zGameClient = 0;
  179. backgroundReader = 0;
  180. foregroundReader = 0;
  181. backgroundWriter = 0;
  182. foregroundWriter = 0;
  183. authKey = randomKey( authKeyLen );
  184. }
  185. // Destruktor
  186. FCKlient::~FCKlient()
  187. {
  188. if( zGameClient )
  189. {
  190. zGameClient->logout();
  191. zGameClient = (GameClient*)zGameClient->release();
  192. }
  193. if( background )
  194. background->release();
  195. if( foreground )
  196. foreground->release();
  197. delete backgroundReader;
  198. delete foregroundReader;
  199. delete backgroundWriter;
  200. delete foregroundWriter;
  201. klient->release();
  202. ls->release();
  203. delete[] authKey;
  204. }
  205. // nicht constant
  206. void FCKlient::setForegroundClient( SKlient* foreground )
  207. {
  208. this->foreground = foreground;
  209. foregroundReader = new NetworkReader( foreground );
  210. foregroundWriter = new NetworkWriter( foreground );
  211. if( foreground && background )
  212. zGameClient = Game::INSTANCE->addPlayer( dynamic_cast<FCKlient*>(getThis()), Framework::Text( (int)accountId ) );
  213. new AsynchronCall( [this]() {
  214. while( this->foreground->waitForNextMessage() )
  215. {
  216. if( zGameClient )
  217. zGameClient->addMessage( foregroundReader );
  218. if( !zGameClient )
  219. Sleep( 100 );
  220. }
  221. zGameClient->logout();
  222. ls->removeKlient( this );
  223. } );
  224. }
  225. void FCKlient::setBackgroundClient( SKlient* background )
  226. {
  227. this->background = background;
  228. backgroundReader = new NetworkReader( background );
  229. backgroundWriter = new NetworkWriter( background );
  230. if( foreground && background )
  231. zGameClient = Game::INSTANCE->addPlayer( dynamic_cast<FCKlient*>(getThis()), Framework::Text( (int)accountId ) );
  232. new AsynchronCall( [this]() {
  233. while( this->background->waitForNextMessage() )
  234. {
  235. if( zGameClient )
  236. zGameClient->addMessage( backgroundReader );
  237. if( !zGameClient )
  238. Sleep( 100 );
  239. }
  240. zGameClient->logout();
  241. ls->removeKlient( this );
  242. } );
  243. }
  244. void FCKlient::absturz()
  245. {
  246. ende();
  247. klient->trenne();
  248. }
  249. void FCKlient::thread()
  250. {
  251. while( 1 )
  252. {
  253. char c = 0;
  254. if( !klient->getNachricht( &c, 1 ) )
  255. break;
  256. else
  257. {
  258. bool br = 0;
  259. switch( c )
  260. {
  261. case 1: // Klient identifikation
  262. {
  263. int accountId = 0;
  264. klient->getNachricht( (char*)&accountId, 4 );
  265. unsigned char secretLength = 0;
  266. klient->getNachricht( (char*)&secretLength, 1 );
  267. char* secret = new char[ secretLength + 1 ];
  268. klient->getNachricht( secret, (int)secretLength );
  269. secret[ secretLength ] = 0;
  270. Text data = "{\"account_id\":";
  271. data += accountId;
  272. data += ", \"secret\": \"";
  273. data += secret;
  274. data += "\"}";
  275. bool ok = false;
  276. HTTP::Answer* answer = HTTP::PostRequest( "/game_client/api/verify_client.php", "koljastrohm-games.com", data, "application/json", 443, true ).execute();
  277. if( answer->getStatusCode() == 200 )
  278. {
  279. JSON::JSONObject obj( answer->getData() );
  280. if( obj.hasValue( "verified" ) )
  281. {
  282. JSON::JSONValue* value = obj.getValue( "verified" );
  283. if( value->getType() == JSON::JSONType::BOOLEAN )
  284. {
  285. if( ((JSON::JSONBool*)value)->getBool() )
  286. {
  287. this->accountId = accountId;
  288. if( zGameClient )
  289. {
  290. zGameClient->logout();
  291. zGameClient = (GameClient*)zGameClient->release();
  292. }
  293. klient->sende( "\1", 1 );
  294. klient->sende( (char*)&authKeyLen, 4 );
  295. klient->sende( authKey, authKeyLen );
  296. int port = ls->getUnencryptedPort();
  297. klient->sende( (char*)&port, 4 );
  298. ok = true;
  299. }
  300. }
  301. value->release();
  302. }
  303. }
  304. answer->release();
  305. delete[]secret;
  306. if( !ok )
  307. klient->sende( "\0", 1 );
  308. break;
  309. }
  310. case 2: // Verbindungsende
  311. br = 1;
  312. if( zGameClient )
  313. {
  314. zGameClient->logout();
  315. zGameClient = (GameClient*)zGameClient->release();
  316. }
  317. klient->sende( "\1", 1 );
  318. break;
  319. default:
  320. br = 1;
  321. break;
  322. }
  323. if( br )
  324. break;
  325. }
  326. }
  327. }
  328. int FCKlient::getAccountId() const // gibt die KlientId zurück
  329. {
  330. return accountId;
  331. }
  332. NetworkWriter* FCKlient::zBackgroundWriter() const
  333. {
  334. return backgroundWriter;
  335. }
  336. NetworkWriter* FCKlient::zForegroundWriter() const
  337. {
  338. return foregroundWriter;
  339. }
  340. bool FCKlient::matchAuthKey( char* key, int len ) const
  341. {
  342. if( foreground && background )
  343. return 0;
  344. if( len != authKeyLen )
  345. return 0;
  346. for( int i = 0; i < len; i++ )
  347. {
  348. if( key[ i ] != authKey[ i ] )
  349. return 0;
  350. }
  351. return 1;
  352. }