コード例 #1
0
ファイル: main.cpp プロジェクト: t0suj4/minetest
static bool init_common(int *log_level, const Settings &cmd_args, int argc, char *argv[])
{
	startup_message();
	set_default_settings(g_settings);

	// Initialize sockets
	sockets_init();
	atexit(sockets_cleanup);

	if (!read_config_file(cmd_args))
		return false;

	init_debug_streams(log_level, cmd_args);

	// Initialize random seed
	srand(time(0));
	mysrand(time(0));

	// Initialize HTTP fetcher
	httpfetch_init(g_settings->getS32("curl_parallel_limit"));

#ifdef _MSC_VER
	init_gettext((porting::path_share + DIR_DELIM + "locale").c_str(),
		g_settings->get("language"), argc, argv);
#else
	init_gettext((porting::path_share + DIR_DELIM + "locale").c_str(),
		g_settings->get("language"));
#endif

	return true;
}
コード例 #2
0
/**
 * matecomponent_activation_get_goption_group:
 *
 * Returns a #GOptionGroup for parsing matecomponent-activation options.
 * 
 * Return value: a new #GOptionGroup
 *
 * Since: 2.14
 */
GOptionGroup *
matecomponent_activation_get_goption_group (void)
{
	const GOptionEntry matecomponent_activation_goption_options[] = {
		{ "oaf-ior-fd", '\0', 0,  G_OPTION_ARG_INT, &matecomponent_activation_ior_fd,
		  N_("File descriptor to print IOR on"), N_("FD") },
		{ "oaf-activate-iid", '\0', 0, G_OPTION_ARG_STRING, &matecomponent_activation_activate_iid,
		  N_("IID to activate"), "IID" },
		{ "oaf-private", '\0', 0, G_OPTION_ARG_NONE, &matecomponent_activation_private,
		  N_("Prevent registering of server with OAF"), NULL },
		{ NULL }
	};
	GOptionGroup *group;

	init_gettext (TRUE);

	group = g_option_group_new ("matecomponent-activation",
				    N_("MateComponent Activation options:"),
				    N_("Show MateComponent Activation options"),
				    NULL, NULL);
	g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
	g_option_group_add_entries (group, matecomponent_activation_goption_options);

	return group;
}
コード例 #3
0
ファイル: main.cpp プロジェクト: EdsonOliveira/ELOcraft
static bool init_common(const Settings &cmd_args, int argc, char *argv[])
{
    startup_message();
    set_default_settings(g_settings);

    // Initialize sockets
    sockets_init();
    atexit(sockets_cleanup);

    if (!read_config_file(cmd_args))
        return false;

    init_log_streams(cmd_args);

    // Initialize random seed
    srand(time(0));
    mysrand(time(0));

    // Initialize HTTP fetcher
    httpfetch_init(g_settings->getS32("curl_parallel_limit"));

    init_gettext(porting::path_locale.c_str(),
                 g_settings->get("language"), argc, argv);

    return true;
}
コード例 #4
0
ファイル: main.cpp プロジェクト: prodigeni/freeminer
static bool init_common(int *log_level, const Settings &cmd_args, int argc, char *argv[])
{
	startup_message();
	set_default_settings(g_settings);

	// Initialize sockets
	sockets_init();
	atexit(sockets_cleanup);

	if (!read_config_file(cmd_args))
		return false;

	init_debug_streams(log_level, cmd_args);

	g_time_taker_enabled = g_settings->getU16("time_taker_enabled") ? g_settings->getU16("time_taker_enabled") : ((g_settings->getFloat("profiler_print_interval") || *log_level >= LMT_INFO) ? 100 : 0);

	int autoexit_ = 0;
	cmd_args.getS32NoEx("autoexit", autoexit_);
	g_profiler_enabled = g_settings->getFloat("profiler_print_interval") || autoexit_;

	// Initialize random seed
	srand(time(0));
	mysrand(time(0));

	// Initialize HTTP fetcher
	httpfetch_init(g_settings->getS32("curl_parallel_limit"));

#ifdef _MSC_VER
	init_gettext((porting::path_share + DIR_DELIM + "locale").c_str(),
		g_settings->get("language"), argc, argv);
#else
	init_gettext((porting::path_share + DIR_DELIM + "locale").c_str(),
		g_settings->get("language"));
#endif

#if defined(_WIN32)
	//Remove windows console window if settings request
	if (!g_settings->getBool("console_enabled"))
		FreeConsole();
#endif

	return true;
}
コード例 #5
0
ファイル: ipa-getkeytab.c プロジェクト: stlaz/freeipa
int main(int argc, const char *argv[])
{
	static const char *server = NULL;
	static const char *principal = NULL;
	static const char *keytab = NULL;
	static const char *enctypes_string = NULL;
	static const char *binddn = NULL;
	static const char *bindpw = NULL;
	char *ldap_uri = NULL;
	static const char *sasl_mech = NULL;
	static const char *ca_cert_file = NULL;
	int quiet = 0;
	int askpass = 0;
	int permitted_enctypes = 0;
	int retrieve = 0;
        struct poptOption options[] = {
            { "quiet", 'q', POPT_ARG_NONE, &quiet, 0,
              _("Print as little as possible"), _("Output only on errors")},
            { "server", 's', POPT_ARG_STRING, &server, 0,
              _("Contact this specific KDC Server"),
              _("Server Name") },
            { "principal", 'p', POPT_ARG_STRING, &principal, 0,
              _("The principal to get a keytab for (ex: ftp/[email protected])"),
              _("Kerberos Service Principal Name") },
            { "keytab", 'k', POPT_ARG_STRING, &keytab, 0,
              _("The keytab file to append the new key to (will be "
                "created if it does not exist)."),
              _("Keytab File Name") },
	    { "enctypes", 'e', POPT_ARG_STRING, &enctypes_string, 0,
              _("Encryption types to request"),
              _("Comma separated encryption types list") },
	    { "permitted-enctypes", 0, POPT_ARG_NONE, &permitted_enctypes, 0,
              _("Show the list of permitted encryption types and exit"),
              _("Permitted Encryption Types") },
	    { "password", 'P', POPT_ARG_NONE, &askpass, 0,
              _("Asks for a non-random password to use for the principal"), NULL },
	    { "binddn", 'D', POPT_ARG_STRING, &binddn, 0,
              _("LDAP DN"), _("DN to bind as if not using kerberos") },
	    { "bindpw", 'w', POPT_ARG_STRING, &bindpw, 0,
              _("LDAP password"), _("password to use if not using kerberos") },
	    { "cacert", 0, POPT_ARG_STRING, &ca_cert_file, 0,
              _("Path to the IPA CA certificate"), _("IPA CA certificate")},
	    { "ldapuri", 'H', POPT_ARG_STRING, &ldap_uri, 0,
              _("LDAP uri to connect to. Mutually exclusive with --server"),
              _("url")},
	    { "mech", 'Y', POPT_ARG_STRING, &sasl_mech, 0,
              _("LDAP SASL bind mechanism if no bindd/bindpw"),
              _("GSSAPI|EXTERNAL") },
	    { "retrieve", 'r', POPT_ARG_NONE, &retrieve, 0,
              _("Retrieve current keys without changing them"), NULL },
            POPT_AUTOHELP
            POPT_TABLEEND
	};
	poptContext pc;
	char *ktname;
	char *password = NULL;
	krb5_context krbctx;
	krb5_ccache ccache;
	krb5_principal uprinc = NULL;
	krb5_principal sprinc;
	krb5_error_code krberr;
	struct keys_container keys = { 0 };
	krb5_keytab kt;
	int kvno;
	int i, ret;
	char *err_msg;

    ret = init_gettext();
    if (ret) {
        fprintf(stderr, "Failed to load translations\n");
    }

	krberr = krb5_init_context(&krbctx);
	if (krberr) {
		fprintf(stderr, _("Kerberos context initialization failed\n"));
		exit(1);
	}

	pc = poptGetContext("ipa-getkeytab", argc, (const char **)argv, options, 0);
	ret = poptGetNextOpt(pc);
	if (ret == -1 && permitted_enctypes &&
	    !(server || principal || keytab || quiet)) {
		krb5_enctype *ktypes;
		char enc[79]; /* fit std terminal or truncate */

		krberr = krb5_get_permitted_enctypes(krbctx, &ktypes);
		if (krberr) {
			fprintf(stderr, _("No system preferred enctypes ?!\n"));
			exit(1);
		}
		fprintf(stdout, _("Supported encryption types:\n"));
		for (i = 0; ktypes[i]; i++) {
			krberr = krb5_enctype_to_string(ktypes[i], enc, 79);
			if (krberr) {
				fprintf(stderr, _("Warning: "
                                        "failed to convert type (#%d)\n"), i);
				continue;
			}
			fprintf(stdout, "%s\n", enc);
		}
		ipa_krb5_free_ktypes(krbctx, ktypes);
		exit (0);
	}

	if (ret != -1 || !principal || !keytab || permitted_enctypes) {
		if (!quiet) {
			poptPrintUsage(pc, stderr, 0);
		}
		exit(2);
	}

	if (NULL!=binddn && NULL==bindpw) {
		fprintf(stderr,
                        _("Bind password required when using a bind DN.\n"));
		if (!quiet)
			poptPrintUsage(pc, stderr, 0);
		exit(10);
	}

    if (NULL != binddn && NULL != sasl_mech) {
        fprintf(stderr, _("Cannot specify both SASL mechanism "
                          "and bind DN simultaneously.\n"));
        if (!quiet)
            poptPrintUsage(pc, stderr, 0);
        exit(2);
    }

    if (sasl_mech && check_sasl_mech(sasl_mech)) {
        fprintf(stderr, _("Invalid SASL bind mechanism\n"));
        if (!quiet)
            poptPrintUsage(pc, stderr, 0);
        exit(2);
    }

    if (!binddn && !sasl_mech) {
        sasl_mech = LDAP_SASL_GSSAPI;
    }

    if (server && ldap_uri) {
        fprintf(stderr, _("Cannot specify server and LDAP uri "
                          "simultaneously.\n"));
        if (!quiet)
            poptPrintUsage(pc, stderr, 0);
        exit(2);
    }

    if (!server && !ldap_uri) {
        struct ipa_config *ipacfg = NULL;

        ret = read_ipa_config(&ipacfg);
        if (ret == 0) {
            server = ipacfg->server_name;
            ipacfg->server_name = NULL;
        }
        free(ipacfg);
        if (!server) {
            fprintf(stderr, _("Server name not provided and unavailable\n"));
            exit(2);
        }
    }
    if (server) {
        ret = ipa_server_to_uri(server, sasl_mech, &ldap_uri);
        if (ret) {
            exit(ret);
        }
    }

    if (!ca_cert_file) {
        ca_cert_file = DEFAULT_CA_CERT_FILE;
    }

    if (askpass && retrieve) {
        fprintf(stderr, _("Incompatible options provided (-r and -P)\n"));
        exit(2);
    }

        if (askpass) {
		password = ask_password(krbctx);
		if (!password) {
			exit(2);
		}
	} else if (enctypes_string && strchr(enctypes_string, ':')) {
		if (!quiet) {
			fprintf(stderr, _("Warning: salt types are not honored"
                                " with randomized passwords (see opt. -P)\n"));
		}
	}

	ret = asprintf(&ktname, "WRFILE:%s", keytab);
	if (ret == -1) {
		exit(3);
	}

	krberr = krb5_parse_name(krbctx, principal, &sprinc);
	if (krberr) {
		fprintf(stderr, _("Invalid Service Principal Name\n"));
		exit(4);
	}

	if (NULL == bindpw && strcmp(sasl_mech, LDAP_SASL_GSSAPI) == 0) {
		krberr = krb5_cc_default(krbctx, &ccache);
		if (krberr) {
			fprintf(stderr,
                                _("Kerberos Credential Cache not found. "
				  "Do you have a Kerberos Ticket?\n"));
			exit(5);
		}

		krberr = krb5_cc_get_principal(krbctx, ccache, &uprinc);
		if (krberr) {
			fprintf(stderr,
                                _("Kerberos User Principal not found. "
				  "Do you have a valid Credential Cache?\n"));
			exit(6);
		}
	}

	krberr = krb5_kt_resolve(krbctx, ktname, &kt);
	if (krberr) {
		fprintf(stderr, _("Failed to open Keytab\n"));
		exit(7);
	}

    kvno = -1;
    ret = ldap_get_keytab(krbctx, (retrieve == 0), password, enctypes_string,
                          ldap_uri, principal, uprinc, binddn, bindpw,
                          sasl_mech, ca_cert_file,
                          &keys, &kvno, &err_msg);
    if (ret) {
        if (!quiet && err_msg != NULL) {
            fprintf(stderr, "%s", err_msg);
        }
    }

    if (retrieve == 0 && kvno == -1) {
        if (!quiet) {
            fprintf(stderr,
                    _("Retrying with pre-4.0 keytab retrieval method...\n"));
        }

        /* create key material */
        ret = create_keys(krbctx, sprinc, password, enctypes_string, &keys, &err_msg);
        if (!ret) {
            if (err_msg != NULL) {
                fprintf(stderr, "%s", err_msg);
            }

            fprintf(stderr, _("Failed to create key material\n"));
            exit(8);
        }

        kvno = ldap_set_keytab(krbctx, ldap_uri, principal, uprinc, binddn,
                               bindpw, sasl_mech, ca_cert_file, &keys);
    }

    if (kvno == -1) {
        fprintf(stderr, _("Failed to get keytab\n"));
        exit(9);
    }

	for (i = 0; i < keys.nkeys; i++) {
		krb5_keytab_entry kt_entry;
		memset((char *)&kt_entry, 0, sizeof(kt_entry));
		kt_entry.principal = sprinc;
		kt_entry.key = keys.ksdata[i].key;
		kt_entry.vno = kvno;

		krberr = krb5_kt_add_entry(krbctx, kt, &kt_entry);
		if (krberr) {
			fprintf(stderr,
                                _("Failed to add key to the keytab\n"));
			exit (11);
		}
	}

	free_keys_contents(krbctx, &keys);

	krberr = krb5_kt_close(krbctx, kt);
	if (krberr) {
		fprintf(stderr, _("Failed to close the keytab\n"));
		exit (12);
	}

	if (!quiet) {
		fprintf(stderr,
			_("Keytab successfully retrieved and stored in: %s\n"),
			keytab);
	}
	exit(0);
}
コード例 #6
0
ファイル: main.cpp プロジェクト: FessWolf/minetest
int main(int argc, char *argv[])
{
	int retval = 0;

	/*
		Initialization
	*/

	log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION);
	log_add_output_all_levs(&main_dstream_no_stderr_log_out);

	log_register_thread("main");
	/*
		Parse command line
	*/

	// List all allowed options
	std::map<std::string, ValueSpec> allowed_options;
	allowed_options.insert(std::make_pair("help", ValueSpec(VALUETYPE_FLAG,
			_("Show allowed options"))));
	allowed_options.insert(std::make_pair("version", ValueSpec(VALUETYPE_FLAG,
			_("Show version information"))));
	allowed_options.insert(std::make_pair("config", ValueSpec(VALUETYPE_STRING,
			_("Load configuration from specified file"))));
	allowed_options.insert(std::make_pair("port", ValueSpec(VALUETYPE_STRING,
			_("Set network port (UDP)"))));
	allowed_options.insert(std::make_pair("disable-unittests", ValueSpec(VALUETYPE_FLAG,
			_("Disable unit tests"))));
	allowed_options.insert(std::make_pair("enable-unittests", ValueSpec(VALUETYPE_FLAG,
			_("Enable unit tests"))));
	allowed_options.insert(std::make_pair("map-dir", ValueSpec(VALUETYPE_STRING,
			_("Same as --world (deprecated)"))));
	allowed_options.insert(std::make_pair("world", ValueSpec(VALUETYPE_STRING,
			_("Set world path (implies local game) ('list' lists all)"))));
	allowed_options.insert(std::make_pair("worldname", ValueSpec(VALUETYPE_STRING,
			_("Set world by name (implies local game)"))));
	allowed_options.insert(std::make_pair("info", ValueSpec(VALUETYPE_FLAG,
			_("Print more information to console"))));
	allowed_options.insert(std::make_pair("verbose",  ValueSpec(VALUETYPE_FLAG,
			_("Print even more information to console"))));
	allowed_options.insert(std::make_pair("trace", ValueSpec(VALUETYPE_FLAG,
			_("Print enormous amounts of information to log and console"))));
	allowed_options.insert(std::make_pair("logfile", ValueSpec(VALUETYPE_STRING,
			_("Set logfile path ('' = no logging)"))));
	allowed_options.insert(std::make_pair("gameid", ValueSpec(VALUETYPE_STRING,
			_("Set gameid (\"--gameid list\" prints available ones)"))));
	allowed_options.insert(std::make_pair("migrate", ValueSpec(VALUETYPE_STRING,
			_("Migrate from current map backend to another (Only works when using minetestserver or with --server)"))));
