Game.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227
  1. #include "Game.h"
  2. #include <Datei.h>
  3. #include <Logging.h>
  4. #include "Chat.h"
  5. #include "Dimension.h"
  6. #include "Entity.h"
  7. #include "ItemEntity.h"
  8. #include "JsonUtils.h"
  9. #include "MultiblockTree.h"
  10. #include "NetworkMessage.h"
  11. #include "NoBlock.h"
  12. #include "Player.h"
  13. #include "PlayerHand.h"
  14. #include "PlayerRegister.h"
  15. #include "Quest.h"
  16. #include "RecipieLoader.h"
  17. #include "Server.h"
  18. #include "TickOrganizer.h"
  19. #include "UIController.h"
  20. #include "WorldGenerator.h"
  21. #include "WorldLoader.h"
  22. #include "Zeit.h"
  23. using namespace Framework;
  24. Framework::ConsoleHandler* Game::consoleHandler = 0;
  25. Framework::InputLine* Game::consoleInput = 0;
  26. Game::Game(Framework::Text name, Framework::Text worldsDir)
  27. : Thread(),
  28. name(name),
  29. typeRegistry(new TypeRegistry()),
  30. blockTypeNameFactory(new BlockTypeNameFactory()),
  31. itemTypeNameFactory(new ItemTypeNameFactory()),
  32. dimensions(new RCArray<Dimension>()),
  33. clients(new RCArray<GameClient>()),
  34. questManager(new QuestManager()),
  35. ticker(new TickOrganizer()),
  36. path((const char*)(worldsDir + "/" + name)),
  37. stop(0),
  38. tickId(0),
  39. nextEntityId(0),
  40. generator(0),
  41. loader(0),
  42. recipies(new RecipieLoader()),
  43. chat(0),
  44. playerRegister(new PlayerRegister(path)),
  45. uiController(new UIController()),
  46. totalTickTime(0),
  47. tickCounter(0),
  48. averageTickTime(0),
  49. ticksPerSecond(0),
  50. totalTime(0),
  51. blockTypes(0),
  52. blockTypeCount(0),
  53. itemTypes(0),
  54. itemTypeCount(0),
  55. entityTypes(0),
  56. entityTypeCount(0),
  57. multiblockStructureTypes(0),
  58. multiblockStructureTypeCount(0)
  59. {
  60. typeRegistry->registerType(
  61. BlockTypeNameFactory::TYPE_ID, blockTypeNameFactory);
  62. typeRegistry->registerType(
  63. ItemTypeNameFactory::TYPE_ID, itemTypeNameFactory);
  64. if (!DateiExistiert(path)) DateiPfadErstellen(path + "/");
  65. Datei d;
  66. d.setDatei(path + "/eid");
  67. if (d.existiert())
  68. {
  69. d.open(Datei::Style::lesen);
  70. d.lese((char*)&nextEntityId, 4);
  71. d.close();
  72. }
  73. start();
  74. }
  75. Game::~Game()
  76. {
  77. dimensions->release();
  78. clients->release();
  79. generator->release();
  80. loader->release();
  81. chat->release();
  82. playerRegister->release();
  83. typeRegistry->release();
  84. uiController->release();
  85. recipies->release();
  86. for (int i = 0; i < blockTypeCount; i++)
  87. {
  88. if (blockTypes[i]) blockTypes[i]->release();
  89. }
  90. delete[] blockTypes;
  91. for (int i = 0; i < itemTypeCount; i++)
  92. {
  93. if (itemTypes[i]) itemTypes[i]->release();
  94. }
  95. delete[] itemTypes;
  96. for (int i = 0; i < entityTypeCount; i++)
  97. {
  98. if (entityTypes[i]) entityTypes[i]->release();
  99. }
  100. delete[] entityTypes;
  101. for (int i = 0; i < multiblockStructureTypeCount; i++)
  102. {
  103. if (multiblockStructureTypes[i]) multiblockStructureTypes[i]->release();
  104. }
  105. delete[] multiblockStructureTypes;
  106. }
  107. void Game::initialize()
  108. {
  109. // TODO load mods libraries
  110. // load block types
  111. Framework::Logging::info() << "Loading block types";
  112. Framework::Array<BlockType*> blockTypeArray;
  113. Framework::Validator::DataValidator* validator
  114. = Framework::Validator::DataValidator::buildForArray()
  115. ->addAcceptedTypeInArray(typeRegistry->getValidator<BlockType>())
  116. ->removeInvalidEntries()
  117. ->finishArray();
  118. loadAllJsonsFromDirectory("data/blocks",
  119. [this, &blockTypeArray, validator](
  120. Framework::JSON::JSONValue* zValue, Framework::Text path) {
  121. Framework::RCArray<Framework::Validator::ValidationResult>
  122. validationResults;
  123. Framework::JSON::JSONValue* validParts
  124. = validator->getValidParts(zValue, &validationResults);
  125. for (Framework::Validator::ValidationResult* result :
  126. validationResults)
  127. {
  128. Framework::Logging::error() << result->getInvalidInfo();
  129. }
  130. if (validParts)
  131. {
  132. for (Framework::JSON::JSONValue* value : *validParts->asArray())
  133. {
  134. BlockType* blockType
  135. = typeRegistry->fromJson<BlockType>(value);
  136. if (blockType)
  137. {
  138. blockTypeArray.add(blockType);
  139. }
  140. }
  141. validParts->release();
  142. }
  143. });
  144. validator->release();
  145. Framework::Logging::info() << "Loaded " << blockTypeArray.getEintragAnzahl()
  146. << " block types from data/blocks";
  147. blockTypes = new BlockType*[2 + blockTypeArray.getEintragAnzahl()];
  148. blockTypes[0] = new NoBlockBlockType(
  149. dynamic_cast<Block*>(NoBlock::INSTANCE.getThis()),
  150. "__not_yet_generated");
  151. blockTypes[1] = new NoBlockBlockType(
  152. dynamic_cast<Block*>(AirBlock::INSTANCE.getThis()), "Air");
  153. blockTypeCount = 2;
  154. for (BlockType* blockType : blockTypeArray)
  155. {
  156. blockTypes[blockTypeCount++] = blockType;
  157. }
  158. Framework::RCArray<Framework::Text>* blockTypeNames
  159. = new Framework::RCArray<Framework::Text>();
  160. for (int i = 0; i < blockTypeCount; i++)
  161. {
  162. blockTypeNames->add(new Framework::Text(blockTypes[i]->getName()));
  163. blockTypes[i]->setTypeId(i);
  164. }
  165. blockTypeNameFactory->setBlockTypeNames(blockTypeNames);
  166. Framework::Logging::info() << "Loading item types";
  167. Framework::Array<ItemType*> itemTypeArray;
  168. validator
  169. = Framework::Validator::DataValidator::buildForArray()
  170. ->addAcceptedTypeInArray(typeRegistry->getValidator<ItemType>())
  171. ->removeInvalidEntries()
  172. ->finishArray();
  173. loadAllJsonsFromDirectory("data/items",
  174. [this, &itemTypeArray, validator](
  175. Framework::JSON::JSONValue* zValue, Framework::Text path) {
  176. Framework::RCArray<Framework::Validator::ValidationResult>
  177. validationResults;
  178. Framework::JSON::JSONValue* validParts
  179. = validator->getValidParts(zValue, &validationResults);
  180. for (Framework::Validator::ValidationResult* result :
  181. validationResults)
  182. {
  183. Framework::Logging::error() << result->getInvalidInfo();
  184. }
  185. if (validParts)
  186. {
  187. for (Framework::JSON::JSONValue* value : *validParts->asArray())
  188. {
  189. ItemType* itemType
  190. = typeRegistry->fromJson<ItemType>(value);
  191. if (itemType)
  192. {
  193. itemTypeArray.add(itemType);
  194. }
  195. }
  196. validParts->release();
  197. }
  198. });
  199. validator->release();
  200. Framework::Logging::info() << "Loaded " << itemTypeArray.getEintragAnzahl()
  201. << " item types from data/items";
  202. itemTypes
  203. = new ItemType*[blockTypeCount + itemTypeArray.getEintragAnzahl()];
  204. itemTypes[0] = new PlayerHandItemType();
  205. itemTypeCount = 1;
  206. for (int i = 0; i < blockTypeCount; i++)
  207. {
  208. ItemType* itemType = blockTypes[i]->createItemType();
  209. if (itemType)
  210. {
  211. itemTypes[itemTypeCount++] = itemType;
  212. }
  213. }
  214. for (ItemType* itemType : itemTypeArray)
  215. {
  216. itemTypes[itemTypeCount++] = itemType;
  217. }
  218. Framework::RCArray<Framework::Text>* itemTypeNames
  219. = new Framework::RCArray<Framework::Text>();
  220. for (int i = 0; i < itemTypeCount; i++)
  221. {
  222. itemTypes[i]->setTypeId(i);
  223. itemTypeNames->add(new Framework::Text(itemTypes[i]->getName()));
  224. }
  225. itemTypeNameFactory->setItemTypeNames(itemTypeNames);
  226. Framework::Logging::info() << "Loading entity types";
  227. Framework::Array<EntityType*> entityTypeArray;
  228. validator
  229. = Framework::Validator::DataValidator::buildForArray()
  230. ->addAcceptedTypeInArray(typeRegistry->getValidator<EntityType>())
  231. ->removeInvalidEntries()
  232. ->finishArray();
  233. loadAllJsonsFromDirectory("data/entities",
  234. [this, &entityTypeArray, validator](
  235. Framework::JSON::JSONValue* zValue, Framework::Text path) {
  236. Framework::RCArray<Framework::Validator::ValidationResult>
  237. validationResults;
  238. Framework::JSON::JSONValue* validParts
  239. = validator->getValidParts(zValue, &validationResults);
  240. for (Framework::Validator::ValidationResult* result :
  241. validationResults)
  242. {
  243. Framework::Logging::error() << result->getInvalidInfo();
  244. }
  245. if (validParts)
  246. {
  247. for (Framework::JSON::JSONValue* value : *validParts->asArray())
  248. {
  249. EntityType* entityType
  250. = typeRegistry->fromJson<EntityType>(value);
  251. if (entityType)
  252. {
  253. entityTypeArray.add(entityType);
  254. }
  255. }
  256. validParts->release();
  257. }
  258. });
  259. validator->release();
  260. Framework::Logging::info()
  261. << "Loaded " << entityTypeArray.getEintragAnzahl()
  262. << " entity types from data/entities";
  263. entityTypes = new EntityType*[2 + entityTypeArray.getEintragAnzahl()];
  264. entityTypes[0] = new PlayerEntityType();
  265. entityTypes[1] = new ItemEntityType();
  266. entityTypeCount = 2;
  267. for (EntityType* entityType : entityTypeArray)
  268. {
  269. entityTypes[entityTypeCount++] = entityType;
  270. }
  271. for (int i = 0; i < entityTypeCount; i++)
  272. {
  273. entityTypes[i]->setTypeId(i);
  274. }
  275. // initialize loaded types
  276. bool allInitialized = false;
  277. while (!allInitialized)
  278. {
  279. allInitialized = true;
  280. for (int i = 0; i < blockTypeCount; i++)
  281. {
  282. if (blockTypes[i] && !blockTypes[i]->initialize(this))
  283. {
  284. Framework::Logging::error()
  285. << "Could not initialize Block Type '"
  286. << blockTypes[i]->getName() << "'.";
  287. blockTypes[i]->release();
  288. blockTypes[i] = 0;
  289. allInitialized = false;
  290. }
  291. }
  292. }
  293. allInitialized = false;
  294. while (!allInitialized)
  295. {
  296. allInitialized = true;
  297. for (int i = 0; i < itemTypeCount; i++)
  298. {
  299. if (itemTypes[i] && !itemTypes[i]->initialize(this))
  300. {
  301. Framework::Logging::error()
  302. << "Could not initialize Item Type '"
  303. << itemTypes[i]->getName() << "'.";
  304. itemTypes[i]->release();
  305. itemTypes[i] = 0;
  306. allInitialized = false;
  307. }
  308. }
  309. }
  310. allInitialized = false;
  311. while (!allInitialized)
  312. {
  313. allInitialized = true;
  314. for (int i = 0; i < entityTypeCount; i++)
  315. {
  316. if (entityTypes[i] && !entityTypes[i]->initialize(this))
  317. {
  318. Framework::Logging::error()
  319. << "Could not initialize Entity Type '"
  320. << entityTypes[i]->getName() << "'.";
  321. entityTypes[i]->release();
  322. entityTypes[i] = 0;
  323. allInitialized = false;
  324. }
  325. }
  326. }
  327. for (int i = 0; i < blockTypeCount; i++)
  328. {
  329. if (blockTypes[i])
  330. {
  331. blockTypes[i]->initializeDefault();
  332. }
  333. }
  334. multiblockStructureTypes = new MultiblockStructureType*[1];
  335. multiblockStructureTypes[0] = new MultiblockTreeStructureType();
  336. multiblockStructureTypeCount = 1;
  337. // save syntax info
  338. Framework::DateiRemove("data/syntax");
  339. // typeRegistry->writeSyntaxInfo("data/syntax");
  340. validator
  341. = Framework::Validator::DataValidator::buildForArray()
  342. ->addAcceptedTypeInArray(typeRegistry->getValidator<BlockType>())
  343. ->finishArray();
  344. Framework::JSON::JSONObject* schema = validator->getJsonSchema();
  345. Framework::Datei syntaxFile;
  346. syntaxFile.setDatei("data/syntax/schema/blocks.json");
  347. syntaxFile.erstellen();
  348. syntaxFile.open(Framework::Datei::Style::schreiben);
  349. syntaxFile.schreibe(schema->toString(), schema->toString().getLength());
  350. syntaxFile.close();
  351. schema->release();
  352. validator->release();
  353. validator
  354. = Framework::Validator::DataValidator::buildForArray()
  355. ->addAcceptedTypeInArray(typeRegistry->getValidator<ItemType>())
  356. ->finishArray();
  357. schema = validator->getJsonSchema();
  358. syntaxFile.setDatei("data/syntax/schema/items.json");
  359. syntaxFile.erstellen();
  360. syntaxFile.open(Framework::Datei::Style::schreiben);
  361. syntaxFile.schreibe(schema->toString(), schema->toString().getLength());
  362. syntaxFile.close();
  363. schema->release();
  364. validator->release();
  365. validator
  366. = Framework::Validator::DataValidator::buildForArray()
  367. ->addAcceptedTypeInArray(typeRegistry->getValidator<EntityType>())
  368. ->finishArray();
  369. schema = validator->getJsonSchema();
  370. syntaxFile.setDatei("data/syntax/schema/entities.json");
  371. syntaxFile.erstellen();
  372. syntaxFile.open(Framework::Datei::Style::schreiben);
  373. syntaxFile.schreibe(schema->toString(), schema->toString().getLength());
  374. syntaxFile.close();
  375. schema->release();
  376. validator->release();
  377. // initialize world generator and world loader
  378. int seed = 0;
  379. int index = 0;
  380. for (const char* n = name; *n; n++)
  381. seed += (int)pow((float)*n * 31, (float)++index);
  382. generator = new WorldGenerator(seed);
  383. loader = new WorldLoader();
  384. // load recipies
  385. recipies->loadRecipies("data");
  386. // initialize chat
  387. chat = new Chat();
  388. // load quests
  389. questManager->loadQuests();
  390. }
  391. void Game::thread()
  392. {
  393. ZeitMesser waitForLock;
  394. ZeitMesser removeOldClients;
  395. ZeitMesser clientReply;
  396. ZeitMesser removeOldChunks;
  397. ZeitMesser m;
  398. ZeitMesser total;
  399. total.messungStart();
  400. double tickTime = 0;
  401. double sleepTime = 0;
  402. int nextTimeSync = MAX_TICKS_PER_SECOND;
  403. int ticktToNextUpdate = MAX_TICKS_PER_SECOND * 5;
  404. while (!stop)
  405. {
  406. ticktToNextUpdate--;
  407. if (ticktToNextUpdate <= 0)
  408. {
  409. questManager->processEvent(new QuestEventTimeUpdate());
  410. ticktToNextUpdate = MAX_TICKS_PER_SECOND * 5;
  411. }
  412. m.messungStart();
  413. ticker->nextTick();
  414. actionsCs.lock();
  415. while (actions.getEintragAnzahl() > 0)
  416. {
  417. actions.get(0)();
  418. actions.remove(0);
  419. }
  420. actionsCs.unlock();
  421. Array<int> removed;
  422. double waitTotal = 0;
  423. waitForLock.messungStart();
  424. cs.lock();
  425. waitForLock.messungEnde();
  426. waitTotal += waitForLock.getSekunden();
  427. removeOldClients.messungStart();
  428. int index = 0;
  429. nextTimeSync--;
  430. for (auto player : *clients)
  431. {
  432. if (!player->isOnline())
  433. {
  434. uiController->removePlayerDialogs(player->zEntity()->getId());
  435. chat->removeObserver(player->zEntity()->getId());
  436. chat->broadcastMessage(
  437. Framework::Text(player->zEntity()->getName())
  438. + " left the game.",
  439. Chat::CHANNEL_INFO);
  440. Datei pFile;
  441. pFile.setDatei(path + "/player/"
  442. + getPlayerId(player->zEntity()->getName()));
  443. pFile.erstellen();
  444. if (pFile.open(Datei::Style::schreiben))
  445. {
  446. zEntityType(EntityTypeEnum::PLAYER)
  447. ->saveEntity(player->zEntity(), &pFile);
  448. }
  449. pFile.close();
  450. Dimension* dim
  451. = zDimension(player->zEntity()->getDimensionId());
  452. Chunk* chunk = dim->zChunk(
  453. getChunkCenter((int)player->zEntity()->getLocation().x,
  454. (int)player->zEntity()->getLocation().y));
  455. if (chunk)
  456. {
  457. chunk->onEntityLeaves(player->zEntity(), 0);
  458. }
  459. dim->removeEntity(player->zEntity()->getId());
  460. removed.add(index, 0);
  461. dim->removeSubscriptions(player->zEntity());
  462. }
  463. else
  464. {
  465. if (nextTimeSync <= 0 && player->zEntity())
  466. {
  467. Dimension* zDim
  468. = zDimension(player->zEntity()->getDimensionId());
  469. if (zDim)
  470. {
  471. NetworkMessage* msg = new NetworkMessage();
  472. msg->syncTime(zDim->getCurrentDayTime(),
  473. zDim->getNightDuration(),
  474. zDim->getNightTransitionDuration(),
  475. zDim->getDayDuration());
  476. player->sendResponse(msg);
  477. }
  478. }
  479. }
  480. index++;
  481. }
  482. if (nextTimeSync <= 0)
  483. {
  484. consoleHandler->print();
  485. nextTimeSync = MAX_TICKS_PER_SECOND;
  486. }
  487. for (auto i : removed)
  488. clients->remove(i);
  489. removeOldClients.messungEnde();
  490. for (Dimension* dim : *dimensions)
  491. {
  492. dim->tick();
  493. }
  494. cs.unlock();
  495. clientReply.messungStart();
  496. for (auto client : *clients)
  497. client->reply();
  498. clientReply.messungEnde();
  499. waitForLock.messungStart();
  500. cs.lock();
  501. waitForLock.messungEnde();
  502. waitTotal += waitForLock.getSekunden();
  503. removeOldChunks.messungStart();
  504. for (auto dim : *dimensions)
  505. dim->removeOldChunks();
  506. removeOldChunks.messungEnde();
  507. cs.unlock();
  508. m.messungEnde();
  509. double sec = m.getSekunden();
  510. tickCounter++;
  511. totalTickTime += sec;
  512. sleepTime += 1.0 / MAX_TICKS_PER_SECOND - tickTime;
  513. if (sleepTime > 0)
  514. {
  515. Sleep((int)(sleepTime * 1000));
  516. }
  517. total.messungEnde();
  518. total.messungStart();
  519. tickTime = total.getSekunden();
  520. totalTime += tickTime;
  521. if (totalTime >= 1)
  522. {
  523. averageTickTime = totalTickTime / tickCounter;
  524. ticksPerSecond = tickCounter;
  525. totalTickTime = 0;
  526. tickCounter = 0;
  527. totalTime = 0;
  528. }
  529. else if (sec > 1)
  530. {
  531. Framework::Logging::warning()
  532. << "tick needed " << sec
  533. << " seconds. The game will run sower then normal.\n";
  534. Framework::Logging::trace()
  535. << "waiting: " << waitTotal
  536. << "\nremoveOldClients: " << removeOldClients.getSekunden()
  537. << "\nclientReply: " << clientReply.getSekunden()
  538. << "\nremoveOldChunks:" << removeOldChunks.getSekunden();
  539. }
  540. }
  541. save();
  542. generator->exitAndWait();
  543. loader->exitAndWait();
  544. ticker->exitAndWait();
  545. for (Dimension* dim : *dimensions)
  546. dim->requestStopAndWait();
  547. Framework::Logging::info() << "Game thread exited";
  548. }
  549. void Game::api(Framework::InMemoryBuffer* zRequest, GameClient* zOrigin)
  550. {
  551. char type;
  552. zRequest->lese(&type, 1);
  553. NetworkMessage* response = new NetworkMessage();
  554. switch (type)
  555. {
  556. case 1: // world
  557. {
  558. Dimension* dim = zDimension(zOrigin->zEntity()->getDimensionId());
  559. if (!dim)
  560. {
  561. dim = generator->createDimension(
  562. zOrigin->zEntity()->getDimensionId());
  563. if (!dim)
  564. {
  565. Framework::Logging::error()
  566. << "could not create dimension "
  567. << zOrigin->zEntity()->getDimensionId()
  568. << ". No Factory was provided.";
  569. return;
  570. }
  571. addDimension(dim);
  572. }
  573. dim->api(zRequest, response, zOrigin->zEntity());
  574. break;
  575. }
  576. case 2: // player
  577. zOrigin->zEntity()->playerApi(zRequest, response);
  578. break;
  579. case 3: // entity
  580. {
  581. int id;
  582. zRequest->lese((char*)&id, 4);
  583. for (Dimension* dim : *dimensions)
  584. {
  585. Entity* entity = dim->zEntity(id);
  586. if (entity)
  587. {
  588. entity->api(zRequest, response, zOrigin->zEntity());
  589. break;
  590. }
  591. }
  592. break;
  593. }
  594. case 4:
  595. { // inventory
  596. bool isEntity;
  597. zRequest->lese((char*)&isEntity, 1);
  598. Inventory* target;
  599. if (isEntity)
  600. {
  601. int id;
  602. zRequest->lese((char*)&id, 4);
  603. target = zEntity(id);
  604. }
  605. else
  606. {
  607. int dim;
  608. Vec3<int> pos;
  609. zRequest->lese((char*)&dim, 4);
  610. zRequest->lese((char*)&pos.x, 4);
  611. zRequest->lese((char*)&pos.y, 4);
  612. zRequest->lese((char*)&pos.z, 4);
  613. target = zBlockAt(pos, dim, 0);
  614. }
  615. if (target)
  616. target->inventoryApi(zRequest, response, zOrigin->zEntity());
  617. break;
  618. }
  619. case 5:
  620. { // crafting uiml request
  621. int id;
  622. zRequest->lese((char*)&id, 4);
  623. Text uiml = recipies->getCrafingUIML(id);
  624. Text dialogId = "crafting_";
  625. dialogId += id;
  626. uiController->addDialog(new UIDialog(dialogId,
  627. zOrigin->zEntity()->getId(),
  628. new Framework::XML::Element(uiml)));
  629. break;
  630. }
  631. case 6:
  632. { // chat message
  633. chat->chatApi(zRequest, zOrigin->zEntity(), response);
  634. break;
  635. }
  636. case 7: // other dimension
  637. {
  638. int dimensionId;
  639. zRequest->lese((char*)&dimensionId, 4);
  640. Dimension* dim = zDimension(dimensionId);
  641. if (dim)
  642. {
  643. dim->api(zRequest, response, zOrigin->zEntity());
  644. }
  645. break;
  646. }
  647. case 8: // ui message
  648. {
  649. uiController->api(zRequest, response, zOrigin->zEntity());
  650. break;
  651. }
  652. default:
  653. Framework::Logging::warning()
  654. << "received unknown api request in game with type " << (int)type;
  655. }
  656. if (!response->isEmpty())
  657. {
  658. if (response->isBroadcast())
  659. broadcastMessage(response);
  660. else
  661. zOrigin->sendResponse(response);
  662. }
  663. else
  664. {
  665. response->release();
  666. }
  667. }
  668. void Game::updateLightning(int dimensionId, Vec3<int> location)
  669. {
  670. Dimension* zDim = zDimension(dimensionId);
  671. if (zDim) zDim->updateLightning(location);
  672. }
  673. void Game::updateLightningWithoutWait(int dimensionId, Vec3<int> location)
  674. {
  675. Dimension* zDim = zDimension(dimensionId);
  676. if (zDim) zDim->updateLightningWithoutWait(location);
  677. }
  678. void Game::broadcastMessage(NetworkMessage* response)
  679. {
  680. for (auto client : *clients)
  681. client->sendResponse(
  682. dynamic_cast<NetworkMessage*>(response->getThis()));
  683. response->release();
  684. }
  685. void Game::sendMessage(NetworkMessage* response, Entity* zTargetPlayer)
  686. {
  687. for (auto client : *clients)
  688. {
  689. if (client->zEntity()->getId() == zTargetPlayer->getId())
  690. {
  691. client->sendResponse(response);
  692. return;
  693. }
  694. }
  695. response->release();
  696. }
  697. bool Game::checkPlayer(Framework::Text name, Framework::Text secret)
  698. {
  699. if (playerRegister->checkSecret(name, secret))
  700. return 1;
  701. else
  702. {
  703. Framework::Logging::warning()
  704. << "player " << name.getText()
  705. << " tryed to connect with an invalid secret.";
  706. return 0;
  707. }
  708. }
  709. bool Game::existsPlayer(Framework::Text name)
  710. {
  711. return playerRegister->hasPlayer(name);
  712. }
  713. Framework::Text Game::createPlayer(Framework::Text name)
  714. {
  715. return playerRegister->addPlayer(name);
  716. }
  717. GameClient* Game::addPlayer(FCKlient* client, Framework::Text name)
  718. {
  719. cs.lock();
  720. int id = playerRegister->getPlayerId(name);
  721. Datei pFile;
  722. pFile.setDatei(path + "/player/" + id);
  723. Player* player;
  724. bool isNew = 0;
  725. if (!pFile.existiert() || !pFile.open(Datei::Style::lesen))
  726. {
  727. player = (Player*)zEntityType(EntityTypeEnum::PLAYER)
  728. ->createEntityAt(
  729. Vec3<float>(0.5, 0.5, 0), DimensionEnum::OVERWORLD);
  730. player->setName(name);
  731. isNew = 1;
  732. }
  733. else
  734. {
  735. player
  736. = (Player*)zEntityType(EntityTypeEnum::PLAYER)->loadEntity(&pFile);
  737. pFile.close();
  738. }
  739. if (player->getId() >= nextEntityId)
  740. {
  741. nextEntityId = player->getId() + 1;
  742. }
  743. GameClient* gameClient = new GameClient(player, client);
  744. gameClient->sendTypes();
  745. clients->add(gameClient);
  746. if (!zDimension(player->getDimensionId()))
  747. {
  748. Dimension* dim = generator->createDimension(player->getDimensionId());
  749. if (!dim)
  750. {
  751. Framework::Logging::error() << "could not create dimension "
  752. << (int)player->getDimensionId()
  753. << ". No Factory was provided.";
  754. return 0;
  755. }
  756. NetworkMessage* msg = new NetworkMessage();
  757. msg->syncTime(dim->getCurrentDayTime(),
  758. dim->getNightDuration(),
  759. dim->getNightTransitionDuration(),
  760. dim->getDayDuration());
  761. gameClient->sendResponse(msg);
  762. this->addDimension(dim);
  763. }
  764. // subscribe the new player as an observer of the new chunk
  765. Dimension* dim = zDimension(player->getDimensionId());
  766. InMemoryBuffer* buffer = new InMemoryBuffer();
  767. buffer->schreibe("\0", 1);
  768. Punkt center = getChunkCenter(
  769. (int)player->getPosition().x, (int)player->getPosition().y);
  770. buffer->schreibe((char*)&center.x, 4);
  771. buffer->schreibe((char*)&center.y, 4);
  772. buffer->schreibe("\0", 1);
  773. dim->api(buffer, 0, player);
  774. buffer->release();
  775. while (!dim->zChunk(getChunkCenter(
  776. (int)player->getPosition().x, (int)player->getPosition().y)))
  777. {
  778. cs.unlock();
  779. Sleep(1000);
  780. cs.lock();
  781. }
  782. if (isNew)
  783. {
  784. Either<Block*, int> b = BlockTypeEnum::AIR;
  785. int h = WORLD_HEIGHT;
  786. while (((b.isA() && (!(Block*)b || ((Block*)b)->isPassable()))
  787. || (b.isB() && zBlockType(b)->zDefault()->isPassable()))
  788. && h > 0)
  789. b = zBlockAt({(int)player->getPosition().x,
  790. (int)player->getPosition().y,
  791. --h},
  792. player->getDimensionId(),
  793. 0);
  794. player->setPosition(
  795. {player->getPosition().x, player->getPosition().y, (float)h + 2.f});
  796. }
  797. dim->addEntity(player);
  798. chat->addObserver(gameClient->zEntity()->getId());
  799. chat->broadcastMessage(name + " joined the game.", Chat::CHANNEL_INFO);
  800. cs.unlock();
  801. return dynamic_cast<GameClient*>(gameClient->getThis());
  802. }
  803. bool Game::isChunkLoaded(int x, int y, int dimension) const
  804. {
  805. Dimension* dim = zDimension(dimension);
  806. return (dim && dim->hasChunck(x, y));
  807. }
  808. bool Game::doesChunkExist(int x, int y, int dimension)
  809. {
  810. cs.lock();
  811. bool result = isChunkLoaded(x, y, dimension)
  812. || loader->existsChunk(x, y, dimension);
  813. cs.unlock();
  814. return result;
  815. }
  816. void Game::blockTargetChanged(Block* zBlock)
  817. {
  818. for (GameClient* client : *this->clients)
  819. {
  820. if (client->zEntity()->zTarget()
  821. && client->zEntity()->zTarget()->isBlock(
  822. zBlock->getPos(), NO_DIRECTION))
  823. {
  824. client->zEntity()->onTargetChange();
  825. }
  826. }
  827. }
  828. void Game::entityTargetChanged(Entity* zEntity)
  829. {
  830. for (GameClient* client : *this->clients)
  831. {
  832. if (client->zEntity()->zTarget()
  833. && client->zEntity()->zTarget()->isEntity(zEntity->getId()))
  834. {
  835. client->zEntity()->onTargetChange();
  836. }
  837. }
  838. }
  839. void Game::spawnItem(
  840. Framework::Vec3<float> location, int dimensionId, Item* stack)
  841. {
  842. spawnItem(location, dimensionId, new ItemStack(stack, 1));
  843. }
  844. void Game::spawnItem(
  845. Framework::Vec3<float> location, int dimensionId, ItemStack* stack)
  846. {
  847. if (stack->getSize() == 0)
  848. {
  849. Logging::error() << "spawn item was called with empty stack";
  850. return;
  851. }
  852. ItemEntity* itemEntity = (ItemEntity*)zEntityType(EntityTypeEnum::ITEM)
  853. ->createEntityAt(location, dimensionId);
  854. itemEntity->unsaveAddItem(stack, NO_DIRECTION, 0);
  855. if (stack->getSize() > 0)
  856. {
  857. Logging::error() << "could not add item to item entity";
  858. }
  859. stack->release();
  860. Dimension* dim = zDimension(dimensionId);
  861. if (dim)
  862. {
  863. dim->addEntity(itemEntity);
  864. dim->zChunk(Game::getChunkCenter((int)itemEntity->getLocation().x,
  865. (int)itemEntity->getLocation().y))
  866. ->onEntityEnters(itemEntity, 0);
  867. }
  868. else
  869. {
  870. Framework::Logging::error()
  871. << "could not spawn item entity in dimension " << dimensionId
  872. << ". Dimension not loaded.";
  873. itemEntity->release();
  874. return;
  875. }
  876. }
  877. Framework::Either<Block*, int> Game::zBlockAt(
  878. Framework::Vec3<int> location, int dimension, OUT Chunk** zChunk) const
  879. {
  880. Dimension* dim = zDimension(dimension);
  881. if (dim) return dim->zBlock(location, zChunk);
  882. return 0;
  883. }
  884. Block* Game::zRealBlockInstance(
  885. Framework::Vec3<int> location, int dimension) const
  886. {
  887. Dimension* dim = zDimension(dimension);
  888. if (dim) return dim->zRealBlockInstance(location);
  889. return 0;
  890. }
  891. const Block* Game::zConstBlock(
  892. Framework::Vec3<int> location, int dimension) const
  893. {
  894. Dimension* dim = zDimension(dimension);
  895. if (dim) return dim->zBlockOrDefault(location);
  896. return 0;
  897. }
  898. int Game::getBlockType(Framework::Vec3<int> location, int dimension) const
  899. {
  900. Dimension* dim = zDimension(dimension);
  901. if (dim) return dim->getBlockType(location);
  902. return 0;
  903. }
  904. Dimension* Game::zDimension(int id) const
  905. {
  906. for (auto dim : *dimensions)
  907. {
  908. if (dim->getDimensionId() == id) return dim;
  909. }
  910. return 0;
  911. }
  912. Framework::Punkt Game::getChunkCenter(int x, int y)
  913. {
  914. return Punkt(((x < 0 ? x + 1 : x) / CHUNK_SIZE) * CHUNK_SIZE
  915. + (x < 0 ? -CHUNK_SIZE : CHUNK_SIZE) / 2,
  916. ((y < 0 ? y + 1 : y) / CHUNK_SIZE) * CHUNK_SIZE
  917. + (y < 0 ? -CHUNK_SIZE : CHUNK_SIZE) / 2);
  918. }
  919. Area Game::getChunckArea(Punkt center) const
  920. {
  921. return {center.x - CHUNK_SIZE / 2,
  922. center.y - CHUNK_SIZE / 2,
  923. center.x + CHUNK_SIZE / 2 - 1,
  924. center.y + CHUNK_SIZE / 2 - 1,
  925. 0};
  926. }
  927. Framework::Text Game::getWorldDirectory() const
  928. {
  929. return path;
  930. }
  931. void Game::requestArea(Area area)
  932. {
  933. generator->requestGeneration(area);
  934. loader->requestLoading(area);
  935. }
  936. void Game::save() const
  937. {
  938. questManager->saveQuests();
  939. Datei d;
  940. d.setDatei(path + "/eid");
  941. d.open(Datei::Style::schreiben);
  942. d.schreibe((char*)&nextEntityId, 4);
  943. d.close();
  944. playerRegister->save();
  945. for (auto dim : *dimensions)
  946. dim->save(path);
  947. chat->save();
  948. Framework::Logging::info() << "Game was saved";
  949. }
  950. void Game::requestStop()
  951. {
  952. stop = 1;
  953. warteAufThread(1000000);
  954. }
  955. void Game::addDimension(Dimension* d)
  956. {
  957. dimensions->add(d);
  958. }
  959. int Game::getNextEntityId()
  960. {
  961. neidl.lock();
  962. int result = nextEntityId++;
  963. neidl.unlock();
  964. return result;
  965. }
  966. WorldGenerator* Game::zGenerator() const
  967. {
  968. return generator;
  969. }
  970. Game* Game::INSTANCE = 0;
  971. void Game::initialize(Framework::Text name, Framework::Text worldsDir)
  972. {
  973. if (!Game::INSTANCE)
  974. {
  975. Game::INSTANCE = new Game(name, worldsDir);
  976. Game::INSTANCE->initialize();
  977. }
  978. }
  979. Entity* Game::zEntity(int id, int dimensionId) const
  980. {
  981. Dimension* d = zDimension(dimensionId);
  982. if (d) return d->zEntity(id);
  983. return 0;
  984. }
  985. Entity* Game::zEntity(int id) const
  986. {
  987. for (Dimension* d : *dimensions)
  988. {
  989. Entity* e = d->zEntity(id);
  990. if (e) return e;
  991. }
  992. // for new players that are currently loading
  993. for (GameClient* client : *clients)
  994. {
  995. if (client->zEntity()->getId() == id)
  996. {
  997. return client->zEntity();
  998. }
  999. }
  1000. return 0;
  1001. }
  1002. Entity* Game::zNearestEntity(int dimensionId,
  1003. Framework::Vec3<float> pos,
  1004. std::function<bool(Entity*)> filter) const
  1005. {
  1006. Dimension* d = zDimension(dimensionId);
  1007. if (!d) return 0;
  1008. return d->zNearestEntity(pos, filter);
  1009. }
  1010. RecipieLoader* Game::zRecipies() const
  1011. {
  1012. return recipies;
  1013. }
  1014. void Game::doLater(std::function<void()> action)
  1015. {
  1016. actionsCs.lock();
  1017. actions.add(action);
  1018. actionsCs.unlock();
  1019. }
  1020. TickOrganizer* Game::zTickOrganizer() const
  1021. {
  1022. return ticker;
  1023. }
  1024. Chat* Game::zChat() const
  1025. {
  1026. return chat;
  1027. }
  1028. Player* Game::zPlayerByName(const char* name) const
  1029. {
  1030. for (GameClient* client : *clients)
  1031. {
  1032. if (strcmp(client->zEntity()->getName(), name) == 0)
  1033. {
  1034. return client->zEntity();
  1035. }
  1036. }
  1037. return 0;
  1038. }
  1039. void Game::listPlayerNames(Framework::RCArray<Framework::Text>& names)
  1040. {
  1041. for (GameClient* client : *clients)
  1042. {
  1043. names.add(new Framework::Text(client->zEntity()->getName()));
  1044. }
  1045. }
  1046. TypeRegistry* Game::zTypeRegistry() const
  1047. {
  1048. return typeRegistry;
  1049. }
  1050. int Game::getPlayerId(const char* name) const
  1051. {
  1052. return playerRegister->getPlayerId(name);
  1053. }
  1054. QuestManager* Game::zQuestManager() const
  1055. {
  1056. return questManager;
  1057. }
  1058. UIController* Game::zUIController() const
  1059. {
  1060. return uiController;
  1061. }
  1062. double Game::getAverageTickTime() const
  1063. {
  1064. return averageTickTime;
  1065. }
  1066. int Game::getTicksPerSecond() const
  1067. {
  1068. return ticksPerSecond;
  1069. }
  1070. int Game::getPlayerCount() const
  1071. {
  1072. return clients->getEintragAnzahl();
  1073. }
  1074. int Game::getChunkCount() const
  1075. {
  1076. int result = 0;
  1077. for (Dimension* dim : *dimensions)
  1078. {
  1079. result += dim->getChunkCount();
  1080. }
  1081. return result;
  1082. }
  1083. const BlockType* Game::zBlockType(int id) const
  1084. {
  1085. return blockTypes[id];
  1086. }
  1087. const ItemType* Game::zItemType(int id) const
  1088. {
  1089. return itemTypes[id];
  1090. }
  1091. const EntityType* Game::zEntityType(int id) const
  1092. {
  1093. return entityTypes[id];
  1094. }
  1095. int Game::getEntityTypeId(const char* name) const
  1096. {
  1097. for (int i = 0; i < entityTypeCount; i++)
  1098. {
  1099. if (entityTypes[i]
  1100. && Framework::Text(entityTypes[i]->getName()).istGleich(name))
  1101. {
  1102. return i;
  1103. }
  1104. }
  1105. Framework::Logging::warning()
  1106. << "no entity type with name '" << name << "' found.";
  1107. return -1;
  1108. }
  1109. int Game::getBlockTypeId(const char* name) const
  1110. {
  1111. for (int i = 0; i < blockTypeCount; i++)
  1112. {
  1113. if (blockTypes[i]
  1114. && Framework::Text(blockTypes[i]->getName()).istGleich(name))
  1115. {
  1116. return i;
  1117. }
  1118. }
  1119. Framework::Logging::warning()
  1120. << "no block type with name '" << name << "' found.";
  1121. return -1;
  1122. }
  1123. int Game::getItemTypeId(const char* name) const
  1124. {
  1125. for (int i = 0; i < itemTypeCount; i++)
  1126. {
  1127. if (itemTypes[i]
  1128. && Framework::Text(itemTypes[i]->getName()).istGleich(name))
  1129. {
  1130. return i;
  1131. }
  1132. }
  1133. Framework::Logging::warning()
  1134. << "no item type with name '" << name << "' found.";
  1135. return -1;
  1136. }
  1137. int Game::getBlockTypeCount() const
  1138. {
  1139. return blockTypeCount;
  1140. }
  1141. int Game::getItemTypeCount() const
  1142. {
  1143. return itemTypeCount;
  1144. }
  1145. int Game::getEntityTypeCount() const
  1146. {
  1147. return entityTypeCount;
  1148. }
  1149. const MultiblockStructureType* Game::zMultiblockStructureType(int id) const
  1150. {
  1151. return multiblockStructureTypes[id];
  1152. }
  1153. int Game::getMultiblockStructureTypeCount() const
  1154. {
  1155. return multiblockStructureTypeCount;
  1156. }