| 2198 | } |
| 2199 | |
| 2200 | Maybe<WorkerPoolPromise<WorldServerThreadPtr>> UniverseServer::instanceWorldPromise(InstanceWorldId const& instanceWorldId) { |
| 2201 | auto storageDirectory = m_storageDirectory; |
| 2202 | auto universeClock = m_universeClock; |
| 2203 | return m_workerPool.addProducer<WorldServerThreadPtr>([this, storageDirectory, instanceWorldId, universeClock]() { |
| 2204 | Json worldConfig = Root::singleton().assets()->json("/instance_worlds.config").get(instanceWorldId.instance); |
| 2205 | uint64_t worldSeed; |
| 2206 | if (worldConfig.contains("seed")) |
| 2207 | worldSeed = worldConfig.getUInt("seed"); |
| 2208 | else |
| 2209 | worldSeed = Random::randu64(); |
| 2210 | |
| 2211 | String worldType = worldConfig.getString("type"); |
| 2212 | |
| 2213 | VisitableWorldParametersPtr worldParameters; |
| 2214 | if (worldType.equalsIgnoreCase("Terrestrial")) |
| 2215 | worldParameters = generateTerrestrialWorldParameters(worldConfig.getString("planetType"), worldConfig.getString("planetSize"), worldSeed); |
| 2216 | else if (worldType.equalsIgnoreCase("Asteroids")) |
| 2217 | worldParameters = generateAsteroidsWorldParameters(worldSeed); |
| 2218 | else if (worldType.equalsIgnoreCase("FloatingDungeon")) |
| 2219 | worldParameters = generateFloatingDungeonWorldParameters(worldConfig.getString("dungeonWorld")); |
| 2220 | else |
| 2221 | throw UniverseServerException(strf("Unknown world type: '{}'\n", worldType)); |
| 2222 | |
| 2223 | if (instanceWorldId.level) |
| 2224 | worldParameters->threatLevel = *instanceWorldId.level; |
| 2225 | |
| 2226 | if (worldConfig.contains("beamUpRule")) |
| 2227 | worldParameters->beamUpRule = BeamUpRuleNames.getLeft(worldConfig.getString("beamUpRule")); |
| 2228 | worldParameters->disableDeathDrops = worldConfig.getBool("disableDeathDrops", false); |
| 2229 | |
| 2230 | SkyParameters skyParameters = SkyParameters(worldConfig.get("skyParameters", Json())); |
| 2231 | auto worldTemplate = make_shared<WorldTemplate>(worldParameters, skyParameters, worldSeed); |
| 2232 | Json worldProperties = worldConfig.get("worldProperties", JsonObject{}); |
| 2233 | bool spawningEnabled = worldConfig.getBool("spawningEnabled", true); |
| 2234 | bool persistent = worldConfig.getBool("persistent", false); |
| 2235 | bool useUniverseClock = worldConfig.getBool("useUniverseClock", false); |
| 2236 | |
| 2237 | WorldServerPtr worldServer; |
| 2238 | |
| 2239 | bool worldExisted = false; |
| 2240 | |
| 2241 | if (persistent) { |
| 2242 | String identifier = instanceWorldId.instance; |
| 2243 | if (instanceWorldId.uuid) |
| 2244 | identifier = strf("{}-{}", identifier, instanceWorldId.uuid->hex()); |
| 2245 | if (instanceWorldId.level) |
| 2246 | identifier = strf("{}-{}", identifier, instanceWorldId.level.value()); |
| 2247 | String storageFile = File::relativeTo(storageDirectory, strf("unique-{}.world", identifier)); |
| 2248 | if (File::isFile(storageFile)) { |
| 2249 | try { |
| 2250 | Logger::info("UniverseServer: Loading persistent unique instance world {}", instanceWorldId.instance); |
| 2251 | worldServer = make_shared<WorldServer>(File::open(storageFile, IOMode::ReadWrite)); |
| 2252 | worldExisted = true; |
| 2253 | } catch (std::exception const& e) { |
| 2254 | Logger::error("UniverseServer: Could not load persistent unique instance world {}, removing! Cause: {}", |
| 2255 | instanceWorldId.instance, outputException(e, false)); |
| 2256 | File::rename(storageFile, strf("{}.{}.fail", storageFile, Time::millisecondsSinceEpoch())); |
| 2257 | } |
nothing calls this directly
no test coverage detected