#ifndef SERVER
	allowed_options.insert(std::make_pair("videomodes", ValueSpec(VALUETYPE_FLAG,
			_("Show available video modes"))));
	allowed_options.insert(std::make_pair("speedtests", ValueSpec(VALUETYPE_FLAG,
			_("Run speed tests"))));
	allowed_options.insert(std::make_pair("address", ValueSpec(VALUETYPE_STRING,
			_("Address to connect to. ('' = local game)"))));
	allowed_options.insert(std::make_pair("random-input", ValueSpec(VALUETYPE_FLAG,
			_("Enable random user input, for testing"))));
	allowed_options.insert(std::make_pair("server", ValueSpec(VALUETYPE_FLAG,
			_("Run dedicated server"))));
	allowed_options.insert(std::make_pair("name", ValueSpec(VALUETYPE_STRING,
			_("Set player name"))));
	allowed_options.insert(std::make_pair("password", ValueSpec(VALUETYPE_STRING,
			_("Set password"))));
	allowed_options.insert(std::make_pair("go", ValueSpec(VALUETYPE_FLAG,
			_("Disable main menu"))));
#endif

	Settings cmd_args;

	bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options);

	if(ret == false || cmd_args.getFlag("help") || cmd_args.exists("nonopt1"))
	{
		dstream<<_("Allowed options:")<<std::endl;
		for(std::map<std::string, ValueSpec>::iterator
				i = allowed_options.begin();
				i != allowed_options.end(); ++i)
		{
			std::ostringstream os1(std::ios::binary);
			os1<<"  --"<<i->first;
			if(i->second.type == VALUETYPE_FLAG)
				{}
			else
				os1<<_(" <value>");
			dstream<<padStringRight(os1.str(), 24);

			if(i->second.help != NULL)
				dstream<<i->second.help;
			dstream<<std::endl;
		}

		return cmd_args.getFlag("help") ? 0 : 1;
	}

	if(cmd_args.getFlag("version"))
	{
#ifdef SERVER
		dstream<<"minetestserver "<<minetest_version_hash<<std::endl;
#else
		dstream<<"Minetest "<<minetest_version_hash<<std::endl;
		dstream<<"Using Irrlicht "<<IRRLICHT_SDK_VERSION<<std::endl;
#endif
		dstream<<"Build info: "<<minetest_build_info<<std::endl;
		return 0;
	}

	/*
		Low-level initialization
	*/

	// If trace is enabled, enable logging of certain things
	if(cmd_args.getFlag("trace")){
		dstream<<_("Enabling trace level debug output")<<std::endl;
		log_trace_level_enabled = true;
		dout_con_ptr = &verbosestream; // this is somewhat old crap
		socket_enable_debug_output = true; // socket doesn't use log.h
	}
	// In certain cases, output info level on stderr
	if(cmd_args.getFlag("info") || cmd_args.getFlag("verbose") ||
			cmd_args.getFlag("trace") || cmd_args.getFlag("speedtests"))
		log_add_output(&main_stderr_log_out, LMT_INFO);
	// In certain cases, output verbose level on stderr
	if(cmd_args.getFlag("verbose") || cmd_args.getFlag("trace"))
		log_add_output(&main_stderr_log_out, LMT_VERBOSE);

	porting::signal_handler_init();
	bool &kill = *porting::signal_handler_killstatus();

	porting::initializePaths();

	// Create user data directory
	fs::CreateDir(porting::path_user);

	infostream<<"path_share = "<<porting::path_share<<std::endl;
	infostream<<"path_user  = "******"gameid") && cmd_args.get("gameid") == "list")
	{
		std::set<std::string> gameids = getAvailableGameIds();
		for(std::set<std::string>::const_iterator i = gameids.begin();
				i != gameids.end(); i++)
			dstream<<(*i)<<std::endl;
		return 0;
	}

	// List worlds if requested
	if(cmd_args.exists("world") && cmd_args.get("world") == "list"){
		dstream<<_("Available worlds:")<<std::endl;
		std::vector<WorldSpec> worldspecs = getAvailableWorlds();
		print_worldspecs(worldspecs, dstream);
		return 0;
	}

	// Print startup message
	infostream<<PROJECT_NAME<<
			" "<<_("with")<<" SER_FMT_VER_HIGHEST_READ="<<(int)SER_FMT_VER_HIGHEST_READ
			<<", "<<minetest_build_info
			<<std::endl;

	/*
		Basic initialization
	*/

	// Initialize default settings
	set_default_settings(g_settings);

	// Initialize sockets
	sockets_init();
	atexit(sockets_cleanup);

	/*
		Read config file
	*/

	// Path of configuration file in use
	g_settings_path = "";

	if(cmd_args.exists("config"))
	{
		bool r = g_settings->readConfigFile(cmd_args.get("config").c_str());
		if(r == false)
		{
			errorstream<<"Could not read configuration from \""
					<<cmd_args.get("config")<<"\""<<std::endl;
			return 1;
		}
		g_settings_path = cmd_args.get("config");
	}
	else
	{
		std::vector<std::string> filenames;
		filenames.push_back(porting::path_user +
				DIR_DELIM + "minetest.conf");
		// Legacy configuration file location
		filenames.push_back(porting::path_user +
				DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#if RUN_IN_PLACE
		// Try also from a lower level (to aid having the same configuration
		// for many RUN_IN_PLACE installs)
		filenames.push_back(porting::path_user +
				DIR_DELIM + ".." + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#endif

		for(u32 i=0; i<filenames.size(); i++)
		{
			bool r = g_settings->readConfigFile(filenames[i].c_str());
			if(r)
			{
				g_settings_path = filenames[i];
				break;
			}
		}

		// If no path found, use the first one (menu creates the file)
		if(g_settings_path == "")
			g_settings_path = filenames[0];
	}

	// Initialize debug streams
#define DEBUGFILE "debug.txt"
#if RUN_IN_PLACE
	std::string logfile = DEBUGFILE;
#else
	std::string logfile = porting::path_user+DIR_DELIM+DEBUGFILE;
#endif
	if(cmd_args.exists("logfile"))
		logfile = cmd_args.get("logfile");

	log_remove_output(&main_dstream_no_stderr_log_out);
	int loglevel = g_settings->getS32("debug_log_level");

	if (loglevel == 0) //no logging
		logfile = "";
	else if (loglevel > 0 && loglevel <= LMT_NUM_VALUES)
		log_add_output_maxlev(&main_dstream_no_stderr_log_out, (LogMessageLevel)(loglevel - 1));

	if(logfile != "")
		debugstreams_init(false, logfile.c_str());
	else
		debugstreams_init(false, NULL);

	infostream<<"logfile    = "<<logfile<<std::endl;

	// Initialize random seed
	srand(time(0));
	mysrand(time(0));

	// Initialize HTTP fetcher
	httpfetch_init(g_settings->getS32("curl_parallel_limit"));

	/*
		Run unit tests
	*/

	if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
			|| cmd_args.getFlag("enable-unittests") == true)
	{
		run_tests();
	}
#ifdef _MSC_VER
	init_gettext((porting::path_share + DIR_DELIM + "locale").c_str(),g_settings->get("language"),argc,argv);
#else
	init_gettext((porting::path_share + DIR_DELIM + "locale").c_str(),g_settings->get("language"));
#endif

	/*
		Game parameters
	*/

	// Port
	u16 port = 30000;
	if(cmd_args.exists("port"))
		port = cmd_args.getU16("port");
	else if(g_settings->exists("port"))
		port = g_settings->getU16("port");
	if(port == 0)
		port = 30000;

	// World directory
	std::string commanded_world = "";
	if(cmd_args.exists("world"))
		commanded_world = cmd_args.get("world");
	else if(cmd_args.exists("map-dir"))
		commanded_world = cmd_args.get("map-dir");
	else if(cmd_args.exists("nonopt0")) // First nameless argument
		commanded_world = cmd_args.get("nonopt0");
	else if(g_settings->exists("map-dir"))
		commanded_world = g_settings->get("map-dir");

	// World name
	std::string commanded_worldname = "";
	if(cmd_args.exists("worldname"))
		commanded_worldname = cmd_args.get("worldname");

	// Strip world.mt from commanded_world
	{
		std::string worldmt = "world.mt";
		if(commanded_world.size() > worldmt.size() &&
				commanded_world.substr(commanded_world.size()-worldmt.size())
				== worldmt){
			dstream<<_("Supplied world.mt file - stripping it off.")<<std::endl;
			commanded_world = commanded_world.substr(
					0, commanded_world.size()-worldmt.size());
		}
	}

	// If a world name was specified, convert it to a path
	if(commanded_worldname != ""){
		// Get information about available worlds
		std::vector<WorldSpec> worldspecs = getAvailableWorlds();
		bool found = false;
		for(u32 i=0; i<worldspecs.size(); i++){
			std::string name = worldspecs[i].name;
			if(name == commanded_worldname){
				if(commanded_world != ""){
					dstream<<_("--worldname takes precedence over previously "
							"selected world.")<<std::endl;
				}
				commanded_world = worldspecs[i].path;
				found = true;
				break;
			}
		}
		if(!found){
			dstream<<_("World")<<" '"<<commanded_worldname<<_("' not "
					"available. Available worlds:")<<std::endl;
			print_worldspecs(worldspecs, dstream);
			return 1;
		}
	}

	// Gamespec
	SubgameSpec commanded_gamespec;
	if(cmd_args.exists("gameid")){
		std::string gameid = cmd_args.get("gameid");
		commanded_gamespec = findSubgame(gameid);
		if(!commanded_gamespec.isValid()){
			errorstream<<"Game \""<<gameid<<"\" not found"<<std::endl;
			return 1;
		}
	}


	/*
		Run dedicated server if asked to or no other option
	*/
#ifdef SERVER
	bool run_dedicated_server = true;
#else
	bool run_dedicated_server = cmd_args.getFlag("server");
#endif
	g_settings->set("server_dedicated", run_dedicated_server ? "true" : "false");
	if(run_dedicated_server)
	{
		DSTACK("Dedicated server branch");
		// Create time getter if built with Irrlicht
#ifndef SERVER
		g_timegetter = new SimpleTimeGetter();
#endif

		// World directory
		std::string world_path;
		verbosestream<<_("Determining world path")<<std::endl;
		bool is_legacy_world = false;
		// If a world was commanded, use it
		if(commanded_world != ""){
			world_path = commanded_world;
			infostream<<"Using commanded world path ["<<world_path<<"]"
					<<std::endl;
		}
		// No world was specified; try to select it automatically
		else
		{
			// Get information about available worlds
			std::vector<WorldSpec> worldspecs = getAvailableWorlds();
			// If a world name was specified, select it
			if(commanded_worldname != ""){
				world_path = "";
				for(u32 i=0; i<worldspecs.size(); i++){
					std::string name = worldspecs[i].name;
					if(name == commanded_worldname){
						world_path = worldspecs[i].path;
						break;
					}
				}
				if(world_path == ""){
					dstream<<_("World")<<" '"<<commanded_worldname<<"' "<<_("not "
							"available. Available worlds:")<<std::endl;
					print_worldspecs(worldspecs, dstream);
					return 1;
				}
			}
			// If there is only a single world, use it
			if(worldspecs.size() == 1){
				world_path = worldspecs[0].path;
				dstream<<_("Automatically selecting world at")<<" ["
						<<world_path<<"]"<<std::endl;
			// If there are multiple worlds, list them
			} else if(worldspecs.size() > 1){
				dstream<<_("Multiple worlds are available.")<<std::endl;
				dstream<<_("Please select one using --worldname <name>"
						" or --world <path>")<<std::endl;
				print_worldspecs(worldspecs, dstream);
				return 1;
			// If there are no worlds, automatically create a new one
			} else {
				// This is the ultimate default world path
				world_path = porting::path_user + DIR_DELIM + "worlds" +
						DIR_DELIM + "world";
				infostream<<"Creating default world at ["
						<<world_path<<"]"<<std::endl;
			}
		}

		if(world_path == ""){
			errorstream<<"No world path specified or found."<<std::endl;
			return 1;
		}
		verbosestream<<_("Using world path")<<" ["<<world_path<<"]"<<std::endl;

		// We need a gamespec.
		SubgameSpec gamespec;
		verbosestream<<_("Determining gameid/gamespec")<<std::endl;
		// If world doesn't exist
		if(!getWorldExists(world_path))
		{
			// Try to take gamespec from command line
			if(commanded_gamespec.isValid()){
				gamespec = commanded_gamespec;
				infostream<<"Using commanded gameid ["<<gamespec.id<<"]"<<std::endl;
			}
			// Otherwise we will be using "minetest"
			else{
				gamespec = findSubgame(g_settings->get("default_game"));
				infostream<<"Using default gameid ["<<gamespec.id<<"]"<<std::endl;
			}
		}
		// World exists
		else
		{
			std::string world_gameid = getWorldGameId(world_path, is_legacy_world);
			// If commanded to use a gameid, do so
			if(commanded_gamespec.isValid()){
				gamespec = commanded_gamespec;
				if(commanded_gamespec.id != world_gameid){
					errorstream<<"WARNING: Using commanded gameid ["
							<<gamespec.id<<"]"<<" instead of world gameid ["
							<<world_gameid<<"]"<<std::endl;
				}
			} else{
				// If world contains an embedded game, use it;
				// Otherwise find world from local system.
				gamespec = findWorldSubgame(world_path);
				infostream<<"Using world gameid ["<<gamespec.id<<"]"<<std::endl;
			}
		}
		if(!gamespec.isValid()){
			errorstream<<"Subgame ["<<gamespec.id<<"] could not be found."
					<<std::endl;
			return 1;
		}
		verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl;

		// Bind address
		std::string bind_str = g_settings->get("bind_address");
		Address bind_addr(0,0,0,0, port);

		if (g_settings->getBool("ipv6_server")) {
			bind_addr.setAddress((IPv6AddressBytes*) NULL);
		}
		try {
			bind_addr.Resolve(bind_str.c_str());
		} catch (ResolveError &e) {
			infostream << "Resolving bind address \"" << bind_str
			           << "\" failed: " << e.what()
		        	   << " -- Listening on all addresses." << std::endl;
		}
		if(bind_addr.isIPv6() && !g_settings->getBool("enable_ipv6")) {
			errorstream << "Unable to listen on "
			            << bind_addr.serializeString()
				    << L" because IPv6 is disabled" << std::endl;
			return 1;
		}

		// Create server
		Server server(world_path, gamespec, false, bind_addr.isIPv6());

		// Database migration
		if (cmd_args.exists("migrate")) {
			std::string migrate_to = cmd_args.get("migrate");
			Settings world_mt;
			bool success = world_mt.readConfigFile((world_path + DIR_DELIM + "world.mt").c_str());
			if (!success) {
				errorstream << "Cannot read world.mt" << std::endl;
				return 1;
			}
			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 1;
			}
			std::string backend = world_mt.get("backend");
			Database *new_db;
			if (backend == migrate_to) {
				errorstream << "Cannot migrate: new backend is same as the old one" << std::endl;
				return 1;
			}
			if (migrate_to == "sqlite3")
				new_db = new Database_SQLite3(&(ServerMap&)server.getMap(), world_path);
			#if USE_LEVELDB
			else if (migrate_to == "leveldb")
				new_db = new Database_LevelDB(&(ServerMap&)server.getMap(), world_path);
			#endif
			#if USE_REDIS
			else if (migrate_to == "redis")
				new_db = new Database_Redis(&(ServerMap&)server.getMap(), world_path);
			#endif
			else {
				errorstream << "Migration to " << migrate_to << " is not supported" << std::endl;
				return 1;
			}

			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);
				new_db->saveBlock(block);
				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((world_path + DIR_DELIM + "world.mt").c_str()))
				errorstream<<"Failed to update world.mt!"<<std::endl;
			else
				actionstream<<"world.mt updated"<<std::endl;

			return 0;
		}

		server.start(bind_addr);

		// Run server
		dedicated_server_loop(server, kill);

		return 0;
	}

