Game.cpp 35 KB

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