- 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 (device)
- device->drop();
-
-#if USE_FREETYPE
- if (use_freetype && font != NULL)
- font->drop();
-#endif
-}
-
-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;
- }
-
- late_init_default_settings(g_settings);
-
- // 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;
- }
-
- if (device->getVideoDriver() == NULL) {
- errorstream << "Could not initialize video driver." << std::endl;
- return false;
- }
-
- /*
- 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();
- std::string font_path = g_settings->get("font_path");
-
-#if USE_FREETYPE
-
- if (use_freetype) {
- std::string fallback;
- if (is_yes(gettext("needs_fallback_font")))
- fallback = "fallback_";
- u16 font_size = g_settings->getU16(fallback + "font_size");
- font_path = g_settings->get(fallback + "font_path");
- u32 font_shadow = g_settings->getU16(fallback + "font_shadow");
- u32 font_shadow_alpha = g_settings->getU16(fallback + "font_shadow_alpha");
- font = gui::CGUITTFont::createTTFont(guienv,
- font_path.c_str(), font_size, true, true,
- font_shadow, font_shadow_alpha);
- } else {
- font = guienv->getFont(font_path.c_str());
- }
-#else
- font = guienv->getFont(font_path.c_str());
-#endif
- if (font)
- skin->setFont(font);
- else
- errorstream << "WARNING: Font file was not found. Using default font."
- << std::endl;
-
- font = skin->getFont(); // If font was not found, this will get us one
- assert(font);
-
- u32 text_height = font->getDimension(L"Hello, world!").Height;
- infostream << "text_height=" << text_height << std::endl;
-
- 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));
-
-#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;
-
- if (!game_has_run) {
- if (skip_main_menu)
- break;
- else
- continue;
- }
-
- // Break out of menu-game loop to shut down cleanly
- if (!device->run() || *kill) {
- if (g_settings_path != "")
- g_settings->updateConfigFile(g_settings_path.c_str());
- break;
- }
-
- if (current_playername.length() > PLAYERNAME_SIZE-1) {
- error_message = wgettext("Player name too long.");
- playername = current_playername.substr(0, PLAYERNAME_SIZE-1);
- g_settings->set("name", playername);
- continue;
- }
-
- device->getVideoDriver()->setTextureCreationFlag(
- video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
-
-#ifdef HAVE_TOUCHSCREENGUI
- receiver->m_touchscreengui = new TouchScreenGUI(device, receiver);
- g_touchscreengui = receiver->m_touchscreengui;
-#endif
- the_game(
- kill,
- random_input,
- input,
- device,
- font,
- worldspec.path,
- current_playername,
- current_password,
- current_address,
- current_port,
- error_message,
- chat_backend,
- gamespec,
- simple_singleplayer_mode
- );
- smgr->clear();
-
-#ifdef HAVE_TOUCHSCREENGUI
- delete g_touchscreengui;
- g_touchscreengui = NULL;
- receiver->m_touchscreengui = NULL;
-#endif
-
- } //try
- catch (con::PeerNotFoundException &e) {
- error_message = wgettext("Connection error (timed out?)");
- errorstream << wide_to_narrow(error_message) << std::endl;
- }
-
-#ifdef NDEBUG
- catch (std::exception &e) {
- std::string narrow_message = "Some exception: \"";
- narrow_message += e.what();
- narrow_message += "\"";
- errorstream << narrow_message << std::endl;
- error_message = narrow_to_wide(narrow_message);
- }
-#endif
-
- // If no main menu, show error and exit
- if (skip_main_menu) {
- if (error_message != L"") {
- verbosestream << "error_message = "
- << wide_to_narrow(error_message) << std::endl;
- retval = false;