#ifndef SERVER // Exclude from dedicated server build

	/*
		More parameters
	*/

	std::string address = g_settings->get("address");
	if(commanded_world != "")
		address = "";
	else if(cmd_args.exists("address"))
		address = cmd_args.get("address");

	std::string playername = g_settings->get("name");
	if(cmd_args.exists("name"))
		playername = cmd_args.get("name");

	bool skip_main_menu = cmd_args.getFlag("go");

	/*
		Device initialization
	*/

	// Resolution selection

	bool fullscreen = g_settings->getBool("fullscreen");
	u16 screenW = g_settings->getU16("screenW");
	u16 screenH = g_settings->getU16("screenH");

	// bpp, fsaa, vsync

	bool vsync = g_settings->getBool("vsync");
	u16 bits = g_settings->getU16("fullscreen_bpp");
	u16 fsaa = g_settings->getU16("fsaa");

	// Determine driver

	video::E_DRIVER_TYPE driverType;

	std::string driverstring = g_settings->get("video_driver");

	if(driverstring == "null")
		driverType = video::EDT_NULL;
	else if(driverstring == "software")
		driverType = video::EDT_SOFTWARE;
	else if(driverstring == "burningsvideo")
		driverType = video::EDT_BURNINGSVIDEO;
	else if(driverstring == "direct3d8")
		driverType = video::EDT_DIRECT3D8;
	else if(driverstring == "direct3d9")
		driverType = video::EDT_DIRECT3D9;
	else if(driverstring == "opengl")
		driverType = video::EDT_OPENGL;
#ifdef _IRR_COMPILE_WITH_OGLES1_
	else if(driverstring == "ogles1")
		driverType = video::EDT_OGLES1;
#endif
#ifdef _IRR_COMPILE_WITH_OGLES2_
	else if(driverstring == "ogles2")
		driverType = video::EDT_OGLES2;
