Game.cpp 35 KB

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