Game.cpp 33 KB

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