#endif
	else
	{
		errorstream<<"WARNING: Invalid video_driver specified; defaulting "
				"to opengl"<<std::endl;
		driverType = video::EDT_OPENGL;
	}

	/*
		List video modes if requested
	*/

	MyEventReceiver receiver;

	if(cmd_args.getFlag("videomodes")){
		IrrlichtDevice *nulldevice;

		SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
		params.DriverType    = video::EDT_NULL;
		params.WindowSize    = core::dimension2d<u32>(640, 480);
		params.Bits          = 24;
		params.AntiAlias     = fsaa;
		params.Fullscreen    = false;
		params.Stencilbuffer = false;
		params.Vsync         = vsync;
		params.EventReceiver = &receiver;
		params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu");

		nulldevice = createDeviceEx(params);

		if(nulldevice == 0)
			return 1;

		dstream<<_("Available video modes (WxHxD):")<<std::endl;

		video::IVideoModeList *videomode_list =
				nulldevice->getVideoModeList();

		if(videomode_list == 0){
			nulldevice->drop();
			return 1;
		}

		s32 videomode_count = videomode_list->getVideoModeCount();
		core::dimension2d<u32> videomode_res;
		s32 videomode_depth;
		for (s32 i = 0; i < videomode_count; ++i){
			videomode_res = videomode_list->getVideoModeResolution(i);
			videomode_depth = videomode_list->getVideoModeDepth(i);
			dstream<<videomode_res.Width<<"x"<<videomode_res.Height
					<<"x"<<videomode_depth<<std::endl;
		}

		dstream<<_("Active video mode (WxHxD):")<<std::endl;
		videomode_res = videomode_list->getDesktopResolution();
		videomode_depth = videomode_list->getDesktopDepth();
		dstream<<videomode_res.Width<<"x"<<videomode_res.Height
				<<"x"<<videomode_depth<<std::endl;

		nulldevice->drop();

		return 0;
	}

	/*
		Create device and exit if creation failed
	*/

	IrrlichtDevice *device;

	SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
	params.DriverType    = driverType;
	params.WindowSize    = core::dimension2d<u32>(screenW, screenH);
	params.Bits          = bits;
	params.AntiAlias     = fsaa;
	params.Fullscreen    = fullscreen;
	params.Stencilbuffer = false;
	params.Vsync         = vsync;
	params.EventReceiver = &receiver;
	params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu");

	device = createDeviceEx(params);

	if (device == 0)
		return 1; // could not create selected driver.

	/*
		Continue initialization
	*/

	video::IVideoDriver* driver = device->getVideoDriver();

	/*
		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);

	/*
		Speed tests (done after irrlicht is loaded to get timer)
	*/
	if(cmd_args.getFlag("speedtests"))
	{
		dstream<<"Running speed tests"<<std::endl;
		SpeedTests();
		device->drop();
		return 0;
	}

	device->setResizable(true);

	bool random_input = g_settings->getBool("random_input")
			|| cmd_args.getFlag("random-input");
	InputHandler *input = NULL;
	if(random_input) {
		input = new RandomInputHandler();
	} else {
		input = new RealInputHandler(device, &receiver);
	}

	scene::ISceneManager* smgr = device->getSceneManager();

	guienv = device->getGUIEnvironment();
	gui::IGUISkin* skin = guienv->getSkin();
	std::string font_path = g_settings->get("font_path");
	gui::IGUIFont *font;
	#if USE_FREETYPE
	bool use_freetype = g_settings->getBool("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;
	// If font was not found, this will get us one
	font = skin->getFont();
	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,0,0,0));
	skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255));
	//skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(0,0,0,0));
	//skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(0,0,0,0));
	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 and the
		menu-game loop is restarted. It is then displayed before
		the menu.
	*/
	std::wstring error_message = L"";

	// The password entered during the menu screen,
	std::string password;

	bool first_loop = true;

	/*
		Menu-game loop
	*/
	while(device->run() && kill == false)
	{
		// Set the window caption
		wchar_t* text = wgettext("Main Menu");
		device->setWindowCaption((std::wstring(L"Minetest [")+text+L"]").c_str());
		delete[] text;

		// This is used for catching disconnects
		try
		{

			/*
				Clear everything from the GUIEnvironment
			*/
			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));

			SubgameSpec gamespec;
			WorldSpec worldspec;
			bool simple_singleplayer_mode = false;

			// These are set up based on the menu and other things
			std::string current_playername = "inv£lid";
			std::string current_password = "";
			std::string current_address = "does-not-exist";
			int current_port = 0;

			/*
				Out-of-game menu loop.

				Loop quits when menu returns proper parameters.
			*/
			while(kill == false)
			{
				// If skip_main_menu, only go through here once
				if(skip_main_menu && !first_loop){
					kill = true;
					break;
				}
				first_loop = false;

				// Cursor can be non-visible when coming from the game
				device->getCursorControl()->setVisible(true);
				// Some stuff are left to scene manager when coming from the game
				// (map at least?)
				smgr->clear();

				// Initialize menu data
				MainMenuData menudata;
				menudata.address = address;
				menudata.name = playername;
				menudata.port = itos(port);
				menudata.errormessage = wide_to_narrow(error_message);
				error_message = L"";
				if(cmd_args.exists("password"))
					menudata.password = cmd_args.get("password");

				driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));

				menudata.enable_public = g_settings->getBool("server_announce");

				std::vector<WorldSpec> worldspecs = getAvailableWorlds();

				// If a world was commanded, append and select it
				if(commanded_world != ""){

					std::string gameid = getWorldGameId(commanded_world, true);
					std::string name = _("[--world parameter]");
					if(gameid == ""){
						gameid = g_settings->get("default_game");
						name += " [new]";
					}
					//TODO find within worldspecs and set config
				}

				if(skip_main_menu == false)
				{
					video::IVideoDriver* driver = device->getVideoDriver();

					infostream<<"Waiting for other menus"<<std::endl;
					while(device->run() && kill == false)
					{
						if(noMenuActive())
							break;
						driver->beginScene(true, true,
								video::SColor(255,128,128,128));
						guienv->drawAll();
						driver->endScene();
						// On some computers framerate doesn't seem to be
						// automatically limited
						sleep_ms(25);
					}
					infostream<<"Waited for other menus"<<std::endl;

					GUIEngine* temp = new GUIEngine(device, guiroot, &g_menumgr,smgr,&menudata,kill);

					delete temp;
					//once finished you'll never end up here
					smgr->clear();
				}

				if(menudata.errormessage != ""){
					error_message = narrow_to_wide(menudata.errormessage);
					continue;
				}

				//update worldspecs (necessary as new world may have been created)
				worldspecs = getAvailableWorlds();

				if (menudata.name == "")
					menudata.name = std::string("Guest") + itos(myrand_range(1000,9999));
				else
					playername = menudata.name;

				password = translatePassword(playername, narrow_to_wide(menudata.password));
				//infostream<<"Main: password hash: '"<<password<<"'"<<std::endl;

				address = menudata.address;
				int newport = stoi(menudata.port);
				if(newport != 0)
					port = newport;

				simple_singleplayer_mode = menudata.simple_singleplayer_mode;

				// Save settings
				g_settings->set("name", playername);

				if((menudata.selected_world >= 0) &&
						(menudata.selected_world < (int)worldspecs.size()))
					g_settings->set("selected_world_path",
							worldspecs[menudata.selected_world].path);

				// Break out of menu-game loop to shut down cleanly
				if(device->run() == false || kill == true)
					break;

				current_playername = playername;
				current_password = password;
				current_address = address;
				current_port = port;

				// If using simple singleplayer mode, override
				if(simple_singleplayer_mode){
					current_playername = "singleplayer";
					current_password = "";
					current_address = "";
					current_port = myrand_range(49152, 65535);
				}
				else if (address != "")
				{
					ServerListSpec server;
					server["name"] = menudata.servername;
					server["address"] = menudata.address;
					server["port"] = menudata.port;
					server["description"] = menudata.serverdescription;
					ServerList::insert(server);
				}

				// Set world path to selected one
				if ((menudata.selected_world >= 0) &&
					(menudata.selected_world < (int)worldspecs.size())) {
					worldspec = worldspecs[menudata.selected_world];
					infostream<<"Selected world: "<<worldspec.name
							<<" ["<<worldspec.path<<"]"<<std::endl;
				}

				// If local game
				if(current_address == "")
				{
					if(menudata.selected_world == -1){
						error_message = wgettext("No world selected and no address "
								"provided. Nothing to do.");
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					// Load gamespec for required game
					gamespec = findWorldSubgame(worldspec.path);
					if(!gamespec.isValid() && !commanded_gamespec.isValid()){
						error_message = wgettext("Could not find or load game \"")
								+ narrow_to_wide(worldspec.gameid) + L"\"";
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					if(commanded_gamespec.isValid() &&
							commanded_gamespec.id != worldspec.gameid){
						errorstream<<"WARNING: Overriding gamespec from \""
								<<worldspec.gameid<<"\" to \""
								<<commanded_gamespec.id<<"\""<<std::endl;
						gamespec = commanded_gamespec;
					}

					if(!gamespec.isValid()){
						error_message = wgettext("Invalid gamespec.");
						error_message += L" (world_gameid="
								+narrow_to_wide(worldspec.gameid)+L")";
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
				}

				// Continue to game
				break;
			}

			// Break out of menu-game loop to shut down cleanly
			if(device->run() == false || kill == true) {
				if(g_settings_path != "") {
					g_settings->updateConfigFile(
						g_settings_path.c_str());
				}
				break;
			}

			/*
				Run game
			*/
			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();

		} //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 = 1;
			}
			break;
		}
	} // Menu-game loop


	g_menuclouds->drop();
	g_menucloudsmgr->drop();

	delete input;

	/*
		In the end, delete the Irrlicht device.
	*/
	device->drop();

#if USE_FREETYPE
	if (use_freetype)
		font->drop();
#endif

#endif // !SERVER

	// Update configuration file
	if(g_settings_path != "")
		g_settings->updateConfigFile(g_settings_path.c_str());

	// Print modified quicktune values
	{
		bool header_printed = false;
		std::vector<std::string> names = getQuicktuneNames();
		for(u32 i=0; i<names.size(); i++){
			QuicktuneValue val = getQuicktuneValue(names[i]);
			if(!val.modified)
				continue;
			if(!header_printed){
				dstream<<"Modified quicktune values:"<<std::endl;
				header_printed = true;
			}
			dstream<<names[i]<<" = "<<val.getString()<<std::endl;
		}
	}

	// Stop httpfetch thread (if started)
	httpfetch_cleanup();

	END_DEBUG_EXCEPTION_HANDLER(errorstream)

	debugstreams_deinit();

	return retval;
}
コード例 #7
0
ファイル: main.cpp プロジェクト: Oblomov/minetest
int main(int argc, char *argv[])
{
	/*
		Initialization
	*/

	log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION);
	log_add_output_all_levs(&main_dstream_no_stderr_log_out);

	log_register_thread("main");

	// Set locale. This is for forcing '.' as the decimal point.
	std::locale::global(std::locale("C"));
	// This enables printing all characters in bitmap font
	setlocale(LC_CTYPE, "en_US");

	/*
		Parse command line
	*/
	
	// List all allowed options
	core::map<std::string, ValueSpec> allowed_options;
	allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG));
	allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,
			"Run server directly"));
	allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,
			"Load configuration from specified file"));
	allowed_options.insert("port", ValueSpec(VALUETYPE_STRING));
	allowed_options.insert("address", ValueSpec(VALUETYPE_STRING));
	allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG));
	allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG));
	allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG));
	allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING));
