Server.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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 = new Game( zIni->zWert( "World" )->getText(), zIni->zWert( "SaveDir" )->getText() );
  38. new Framework::AsynchronCall( [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( 2000 );
  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->requestStop();
  88. game->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->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. Game* FactoryCraftServer::zGame() const
  157. {
  158. return game;
  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. if( foreground && background )
  210. zGameClient = ls->zGame()->addPlayer( dynamic_cast<FCKlient*>(getThis()), Framework::Text( (int)accountId ) );
  211. new AsynchronCall( [this]() {
  212. while( this->foreground->waitForNextMessage() )
  213. {
  214. if( zGameClient )
  215. zGameClient->addMessage( foregroundReader );
  216. if( !zGameClient )
  217. Sleep( 100 );
  218. }
  219. zGameClient->logout();
  220. ls->removeKlient( this );
  221. } );
  222. }
  223. void FCKlient::setBackgroundClient( SKlient* background )
  224. {
  225. this->background = background;
  226. if( foreground && background )
  227. zGameClient = ls->zGame()->addPlayer( dynamic_cast<FCKlient*>(getThis()), Framework::Text( (int)accountId ) );
  228. new AsynchronCall( [this]() {
  229. while( this->background->waitForNextMessage() )
  230. {
  231. if( zGameClient )
  232. zGameClient->addMessage( backgroundReader );
  233. if( !zGameClient )
  234. Sleep( 100 );
  235. }
  236. zGameClient->logout();
  237. ls->removeKlient( this );
  238. } );
  239. }
  240. void FCKlient::absturz()
  241. {
  242. ende();
  243. klient->trenne();
  244. }
  245. void FCKlient::thread()
  246. {
  247. while( 1 )
  248. {
  249. char c = 0;
  250. if( !klient->getNachricht( &c, 1 ) )
  251. break;
  252. else
  253. {
  254. bool br = 0;
  255. switch( c )
  256. {
  257. case 1: // Klient identifikation
  258. {
  259. int accountId = 0;
  260. klient->getNachricht( (char*)&accountId, 4 );
  261. unsigned char secretLength = 0;
  262. klient->getNachricht( (char*)&secretLength, 1 );
  263. char* secret = new char[ secretLength + 1 ];
  264. klient->getNachricht( secret, (int)secretLength );
  265. secret[ secretLength ] = 0;
  266. Text data = "{\"account_id\":";
  267. data += accountId;
  268. data += ", \"secret\": \"";
  269. data += secret;
  270. data += "\"}";
  271. bool ok = false;
  272. HTTP::Answer* answer = HTTP::PostRequest( "/game_client/api/verify_client.php", "koljastrohm-games.com", data, "application/json", 443, true ).execute();
  273. if( answer->getStatusCode() == 200 )
  274. {
  275. JSON::JSONObject obj( answer->getData() );
  276. if( obj.hasValue( "verified" ) )
  277. {
  278. JSON::JSONValue* value = obj.getValue( "verified" );
  279. if( value->getType() == JSON::JSONType::BOOLEAN )
  280. {
  281. if( ((JSON::JSONBool*)value)->getBool() )
  282. {
  283. this->accountId = accountId;
  284. if( zGameClient )
  285. {
  286. zGameClient->logout();
  287. zGameClient = (GameClient*)zGameClient->release();
  288. }
  289. klient->sende( "\1", 1 );
  290. klient->sende( (char*)&authKeyLen, 4 );
  291. klient->sende( authKey, authKeyLen );
  292. ok = true;
  293. }
  294. }
  295. value->release();
  296. }
  297. }
  298. answer->release();
  299. delete[]secret;
  300. if( !ok )
  301. klient->sende( "\0", 1 );
  302. break;
  303. }
  304. case 2: // Verbindungsende
  305. br = 1;
  306. if( zGameClient )
  307. {
  308. zGameClient->logout();
  309. zGameClient = (GameClient*)zGameClient->release();
  310. }
  311. klient->sende( "\1", 1 );
  312. break;
  313. default:
  314. br = 1;
  315. break;
  316. }
  317. if( br )
  318. break;
  319. }
  320. }
  321. }
  322. int FCKlient::getAccountId() const // gibt die KlientId zurück
  323. {
  324. return accountId;
  325. }
  326. NetworkWriter* FCKlient::zBackgroundWriter() const
  327. {
  328. return backgroundWriter;
  329. }
  330. NetworkWriter* FCKlient::zForegroundWriter() const
  331. {
  332. return foregroundWriter;
  333. }
  334. bool FCKlient::matchAuthKey( char* key, int len ) const
  335. {
  336. if( foreground && background )
  337. return 0;
  338. if( len != authKeyLen )
  339. return 0;
  340. for( int i = 0; i < len; i++ )
  341. {
  342. if( key[ i ] != authKey[ i ] )
  343. return 0;
  344. }
  345. return 1;
  346. }