Game.cpp 42 KB

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