#ifdef _WIN32
	allowed_options.insert("dstream-on-stderr", ValueSpec(VALUETYPE_FLAG));
#endif
	allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG));
	allowed_options.insert("info-on-stderr", ValueSpec(VALUETYPE_FLAG));

	Settings cmd_args;
	
	bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options);

	if(ret == false || cmd_args.getFlag("help"))
	{
		dstream<<"Allowed options:"<<std::endl;
		for(core::map<std::string, ValueSpec>::Iterator
				i = allowed_options.getIterator();
				i.atEnd() == false; i++)
		{
			dstream<<"  --"<<i.getNode()->getKey();
			if(i.getNode()->getValue().type == VALUETYPE_FLAG)
			{
			}
			else
			{
				dstream<<" <value>";
			}
			dstream<<std::endl;

			if(i.getNode()->getValue().help != NULL)
			{
				dstream<<"      "<<i.getNode()->getValue().help
						<<std::endl;
			}
		}

		return cmd_args.getFlag("help") ? 0 : 1;
	}
	
	/*
		Low-level initialization
	*/

	bool disable_stderr = false;
#ifdef _WIN32
	if(cmd_args.getFlag("dstream-on-stderr") == false)
		disable_stderr = true;
#endif
	
	if(cmd_args.getFlag("info-on-stderr"))
		log_add_output(&main_stderr_log_out, LMT_INFO);

	porting::signal_handler_init();
	bool &kill = *porting::signal_handler_killstatus();
	
	// Initialize porting::path_data and porting::path_userdata
	porting::initializePaths();

	// Create user data directory
	fs::CreateDir(porting::path_userdata);

	init_gettext((porting::path_data+DIR_DELIM+".."+DIR_DELIM+"locale").c_str());
	
	// Initialize debug streams
#ifdef RUN_IN_PLACE
	std::string debugfile = DEBUGFILE;
#else
	std::string debugfile = porting::path_userdata+DIR_DELIM+DEBUGFILE;
#endif
	debugstreams_init(disable_stderr, debugfile.c_str());
	// Initialize debug stacks
	debug_stacks_init();

	DSTACK(__FUNCTION_NAME);

	// Init material properties table
	//initializeMaterialProperties();

	// Debug handler
	BEGIN_DEBUG_EXCEPTION_HANDLER

	// Print startup message
	actionstream<<PROJECT_NAME<<
			" with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
			<<", "<<BUILD_INFO
			<<std::endl;
	
	/*
		Basic initialization
	*/

	// Initialize default settings
	set_default_settings(g_settings);
	
	// Initialize sockets
	sockets_init();
	atexit(sockets_cleanup);
	
	/*
		Read config file
	*/
	
	// Path of configuration file in use
	std::string configpath = "";
	
	if(cmd_args.exists("config"))
	{
		bool r = g_settings->readConfigFile(cmd_args.get("config").c_str());
		if(r == false)
		{
			errorstream<<"Could not read configuration from \""
					<<cmd_args.get("config")<<"\""<<std::endl;
			return 1;
		}
		configpath = cmd_args.get("config");
	}
	else
	{
		core::array<std::string> filenames;
		filenames.push_back(porting::path_userdata +
				DIR_DELIM + "minetest.conf");
#ifdef RUN_IN_PLACE
		filenames.push_back(porting::path_userdata +
				DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#endif

		for(u32 i=0; i<filenames.size(); i++)
		{
			bool r = g_settings->readConfigFile(filenames[i].c_str());
			if(r)
			{
				configpath = filenames[i];
				break;
			}
		}
		
		// If no path found, use the first one (menu creates the file)
		if(configpath == "")
			configpath = filenames[0];
	}

	// Initialize random seed
	srand(time(0));
	mysrand(time(0));

	/*
		Run unit tests
	*/

	if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
			|| cmd_args.getFlag("enable-unittests") == true)
	{
		run_tests();
	}
	
	/*for(s16 y=-100; y<100; y++)
	for(s16 x=-100; x<100; x++)
	{
		std::cout<<noise2d_gradient((double)x/10,(double)y/10, 32415)<<std::endl;
	}
	return 0;*/
	
	/*
		Game parameters
	*/

	// Port
	u16 port = 30000;
	if(cmd_args.exists("port"))
		port = cmd_args.getU16("port");
	else if(g_settings->exists("port"))
		port = g_settings->getU16("port");
	if(port == 0)
		port = 30000;
	
	// Map directory
	std::string map_dir = porting::path_userdata+DIR_DELIM+"world";
	if(cmd_args.exists("map-dir"))
		map_dir = cmd_args.get("map-dir");
	else if(g_settings->exists("map-dir"))
		map_dir = g_settings->get("map-dir");
	
	// Run dedicated server if asked to
	if(cmd_args.getFlag("server"))
	{
		DSTACK("Dedicated server branch");

		// Create time getter
		g_timegetter = new SimpleTimeGetter();
		
		// Create server
		Server server(map_dir.c_str(), configpath);
		server.start(port);
		
		// Run server
		dedicated_server_loop(server, kill);

		return 0;
	}


	/*
		More parameters
	*/
	
	// Address to connect to
	std::string address = "";
	
	if(cmd_args.exists("address"))
	{
		address = cmd_args.get("address");
	}
	else
	{
		address = g_settings->get("address");
	}
	
	std::string playername = g_settings->get("name");

	/*
		Device initialization
	*/

	// Resolution selection
	
	bool fullscreen = false;
	u16 screenW = g_settings->getU16("screenW");
	u16 screenH = g_settings->getU16("screenH");

	// Determine driver

	video::E_DRIVER_TYPE driverType;
	
	std::string driverstring = g_settings->get("video_driver");

	if(driverstring == "null")
		driverType = video::EDT_NULL;
	else if(driverstring == "software")
		driverType = video::EDT_SOFTWARE;
	else if(driverstring == "burningsvideo")
		driverType = video::EDT_BURNINGSVIDEO;
	else if(driverstring == "direct3d8")
		driverType = video::EDT_DIRECT3D8;
	else if(driverstring == "direct3d9")
		driverType = video::EDT_DIRECT3D9;
	else if(driverstring == "opengl")
		driverType = video::EDT_OPENGL;
	else
	{
		errorstream<<"WARNING: Invalid video_driver specified; defaulting "
				"to opengl"<<std::endl;
		driverType = video::EDT_OPENGL;
	}

	/*
		Create device and exit if creation failed
	*/

	MyEventReceiver receiver;

	IrrlichtDevice *device;
	device = createDevice(driverType,
			core::dimension2d<u32>(screenW, screenH),
			16, fullscreen, false, false, &receiver);

	if (device == 0)
		return 1; // could not create selected driver.
	
	/*
		Continue initialization
	*/

	video::IVideoDriver* driver = device->getVideoDriver();

	// Disable mipmaps (because some of them look ugly)
	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);

	/*
		This changes the minimum allowed number of vertices in a VBO.
		Default is 500.
	*/
	//driver->setMinHardwareBufferVertexCount(50);

	// Set the window caption
	device->setWindowCaption(L"Minetest [Main Menu]");
	
	// Create time getter
	g_timegetter = new IrrlichtTimeGetter(device);
	
	// Create game callback for menus
	g_gamecallback = new MainGameCallback(device);
	
	/*
		Speed tests (done after irrlicht is loaded to get timer)
	*/
	if(cmd_args.getFlag("speedtests"))
	{
		dstream<<"Running speed tests"<<std::endl;
		SpeedTests();
		return 0;
	}
	
	device->setResizable(true);

	bool random_input = g_settings->getBool("random_input")
			|| cmd_args.getFlag("random-input");
	InputHandler *input = NULL;
	if(random_input)
		input = new RandomInputHandler();
	else
		input = new RealInputHandler(device, &receiver);
	
	scene::ISceneManager* smgr = device->getSceneManager();

	guienv = device->getGUIEnvironment();
	gui::IGUISkin* skin = guienv->getSkin();
	gui::IGUIFont* font = guienv->getFont(getTexturePath("fontlucida.png").c_str());
	if(font)
		skin->setFont(font);
	else
		errorstream<<"WARNING: Font file was not found."
				" Using default font."<<std::endl;
	// If font was not found, this will get us one
	font = skin->getFont();
	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,0,0,0));
	skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255));
	//skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(0,0,0,0));
	//skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(0,0,0,0));
	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));
	
	/*
		GUI stuff
	*/

	/*
		If an error occurs, this is set to something and the
		menu-game loop is restarted. It is then displayed before
		the menu.
	*/
	std::wstring error_message = L"";

	// The password entered during the menu screen,
	std::string password;

	/*
		Menu-game loop
	*/
	while(device->run() && kill == false)
	{

		// This is used for catching disconnects
		try
		{

			/*
				Clear everything from the GUIEnvironment
			*/
			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));
			
			/*
				Out-of-game menu loop.

				Loop quits when menu returns proper parameters.
			*/
			while(kill == false)
			{
				// Cursor can be non-visible when coming from the game
				device->getCursorControl()->setVisible(true);
				// Some stuff are left to scene manager when coming from the game
				// (map at least?)
				smgr->clear();
				// Reset or hide the debug gui texts
				/*guitext->setText(L"Minetest-c55");
				guitext2->setVisible(false);
				guitext_info->setVisible(false);
				guitext_chat->setVisible(false);*/
				
				// Initialize menu data
				MainMenuData menudata;
				menudata.address = narrow_to_wide(address);
				menudata.name = narrow_to_wide(playername);
				menudata.port = narrow_to_wide(itos(port));
				menudata.fancy_trees = g_settings->getBool("new_style_leaves");
				menudata.smooth_lighting = g_settings->getBool("smooth_lighting");
				menudata.clouds_3d = g_settings->getBool("enable_3d_clouds");
				menudata.opaque_water = g_settings->getBool("opaque_water");
				menudata.creative_mode = g_settings->getBool("creative_mode");
				menudata.enable_damage = g_settings->getBool("enable_damage");

				GUIMainMenu *menu =
						new GUIMainMenu(guienv, guiroot, -1, 
							&g_menumgr, &menudata, g_gamecallback);
				menu->allowFocusRemoval(true);

				if(error_message != L"")
				{
					errorstream<<"error_message = "
							<<wide_to_narrow(error_message)<<std::endl;

					GUIMessageMenu *menu2 =
							new GUIMessageMenu(guienv, guiroot, -1, 
								&g_menumgr, error_message.c_str());
					menu2->drop();
					error_message = L"";
				}

				video::IVideoDriver* driver = device->getVideoDriver();
				
				infostream<<"Created main menu"<<std::endl;

				while(device->run() && kill == false)
				{
					if(menu->getStatus() == true)
						break;

					//driver->beginScene(true, true, video::SColor(255,0,0,0));
					driver->beginScene(true, true, video::SColor(255,128,128,128));

					drawMenuBackground(driver);

					guienv->drawAll();
					
					driver->endScene();
					
					// On some computers framerate doesn't seem to be
					// automatically limited
					sleep_ms(25);
				}
				
				// Break out of menu-game loop to shut down cleanly
				if(device->run() == false || kill == true)
					break;
				
				infostream<<"Dropping main menu"<<std::endl;

				menu->drop();
				
				// Delete map if requested
				if(menudata.delete_map)
				{
					bool r = fs::RecursiveDeleteContent(map_dir);
					if(r == false)
						error_message = L"Delete failed";
					continue;
				}

				playername = wide_to_narrow(menudata.name);

				password = translatePassword(playername, menudata.password);

				//infostream<<"Main: password hash: '"<<password<<"'"<<std::endl;

				address = wide_to_narrow(menudata.address);
				int newport = stoi(wide_to_narrow(menudata.port));
				if(newport != 0)
					port = newport;
				g_settings->set("new_style_leaves", itos(menudata.fancy_trees));
				g_settings->set("smooth_lighting", itos(menudata.smooth_lighting));
				g_settings->set("enable_3d_clouds", itos(menudata.clouds_3d));
				g_settings->set("opaque_water", itos(menudata.opaque_water));
				g_settings->set("creative_mode", itos(menudata.creative_mode));
				g_settings->set("enable_damage", itos(menudata.enable_damage));
				
				// NOTE: These are now checked server side; no need to do it
				//       here, so let's not do it here.
				/*// Check for valid parameters, restart menu if invalid.
				if(playername == "")
				{
					error_message = L"Name required.";
					continue;
				}
				// Check that name has only valid chars
				if(string_allowed(playername, PLAYERNAME_ALLOWED_CHARS)==false)
				{
					error_message = L"Characters allowed: "
							+narrow_to_wide(PLAYERNAME_ALLOWED_CHARS);
					continue;
				}*/

				// Save settings
				g_settings->set("name", playername);
				g_settings->set("address", address);
				g_settings->set("port", itos(port));
				// Update configuration file
				if(configpath != "")
					g_settings->updateConfigFile(configpath.c_str());
			
				// Continue to game
				break;
			}
			
			// Break out of menu-game loop to shut down cleanly
			if(device->run() == false || kill == true)
				break;
			
			/*
				Run game
			*/
			the_game(
				kill,
				random_input,
				input,
				device,
				font,
				map_dir,
				playername,
				password,
				address,
				port,
				error_message,
				configpath
			);

		} //try
		catch(con::PeerNotFoundException &e)
		{
			errorstream<<"Connection error (timed out?)"<<std::endl;
			error_message = L"Connection error (timed out?)";
		}
		catch(SocketException &e)
		{
			errorstream<<"Socket error (port already in use?)"<<std::endl;
			error_message = L"Socket error (port already in use?)";
		}
		catch(ModError &e)
		{
			errorstream<<e.what()<<std::endl;
			error_message = narrow_to_wide(e.what()) + L"\nCheck debug.txt for details.";
		}
