- return migrate_database(game_params, cmd_args, &server);
-
- server.start(bind_addr);
-
- // Run server
- bool &kill = *porting::signal_handler_killstatus();
- dedicated_server_loop(server, kill);
-
- return true;
-}
-
-static bool migrate_database(const GameParams &game_params, const Settings &cmd_args,
- Server *server)
-{
- Settings world_mt;
- bool success = world_mt.readConfigFile((game_params.world_path
- + DIR_DELIM + "world.mt").c_str());
- if (!success) {
- errorstream << "Cannot read world.mt" << std::endl;
- return false;
- }
-
- if (!world_mt.exists("backend")) {
- errorstream << "Please specify your current backend in world.mt file:"
- << std::endl << " backend = {sqlite3|leveldb|redis|dummy}"
- << std::endl;
- return false;
- }
-
- std::string backend = world_mt.get("backend");
- Database *new_db;
- std::string migrate_to = cmd_args.get("migrate");
-
- if (backend == migrate_to) {
- errorstream << "Cannot migrate: new backend is same as the old one"
- << std::endl;
- return false;
- }
-
- if (migrate_to == "sqlite3")
- new_db = new Database_SQLite3(&(ServerMap&)server->getMap(),
- game_params.world_path);
-#if USE_LEVELDB
- else if (migrate_to == "leveldb")
- new_db = new Database_LevelDB(&(ServerMap&)server->getMap(),
- game_params.world_path);
-#endif
-#if USE_REDIS
- else if (migrate_to == "redis")
- new_db = new Database_Redis(&(ServerMap&)server->getMap(),
- game_params.world_path);
-#endif
- else {
- errorstream << "Migration to " << migrate_to << " is not supported"
- << std::endl;
- return false;
- }
-
- std::list<v3s16> blocks;
- ServerMap &old_map = ((ServerMap&)server->getMap());
- old_map.listAllLoadableBlocks(blocks);
- int count = 0;
- new_db->beginSave();
- for (std::list<v3s16>::iterator i = blocks.begin(); i != blocks.end(); i++) {
- MapBlock *block = old_map.loadBlock(*i);
- if (!block) {
- errorstream << "Failed to load block " << PP(*i) << ", skipping it.";
- } else {
- old_map.saveBlock(block, new_db);
- MapSector *sector = old_map.getSectorNoGenerate(v2s16(i->X, i->Z));
- sector->deleteBlock(block);
- }
- ++count;
- if (count % 500 == 0)
- actionstream << "Migrated " << count << " blocks "
- << (100.0 * count / blocks.size()) << "% completed" << std::endl;
- }
- new_db->endSave();
- delete new_db;
-
- actionstream << "Successfully migrated " << count << " blocks" << std::endl;
- world_mt.set("backend", migrate_to);
- if (!world_mt.updateConfigFile(
- (game_params.world_path+ DIR_DELIM + "world.mt").c_str()))
- errorstream << "Failed to update world.mt!" << std::endl;
- else
- actionstream << "world.mt updated" << std::endl;
-
- return true;
-}
-
-
-/*****************************************************************************
- * Client
- *****************************************************************************/
-#ifndef SERVER
-
-ClientLauncher::~ClientLauncher()
-{
- if (receiver)
- delete receiver;
-
- if (input)
- delete input;
-
- if (g_fontengine)
- delete g_fontengine;
-
- if (device)
- device->drop();
-}
-
-
-bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
-{
- init_args(game_params, cmd_args);
-
- // List video modes if requested
- if (list_video_modes)
- return print_video_modes();
-
- if (!init_engine(game_params.log_level)) {
- errorstream << "Could not initialize game engine." << std::endl;
- return false;
- }
-
- // Speed tests (done after irrlicht is loaded to get timer)
- if (cmd_args.getFlag("speedtests")) {
- dstream << "Running speed tests" << std::endl;
- speed_tests();
- return true;
- }
-
- video::IVideoDriver *video_driver = device->getVideoDriver();
- if (video_driver == NULL) {
- errorstream << "Could not initialize video driver." << std::endl;
- return false;
- }
-
- porting::setXorgClassHint(video_driver->getExposedVideoData(), "Minetest");
-
- /*
- This changes the minimum allowed number of vertices in a VBO.
- Default is 500.
- */
- //driver->setMinHardwareBufferVertexCount(50);
-
- // Create time getter
- g_timegetter = new IrrlichtTimeGetter(device);
-
- // Create game callback for menus
- g_gamecallback = new MainGameCallback(device);
-
- device->setResizable(true);
-
- if (random_input)
- input = new RandomInputHandler();
- else
- input = new RealInputHandler(device, receiver);
-
- smgr = device->getSceneManager();
-
- guienv = device->getGUIEnvironment();
- skin = guienv->getSkin();
- skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255));
- skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 0, 0, 0));
- skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255, 0, 0, 0));
- skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255, 70, 100, 50));
- skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255, 255, 255, 255));
-
- g_fontengine = new FontEngine(g_settings, guienv);
- assert(g_fontengine != NULL);
-
-#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
- // Irrlicht 1.8 input colours
- skin->setColor(gui::EGDC_EDITABLE, video::SColor(255, 128, 128, 128));
- skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255, 96, 134, 49));
-#endif
-
- // Create the menu clouds
- if (!g_menucloudsmgr)
- g_menucloudsmgr = smgr->createNewSceneManager();
- if (!g_menuclouds)
- g_menuclouds = new Clouds(g_menucloudsmgr->getRootSceneNode(),
- g_menucloudsmgr, -1, rand(), 100);
- g_menuclouds->update(v2f(0, 0), video::SColor(255, 200, 200, 255));
- scene::ICameraSceneNode* camera;
- camera = g_menucloudsmgr->addCameraSceneNode(0,
- v3f(0, 0, 0), v3f(0, 60, 100));
- camera->setFarValue(10000);
-
- /*
- GUI stuff
- */
-
- ChatBackend chat_backend;
-
- // If an error occurs, this is set to something by menu().
- // It is then displayed before the menu shows on the next call to menu()
- std::wstring error_message = L"";
-
- bool first_loop = true;
-
- /*
- Menu-game loop
- */
- bool retval = true;
- bool *kill = porting::signal_handler_killstatus();
-
- while (device->run() && !*kill && !g_gamecallback->shutdown_requested)
- {
- // Set the window caption
- wchar_t *text = wgettext("Main Menu");
- device->setWindowCaption((std::wstring(L"Minetest [") + text + L"]").c_str());
- delete[] text;
-
- try { // This is used for catching disconnects
-
- guienv->clear();
-
- /*
- We need some kind of a root node to be able to add
- custom gui elements directly on the screen.
- Otherwise they won't be automatically drawn.
- */
- guiroot = guienv->addStaticText(L"", core::rect<s32>(0, 0, 10000, 10000));
-
- bool game_has_run = launch_game(&error_message, game_params, cmd_args);
-
- // If skip_main_menu, we only want to startup once
- if (skip_main_menu && !first_loop)
- break;
-
- first_loop = false;