#ifdef NDEBUG
		catch(std::exception &e)
		{
			std::string narrow_message = "Some exception, what()=\"";
			narrow_message += e.what();
			narrow_message += "\"";
			errorstream<<narrow_message<<std::endl;
			error_message = narrow_to_wide(narrow_message);
		}
#endif

	} // Menu-game loop
	
	delete input;

	/*
		In the end, delete the Irrlicht device.
	*/
	device->drop();
	
	END_DEBUG_EXCEPTION_HANDLER(errorstream)
	
	debugstreams_deinit();
	
	return 0;
}
コード例 #8
0
ファイル: main.cpp プロジェクト: Silenthal/minetest
int main(int argc, char *argv[])
{
	int retval = 0;

	/*
		Initialization
	*/

	log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION);
	log_add_output_all_levs(&main_dstream_no_stderr_log_out);

	log_register_thread("main");

	// Set locale. This is for forcing '.' as the decimal point.
	std::locale::global(std::locale("C"));
	// This enables printing all characters in bitmap font
	setlocale(LC_CTYPE, "en_US");

	/*
		Parse command line
	*/
	
	// List all allowed options
	core::map<std::string, ValueSpec> allowed_options;
	allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG,
			_("Show allowed options")));
	allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,
			_("Load configuration from specified file")));
	allowed_options.insert("port", ValueSpec(VALUETYPE_STRING,
			_("Set network port (UDP)")));
	allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG,
			_("Disable unit tests")));
	allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG,
			_("Enable unit tests")));
	allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING,
			_("Same as --world (deprecated)")));
	allowed_options.insert("world", ValueSpec(VALUETYPE_STRING,
			_("Set world path (implies local game) ('list' lists all)")));
	allowed_options.insert("worldname", ValueSpec(VALUETYPE_STRING,
			_("Set world by name (implies local game)")));
	allowed_options.insert("info", ValueSpec(VALUETYPE_FLAG,
			_("Print more information to console")));
	allowed_options.insert("verbose", ValueSpec(VALUETYPE_FLAG,
			_("Print even more information to console")));
	allowed_options.insert("trace", ValueSpec(VALUETYPE_FLAG,
			_("Print enormous amounts of information to log and console")));
	allowed_options.insert("logfile", ValueSpec(VALUETYPE_STRING,
			_("Set logfile path ('' = no logging)")));
	allowed_options.insert("gameid", ValueSpec(VALUETYPE_STRING,
			_("Set gameid (\"--gameid list\" prints available ones)")));
#ifndef SERVER
	allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG,
			_("Run speed tests")));
	allowed_options.insert("address", ValueSpec(VALUETYPE_STRING,
			_("Address to connect to. ('' = local game)")));
	allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG,
			_("Enable random user input, for testing")));
	allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,
			_("Run dedicated server")));
	allowed_options.insert("name", ValueSpec(VALUETYPE_STRING,
			_("Set player name")));
	allowed_options.insert("password", ValueSpec(VALUETYPE_STRING,
			_("Set password")));
	allowed_options.insert("go", ValueSpec(VALUETYPE_FLAG,
			_("Disable main menu")));
#endif

	Settings cmd_args;
	
	bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options);

	if(ret == false || cmd_args.getFlag("help") || cmd_args.exists("nonopt1"))
	{
		dstream<<_("Allowed options:")<<std::endl;
		for(core::map<std::string, ValueSpec>::Iterator
				i = allowed_options.getIterator();
				i.atEnd() == false; i++)
		{
			std::ostringstream os1(std::ios::binary);
			os1<<"  --"<<i.getNode()->getKey();
			if(i.getNode()->getValue().type == VALUETYPE_FLAG)
				{}
			else
				os1<<_(" <value>");
			dstream<<padStringRight(os1.str(), 24);

			if(i.getNode()->getValue().help != NULL)
				dstream<<i.getNode()->getValue().help;
			dstream<<std::endl;
		}

		return cmd_args.getFlag("help") ? 0 : 1;
	}
	
	/*
		Low-level initialization
	*/
	
	// If trace is enabled, enable logging of certain things
	if(cmd_args.getFlag("trace")){
		dstream<<_("Enabling trace level debug output")<<std::endl;
		log_trace_level_enabled = true;
		dout_con_ptr = &verbosestream; // this is somewhat old crap
		socket_enable_debug_output = true; // socket doesn't use log.h
	}
	// In certain cases, output info level on stderr
	if(cmd_args.getFlag("info") || cmd_args.getFlag("verbose") ||
			cmd_args.getFlag("trace") || cmd_args.getFlag("speedtests"))
		log_add_output(&main_stderr_log_out, LMT_INFO);
	// In certain cases, output verbose level on stderr
	if(cmd_args.getFlag("verbose") || cmd_args.getFlag("trace"))
		log_add_output(&main_stderr_log_out, LMT_VERBOSE);

	porting::signal_handler_init();
	bool &kill = *porting::signal_handler_killstatus();
	
	porting::initializePaths();

	// Create user data directory
	fs::CreateDir(porting::path_user);

	init_gettext((porting::path_share+DIR_DELIM+".."+DIR_DELIM+"locale").c_str());
	
	// Initialize debug streams
#define DEBUGFILE "debug.txt"
#if RUN_IN_PLACE
	std::string logfile = DEBUGFILE;
#else
	std::string logfile = porting::path_user+DIR_DELIM+DEBUGFILE;
#endif
	if(cmd_args.exists("logfile"))
		logfile = cmd_args.get("logfile");
	if(logfile != "")
		debugstreams_init(false, logfile.c_str());
	else
		debugstreams_init(false, NULL);

	infostream<<"logfile    = "<<logfile<<std::endl;
	infostream<<"path_share = "<<porting::path_share<<std::endl;
	infostream<<"path_user  = "******"gameid") && cmd_args.get("gameid") == "list")
	{
		std::set<std::string> gameids = getAvailableGameIds();
		for(std::set<std::string>::const_iterator i = gameids.begin();
				i != gameids.end(); i++)
			dstream<<(*i)<<std::endl;
		return 0;
	}
	
	// List worlds if requested
	if(cmd_args.exists("world") && cmd_args.get("world") == "list"){
		dstream<<_("Available worlds:")<<std::endl;
		std::vector<WorldSpec> worldspecs = getAvailableWorlds();
		print_worldspecs(worldspecs, dstream);
		return 0;
	}
	
	// Print startup message
	infostream<<PROJECT_NAME<<
			" "<<_("with")<<" SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
			<<", "<<BUILD_INFO
			<<std::endl;
	
	/*
		Basic initialization
	*/

	// Initialize default settings
	set_default_settings(g_settings);
	
	// Initialize sockets
	sockets_init();
	atexit(sockets_cleanup);
	
	/*
		Read config file
	*/
	
	// Path of configuration file in use
	std::string configpath = "";
	
	if(cmd_args.exists("config"))
	{
		bool r = g_settings->readConfigFile(cmd_args.get("config").c_str());
		if(r == false)
		{
			errorstream<<"Could not read configuration from \""
					<<cmd_args.get("config")<<"\""<<std::endl;
			return 1;
		}
		configpath = cmd_args.get("config");
	}
	else
	{
		core::array<std::string> filenames;
		filenames.push_back(porting::path_user +
				DIR_DELIM + "minetest.conf");
		// Legacy configuration file location
		filenames.push_back(porting::path_user +
				DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#if RUN_IN_PLACE
		// Try also from a lower level (to aid having the same configuration
		// for many RUN_IN_PLACE installs)
		filenames.push_back(porting::path_user +
				DIR_DELIM + ".." + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#endif

		for(u32 i=0; i<filenames.size(); i++)
		{
			bool r = g_settings->readConfigFile(filenames[i].c_str());
			if(r)
			{
				configpath = filenames[i];
				break;
			}
		}
		
		// If no path found, use the first one (menu creates the file)
		if(configpath == "")
			configpath = filenames[0];
	}

	// Initialize random seed
	srand(time(0));
	mysrand(time(0));

	/*
		Run unit tests
	*/

	if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
			|| cmd_args.getFlag("enable-unittests") == true)
	{
		run_tests();
	}
	
	/*
		Game parameters
	*/

	// Port
	u16 port = 30000;
	if(cmd_args.exists("port"))
		port = cmd_args.getU16("port");
	else if(g_settings->exists("port"))
		port = g_settings->getU16("port");
	if(port == 0)
		port = 30000;
	
	// World directory
	std::string commanded_world = "";
	if(cmd_args.exists("world"))
		commanded_world = cmd_args.get("world");
	else if(cmd_args.exists("map-dir"))
		commanded_world = cmd_args.get("map-dir");
	else if(cmd_args.exists("nonopt0")) // First nameless argument
		commanded_world = cmd_args.get("nonopt0");
	else if(g_settings->exists("map-dir"))
		commanded_world = g_settings->get("map-dir");
	
	// World name
	std::string commanded_worldname = "";
	if(cmd_args.exists("worldname"))
		commanded_worldname = cmd_args.get("worldname");
	
	// Strip world.mt from commanded_world
	{
		std::string worldmt = "world.mt";
		if(commanded_world.size() > worldmt.size() &&
				commanded_world.substr(commanded_world.size()-worldmt.size())
				== worldmt){
			dstream<<_("Supplied world.mt file - stripping it off.")<<std::endl;
			commanded_world = commanded_world.substr(
					0, commanded_world.size()-worldmt.size());
		}
	}
	
	// If a world name was specified, convert it to a path
	if(commanded_worldname != ""){
		// Get information about available worlds
		std::vector<WorldSpec> worldspecs = getAvailableWorlds();
		bool found = false;
		for(u32 i=0; i<worldspecs.size(); i++){
			std::string name = worldspecs[i].name;
			if(name == commanded_worldname){
				if(commanded_world != ""){
					dstream<<_("--worldname takes precedence over previously "
							"selected world.")<<std::endl;
				}
				commanded_world = worldspecs[i].path;
				found = true;
				break;
			}
		}
		if(!found){
			dstream<<_("World")<<" '"<<commanded_worldname<<_("' not "
					"available. Available worlds:")<<std::endl;
			print_worldspecs(worldspecs, dstream);
			return 1;
		}
	}

	// Gamespec
	SubgameSpec commanded_gamespec;
	if(cmd_args.exists("gameid")){
		std::string gameid = cmd_args.get("gameid");
		commanded_gamespec = findSubgame(gameid);
		if(!commanded_gamespec.isValid()){
			errorstream<<"Game \""<<gameid<<"\" not found"<<std::endl;
			return 1;
		}
	}

	/*
		Run dedicated server if asked to or no other option
	*/
#ifdef SERVER
	bool run_dedicated_server = true;
#else
	bool run_dedicated_server = cmd_args.getFlag("server");
#endif
	if(run_dedicated_server)
	{
		DSTACK("Dedicated server branch");
		// Create time getter if built with Irrlicht
#ifndef SERVER
		g_timegetter = new SimpleTimeGetter();
#endif

		// World directory
		std::string world_path;
		verbosestream<<_("Determining world path")<<std::endl;
		bool is_legacy_world = false;
		// If a world was commanded, use it
		if(commanded_world != ""){
			world_path = commanded_world;
			infostream<<"Using commanded world path ["<<world_path<<"]"
					<<std::endl;
		}
		// No world was specified; try to select it automatically
		else
		{
			// Get information about available worlds
			std::vector<WorldSpec> worldspecs = getAvailableWorlds();
			// If a world name was specified, select it
			if(commanded_worldname != ""){
				world_path = "";
				for(u32 i=0; i<worldspecs.size(); i++){
					std::string name = worldspecs[i].name;
					if(name == commanded_worldname){
						world_path = worldspecs[i].path;
						break;
					}
				}
				if(world_path == ""){
					dstream<<_("World")<<" '"<<commanded_worldname<<"' "<<_("not "
							"available. Available worlds:")<<std::endl;
					print_worldspecs(worldspecs, dstream);
					return 1;
				}
			}
			// If there is only a single world, use it
			if(worldspecs.size() == 1){
				world_path = worldspecs[0].path;
				dstream<<_("Automatically selecting world at")<<" ["
						<<world_path<<"]"<<std::endl;
			// If there are multiple worlds, list them
			} else if(worldspecs.size() > 1){
				dstream<<_("Multiple worlds are available.")<<std::endl;
				dstream<<_("Please select one using --worldname <name>"
						" or --world <path>")<<std::endl;
				print_worldspecs(worldspecs, dstream);
				return 1;
			// If there are no worlds, automatically create a new one
			} else {
				// This is the ultimate default world path
				world_path = porting::path_user + DIR_DELIM + "worlds" +
						DIR_DELIM + "world";
				infostream<<"Creating default world at ["
						<<world_path<<"]"<<std::endl;
			}
		}

		if(world_path == ""){
			errorstream<<"No world path specified or found."<<std::endl;
			return 1;
		}
		verbosestream<<_("Using world path")<<" ["<<world_path<<"]"<<std::endl;

		// We need a gamespec.
		SubgameSpec gamespec;
		verbosestream<<_("Determining gameid/gamespec")<<std::endl;
		// If world doesn't exist
		if(!getWorldExists(world_path))
		{
			// Try to take gamespec from command line
			if(commanded_gamespec.isValid()){
				gamespec = commanded_gamespec;
				infostream<<"Using commanded gameid ["<<gamespec.id<<"]"<<std::endl;
			}
			// Otherwise we will be using "minetest"
			else{
				gamespec = findSubgame(g_settings->get("default_game"));
				infostream<<"Using default gameid ["<<gamespec.id<<"]"<<std::endl;
			}
		}
		// World exists
		else
		{
			std::string world_gameid = getWorldGameId(world_path, is_legacy_world);
			// If commanded to use a gameid, do so
			if(commanded_gamespec.isValid()){
				gamespec = commanded_gamespec;
				if(commanded_gamespec.id != world_gameid){
					errorstream<<"WARNING: Using commanded gameid ["
							<<gamespec.id<<"]"<<" instead of world gameid ["
							<<world_gameid<<"]"<<std::endl;
				}
			} else{
				// If world contains an embedded game, use it;
				// Otherwise find world from local system.
				gamespec = findWorldSubgame(world_path);
				infostream<<"Using world gameid ["<<gamespec.id<<"]"<<std::endl;
			}
		}
		if(!gamespec.isValid()){
			errorstream<<"Subgame ["<<gamespec.id<<"] could not be found."
					<<std::endl;
			return 1;
		}
		verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl;

		// Create server
		Server server(world_path, configpath, gamespec, false);
		server.start(port);
		
		// Run server
		dedicated_server_loop(server, kill);

		return 0;
	}

#ifndef SERVER // Exclude from dedicated server build

	/*
		More parameters
	*/
	
	std::string address = g_settings->get("address");
	if(commanded_world != "")
		address = "";
	else if(cmd_args.exists("address"))
		address = cmd_args.get("address");
	
	std::string playername = g_settings->get("name");
	if(cmd_args.exists("name"))
		playername = cmd_args.get("name");
	
	bool skip_main_menu = cmd_args.getFlag("go");

	/*
		Device initialization
	*/

	// Resolution selection
	
	bool fullscreen = g_settings->getBool("fullscreen");
	u16 screenW = g_settings->getU16("screenW");
	u16 screenH = g_settings->getU16("screenH");

	// bpp, fsaa, vsync

	bool vsync = g_settings->getBool("vsync");
	u16 bits = g_settings->getU16("fullscreen_bpp");
	u16 fsaa = g_settings->getU16("fsaa");

	// Determine driver

	video::E_DRIVER_TYPE driverType;
	
	std::string driverstring = g_settings->get("video_driver");

	if(driverstring == "null")
		driverType = video::EDT_NULL;
	else if(driverstring == "software")
		driverType = video::EDT_SOFTWARE;
	else if(driverstring == "burningsvideo")
		driverType = video::EDT_BURNINGSVIDEO;
	else if(driverstring == "direct3d8")
		driverType = video::EDT_DIRECT3D8;
	else if(driverstring == "direct3d9")
		driverType = video::EDT_DIRECT3D9;
	else if(driverstring == "opengl")
		driverType = video::EDT_OPENGL;
	else
	{
		errorstream<<"WARNING: Invalid video_driver specified; defaulting "
				"to opengl"<<std::endl;
		driverType = video::EDT_OPENGL;
	}

	/*
		Create device and exit if creation failed
	*/

	MyEventReceiver receiver;

	IrrlichtDevice *device;

	SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
	params.DriverType    = driverType;
	params.WindowSize    = core::dimension2d<u32>(screenW, screenH);
	params.Bits          = bits;
	params.AntiAlias     = fsaa;
	params.Fullscreen    = fullscreen;
	params.Stencilbuffer = false;
	params.Vsync         = vsync;
	params.EventReceiver = &receiver;

	device = createDeviceEx(params);

	if (device == 0)
		return 1; // could not create selected driver.
	
	/*
		Continue initialization
	*/

	video::IVideoDriver* driver = device->getVideoDriver();

	/*
		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);
	
	/*
		Speed tests (done after irrlicht is loaded to get timer)
	*/
	if(cmd_args.getFlag("speedtests"))
	{
		dstream<<"Running speed tests"<<std::endl;
		SpeedTests();
		return 0;
	}
	
	device->setResizable(true);

	bool random_input = g_settings->getBool("random_input")
			|| cmd_args.getFlag("random-input");
	InputHandler *input = NULL;
	if(random_input)
		input = new RandomInputHandler();
	else
		input = new RealInputHandler(device, &receiver);
	
	scene::ISceneManager* smgr = device->getSceneManager();

	guienv = device->getGUIEnvironment();
	gui::IGUISkin* skin = guienv->getSkin();
	gui::IGUIFont* font = guienv->getFont(getTexturePath("fontlucida.png").c_str());
	if(font)
		skin->setFont(font);
	else
		errorstream<<"WARNING: Font file was not found."
				" Using default font."<<std::endl;
	// If font was not found, this will get us one
	font = skin->getFont();
	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,0,0,0));
	skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255));
	//skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(0,0,0,0));
	//skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(0,0,0,0));
	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

	/*
		GUI stuff
	*/

	ChatBackend chat_backend;

	/*
		If an error occurs, this is set to something and the
		menu-game loop is restarted. It is then displayed before
		the menu.
	*/
	std::wstring error_message = L"";

	// The password entered during the menu screen,
	std::string password;

	bool first_loop = true;

	/*
		Menu-game loop
	*/
	while(device->run() && kill == false)
	{
		// Set the window caption
		device->setWindowCaption((std::wstring(L"Minetest [")+wgettext("Main Menu")+L"]").c_str());

		// This is used for catching disconnects
		try
		{

			/*
				Clear everything from the GUIEnvironment
			*/
			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));
			
			SubgameSpec gamespec;
			WorldSpec worldspec;
			bool simple_singleplayer_mode = false;

			// These are set up based on the menu and other things
			std::string current_playername = "inv£lid";
			std::string current_password = "";
			std::string current_address = "does-not-exist";
			int current_port = 0;

			/*
				Out-of-game menu loop.

				Loop quits when menu returns proper parameters.
			*/
			while(kill == false)
			{
				// If skip_main_menu, only go through here once
				if(skip_main_menu && !first_loop){
					kill = true;
					break;
				}
				first_loop = false;
				
				// Cursor can be non-visible when coming from the game
				device->getCursorControl()->setVisible(true);
				// Some stuff are left to scene manager when coming from the game
				// (map at least?)
				smgr->clear();
				
				// Initialize menu data
				MainMenuData menudata;
				if(g_settings->exists("selected_mainmenu_tab"))
					menudata.selected_tab = g_settings->getS32("selected_mainmenu_tab");
				menudata.address = narrow_to_wide(address);
				menudata.name = narrow_to_wide(playername);
				menudata.port = narrow_to_wide(itos(port));
				if(cmd_args.exists("password"))
					menudata.password = narrow_to_wide(cmd_args.get("password"));
				menudata.fancy_trees = g_settings->getBool("new_style_leaves");
				menudata.smooth_lighting = g_settings->getBool("smooth_lighting");
				menudata.clouds_3d = g_settings->getBool("enable_3d_clouds");
				menudata.opaque_water = g_settings->getBool("opaque_water");
				menudata.mip_map = g_settings->getBool("mip_map");
				menudata.anisotropic_filter = g_settings->getBool("anisotropic_filter");
				menudata.bilinear_filter = g_settings->getBool("bilinear_filter");
				menudata.trilinear_filter = g_settings->getBool("trilinear_filter");
				menudata.enable_shaders = g_settings->getS32("enable_shaders");
				menudata.preload_item_visuals = g_settings->getBool("preload_item_visuals");
				driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, menudata.mip_map);
				menudata.creative_mode = g_settings->getBool("creative_mode");
				menudata.enable_damage = g_settings->getBool("enable_damage");
				// Default to selecting nothing
				menudata.selected_world = -1;
				// Get world listing for the menu
				std::vector<WorldSpec> worldspecs = getAvailableWorlds();
				// If there is only one world, select it
				if(worldspecs.size() == 1){
					menudata.selected_world = 0;
				}
				// Otherwise try to select according to selected_world_path
				else if(g_settings->exists("selected_world_path")){
					std::string trypath = g_settings->get("selected_world_path");
					for(u32 i=0; i<worldspecs.size(); i++){
						if(worldspecs[i].path == trypath){
							menudata.selected_world = i;
							break;
						}
					}
				}
				// If a world was commanded, append and select it
				if(commanded_world != ""){
					std::string gameid = getWorldGameId(commanded_world, true);
					std::string name = _("[--world parameter]");
					if(gameid == ""){
						gameid = g_settings->get("default_game");
						name += " [new]";
					}
					WorldSpec spec(commanded_world, name, gameid);
					worldspecs.push_back(spec);
					menudata.selected_world = worldspecs.size()-1;
				}
				// Copy worldspecs to menu
				menudata.worlds = worldspecs;

				if(skip_main_menu == false)
				{
					video::IVideoDriver* driver = device->getVideoDriver();
					
					infostream<<"Waiting for other menus"<<std::endl;
					while(device->run() && kill == false)
					{
						if(noMenuActive())
							break;
						driver->beginScene(true, true,
								video::SColor(255,128,128,128));
						drawMenuBackground(driver);
						guienv->drawAll();
						driver->endScene();
						// On some computers framerate doesn't seem to be
						// automatically limited
						sleep_ms(25);
					}
					infostream<<"Waited for other menus"<<std::endl;

					GUIMainMenu *menu =
							new GUIMainMenu(guienv, guiroot, -1, 
								&g_menumgr, &menudata, g_gamecallback);
					menu->allowFocusRemoval(true);

					if(error_message != L"")
					{
						verbosestream<<"error_message = "
								<<wide_to_narrow(error_message)<<std::endl;

						GUIMessageMenu *menu2 =
								new GUIMessageMenu(guienv, guiroot, -1, 
									&g_menumgr, error_message.c_str());
						menu2->drop();
						error_message = L"";
					}

					infostream<<"Created main menu"<<std::endl;

					while(device->run() && kill == false)
					{
						if(menu->getStatus() == true)
							break;

						//driver->beginScene(true, true, video::SColor(255,0,0,0));
						driver->beginScene(true, true, video::SColor(255,128,128,128));

						drawMenuBackground(driver);

						guienv->drawAll();
						
						driver->endScene();
						
						// On some computers framerate doesn't seem to be
						// automatically limited
						sleep_ms(25);
					}
					
					infostream<<"Dropping main menu"<<std::endl;

					menu->drop();
				}

				playername = wide_to_narrow(menudata.name);
				password = translatePassword(playername, menudata.password);
				//infostream<<"Main: password hash: '"<<password<<"'"<<std::endl;

				address = wide_to_narrow(menudata.address);
				int newport = stoi(wide_to_narrow(menudata.port));
				if(newport != 0)
					port = newport;
				simple_singleplayer_mode = menudata.simple_singleplayer_mode;
				// Save settings
				g_settings->setS32("selected_mainmenu_tab", menudata.selected_tab);
				g_settings->set("new_style_leaves", itos(menudata.fancy_trees));
				g_settings->set("smooth_lighting", itos(menudata.smooth_lighting));
				g_settings->set("enable_3d_clouds", itos(menudata.clouds_3d));
				g_settings->set("opaque_water", itos(menudata.opaque_water));

				g_settings->set("mip_map", itos(menudata.mip_map));
				g_settings->set("anisotropic_filter", itos(menudata.anisotropic_filter));
				g_settings->set("bilinear_filter", itos(menudata.bilinear_filter));
				g_settings->set("trilinear_filter", itos(menudata.trilinear_filter));

				g_settings->setS32("enable_shaders", menudata.enable_shaders);
				g_settings->set("preload_item_visuals", itos(menudata.preload_item_visuals));

				g_settings->set("creative_mode", itos(menudata.creative_mode));
				g_settings->set("enable_damage", itos(menudata.enable_damage));
				g_settings->set("name", playername);
				g_settings->set("address", address);
				g_settings->set("port", itos(port));
				if(menudata.selected_world != -1)
					g_settings->set("selected_world_path",
							worldspecs[menudata.selected_world].path);
				
				// Break out of menu-game loop to shut down cleanly
				if(device->run() == false || kill == true)
					break;
				
				current_playername = playername;
				current_password = password;
				current_address = address;
				current_port = port;

				// If using simple singleplayer mode, override
				if(simple_singleplayer_mode){
					current_playername = "singleplayer";
					current_password = "";
					current_address = "";
					current_port = 30011;
				}
				
				// Set world path to selected one
				if(menudata.selected_world != -1){
					worldspec = worldspecs[menudata.selected_world];
					infostream<<"Selected world: "<<worldspec.name
							<<" ["<<worldspec.path<<"]"<<std::endl;
				}

				// Only refresh if so requested
				if(menudata.only_refresh){
					infostream<<"Refreshing menu"<<std::endl;
					continue;
				}
				
				// Create new world if requested
				if(menudata.create_world_name != L"")
				{
					std::string path = porting::path_user + DIR_DELIM
							"worlds" + DIR_DELIM
							+ wide_to_narrow(menudata.create_world_name);
					// Create world if it doesn't exist
					if(!initializeWorld(path, menudata.create_world_gameid)){
						error_message = wgettext("Failed to initialize world");
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					g_settings->set("selected_world_path", path);
					continue;
				}

				// If local game
				if(current_address == "")
				{
					if(menudata.selected_world == -1){
						error_message = wgettext("No world selected and no address "
								"provided. Nothing to do.");
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					// Load gamespec for required game
					gamespec = findWorldSubgame(worldspec.path);
					if(!gamespec.isValid() && !commanded_gamespec.isValid()){
						error_message = wgettext("Could not find or load game \"")
								+ narrow_to_wide(worldspec.gameid) + L"\"";
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
					if(commanded_gamespec.isValid() &&
							commanded_gamespec.id != worldspec.gameid){
						errorstream<<"WARNING: Overriding gamespec from \""
								<<worldspec.gameid<<"\" to \""
								<<commanded_gamespec.id<<"\""<<std::endl;
						gamespec = commanded_gamespec;
					}

					if(!gamespec.isValid()){
						error_message = wgettext("Invalid gamespec.");
						error_message += L" (world_gameid="
								+narrow_to_wide(worldspec.gameid)+L")";
						errorstream<<wide_to_narrow(error_message)<<std::endl;
						continue;
					}
				}

				// Continue to game
				break;
			}
			
			// Break out of menu-game loop to shut down cleanly
			if(device->run() == false || kill == true)
				break;

			/*
				Run game
			*/
			the_game(
				kill,
				random_input,
				input,
				device,
				font,
				worldspec.path,
				current_playername,
				current_password,
				current_address,
				current_port,
				error_message,
				configpath,
				chat_backend,
				gamespec,
				simple_singleplayer_mode
			);

		} //try
		catch(con::PeerNotFoundException &e)
		{
			error_message = wgettext("Connection error (timed out?)");
			errorstream<<wide_to_narrow(error_message)<<std::endl;
		}
		catch(ServerError &e)
		{
			error_message = narrow_to_wide(e.what());
			errorstream<<wide_to_narrow(error_message)<<std::endl;
		}
		catch(ModError &e)
		{
			errorstream<<e.what()<<std::endl;
			error_message = narrow_to_wide(e.what()) + wgettext("\nCheck debug.txt for details.");
		}
#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 = 1;
			}
			break;
		}
	} // Menu-game loop
	
	delete input;

	/*
		In the end, delete the Irrlicht device.
	*/
	device->drop();

#endif // !SERVER
	
	// Update configuration file
	if(configpath != "")
		g_settings->updateConfigFile(configpath.c_str());
	
	// Print modified quicktune values
	{
		bool header_printed = false;
		std::vector<std::string> names = getQuicktuneNames();
		for(u32 i=0; i<names.size(); i++){
			QuicktuneValue val = getQuicktuneValue(names[i]);
			if(!val.modified)
				continue;
			if(!header_printed){
				dstream<<"Modified quicktune values:"<<std::endl;
				header_printed = true;
			}
			dstream<<names[i]<<" = "<<val.getString()<<std::endl;
		}
	}

	END_DEBUG_EXCEPTION_HANDLER(errorstream)
	
	debugstreams_deinit();
	
	return retval;
}
コード例 #9
0
/**
 * matecomponent_activation_get_popt_table_name:
 *
 * Get the table name to use for the oaf popt options table when
 * registering with libmate
 * 
 * Return value: A localized copy of the string "matecomponent activation options"
 */
char *
matecomponent_activation_get_popt_table_name (void)
{
	init_gettext (FALSE);
	return _("MateComponent activation options");
}
コード例 #10
0
void
matecomponent_activation_preinit (gpointer app, gpointer mod_info)
{
	init_gettext (FALSE);
}
コード例 #11
0
ファイル: ipa-join.c プロジェクト: jtux270/translate
/*
 * Note, an intention with return values is so that this is compatible with
 * ipa-getkeytab. This is so based on the return value you can distinguish
 * between errors common between the two (no kerbeors ccache) and those
 * unique (host already added).
 */
int
main(int argc, const char **argv) {
    static const char *hostname = NULL;
    static const char *server = NULL;
    static const char *keytab = NULL;
    static const char *bindpw = NULL;
    static const char *basedn = NULL;
    int quiet = 0;
    int unenroll = 0;
    int force = 0;
    struct poptOption options[] = {
        { "debug", 'd', POPT_ARG_NONE, &debug, 0,
          _("Print the raw XML-RPC output in GSSAPI mode"), NULL },
        { "quiet", 'q', POPT_ARG_NONE, &quiet, 0,
          _("Quiet mode. Only errors are displayed."), NULL },
        { "unenroll", 'u', POPT_ARG_NONE, &unenroll, 0,
          _("Unenroll this host from IPA server"), NULL },
        { "hostname", 'h', POPT_ARG_STRING, &hostname, 0,
          _("Hostname of this server"), _("hostname") },
        { "server", 's', POPT_ARG_STRING, &server, 0,
          _("IPA Server to use"), _("hostname") },
        { "keytab", 'k', POPT_ARG_STRING, &keytab, 0,
          _("Specifies where to store keytab information."), _("filename") },
        { "force", 'f', POPT_ARG_NONE, &force, 0,
          _("Force the host join. Rejoin even if already joined."), NULL },
        { "bindpw", 'w', POPT_ARG_STRING, &bindpw, 0,
          _("LDAP password (if not using Kerberos)"), _("password") },
        { "basedn", 'b', POPT_ARG_STRING, &basedn, 0,
          _("LDAP basedn"), _("basedn") },
        POPT_AUTOHELP
        POPT_TABLEEND
    };
    poptContext pc;
    int ret;

    ret = init_gettext();
    if (ret) {
        exit(2);
    }

    pc = poptGetContext("ipa-join", argc, (const char **)argv, options, 0);
    ret = poptGetNextOpt(pc);
    if (ret != -1) {
        if (!quiet) {
            poptPrintUsage(pc, stderr, 0);
        }
        exit(2);
    }
    poptFreeContext(pc);
    if (debug)
        setenv("XMLRPC_TRACE_XML", "1", 1);


    if (!keytab)
        keytab = "/etc/krb5.keytab";

    if (unenroll) {
        ret = unenroll_host(server, hostname, keytab, quiet);
    } else {
        ret = check_perms(keytab);
        if (ret == 0)
            ret = join(server, hostname, bindpw, basedn, keytab, force, quiet);
    }

    exit(ret);
}