bool Mineserver::init() { // expand '~', '~user' in next vars bool error = false; const char* const vars[] = { "system.path.data", "system.path.plugins", "system.path.home", "system.pid_file", }; for (size_t i = 0; i < sizeof(vars) / sizeof(vars[0]); i++) { ConfigNode::Ptr node = config()->mData(vars[i]); if (!node) { LOG2(ERROR, std::string("Variable is missing: ") + vars[i]); error = true; continue; } if (node->type() != CONFIG_NODE_STRING) { LOG2(ERROR, std::string("Variable is not string: ") + vars[i]); error = true; continue; } const std::string newvalue = relativeToAbsolute(node->sData()); node->setData(newvalue); LOG2(INFO, std::string(vars[i]) + " = \"" + newvalue + "\""); } if (error) { return false; } const std::string str = config()->sData("system.path.home"); #ifdef WIN32 if (_chdir(str.c_str()) != 0) #else if (chdir(str.c_str()) != 0) #endif { LOG2(ERROR, "Failed to change working directory to: " + str); return false; } // Write PID to file std::ofstream pid_out((config()->sData("system.pid_file")).c_str()); if (!pid_out.fail()) { #ifdef WIN32 pid_out << _getpid(); #else pid_out << getpid(); #endif } pid_out.close(); // screen::init() needs m_plugin m_plugin = new Plugin; init_plugin_api(); if (config()->bData("system.interface.use_cli")) { // Init our Screen screen()->init(VERSION); } LOG2(INFO, "Welcome to Mineserver v" + VERSION); MapGen* mapgen = new MapGen; MapGen* nethergen = new NetherGen; MapGen* heavengen = new HeavenGen; MapGen* biomegen = new BiomeGen; MapGen* eximgen = new EximGen; m_mapGenNames.push_back(mapgen); m_mapGenNames.push_back(nethergen); m_mapGenNames.push_back(heavengen); m_mapGenNames.push_back(biomegen); m_mapGenNames.push_back(eximgen); m_saveInterval = m_config->iData("map.save_interval"); m_only_helmets = m_config->bData("system.armour.helmet_strict"); m_pvp_enabled = m_config->bData("system.pvp.enabled"); m_damage_enabled = m_config->bData("system.damage.enabled"); const char* key = "map.storage.nbt.directories"; // Prefix for worlds config if (m_config->has(key) && (m_config->type(key) == CONFIG_NODE_LIST)) { std::list<std::string> tmp = m_config->mData(key)->keys(); int n = 0; for (std::list<std::string>::const_iterator it = tmp.begin(); it != tmp.end(); ++it) { m_map.push_back(new Map()); Physics* phy = new Physics; phy->map = n; m_physics.push_back(phy); int k = m_config->iData((std::string(key) + ".") + (*it)); if ((uint32_t)k >= m_mapGenNames.size()) { std::ostringstream s; s << "Error! Mapgen number " << k << " in config. " << m_mapGenNames.size() << " Mapgens known"; LOG2(INFO, s.str()); } // WARNING: if k is too big this will be an access error! -- louisdx MapGen* m = m_mapGenNames[k]; m_mapGen.push_back(m); n++; } } else { LOG2(WARNING, "Cannot find map.storage.nbt.directories.*"); } if (m_map.size() == 0) { LOG2(ERROR, "No worlds in Config!"); return false; } m_chat = new Chat; m_furnaceManager = new FurnaceManager; m_packetHandler = new PacketHandler; m_inventory = new Inventory(m_config->sData("system.path.data") + '/' + "recipes", ".recipe", "ENABLED_RECIPES.cfg"); m_mobs = new Mobs; return true; }
Mineserver::Mineserver(int args, char **argarray) : argv(argarray), argc(args), m_socketlisten (0), m_saveInterval (0), m_lastSave (std::time(NULL)), m_pvp_enabled (false), m_damage_enabled(false), m_only_helmets (false), m_running (false), m_eventBase (NULL), // core modules m_config (new Config()), m_screen (new CliScreen()), m_logger (new Logger()), m_plugin (NULL), m_chat (NULL), m_furnaceManager(NULL), m_packetHandler (NULL), m_inventory (NULL), m_mobs (NULL) { pthread_mutex_init(&m_validation_mutex,NULL); ServerInstance = this; InitSignals(); std::srand((uint32_t)std::time(NULL)); initPRNG(); std::string cfg; std::vector<std::string> overrides; for (int i = 1; i < argc; i++) { const std::string arg(argv[i]); switch (arg[0]) { case '-': // option // we have only '-h' and '--help' now, so just return with help printHelp(0); throw CoreException(); case '+': // override overrides.push_back(arg.substr(1)); break; default: // otherwise, it is config file if (!cfg.empty()) throw CoreException("Only single CONFIG_FILE argument is allowed!"); cfg = arg; break; } } const std::string path_exe = "./"; // If config file is provided as an argument if (!cfg.empty()) { std::cout << "Searching for configuration file..." << std::endl; if (fileExists(cfg)) { const std::pair<std::string, std::string> fullpath = pathOfFile(cfg); cfg = fullpath.first + PATH_SEPARATOR + fullpath.second; this->config()->config_path = fullpath.first; } else { std::cout << "Config not found...\n";; cfg.clear(); } } if (cfg.empty()) { if (fileExists(path_exe + PATH_SEPARATOR + CONFIG_FILE)) { cfg = path_exe + PATH_SEPARATOR + CONFIG_FILE; this->config()->config_path = path_exe; } else { std::cout << "Config not found\n"; } } // load config Config &configvar = *this->config(); if (!configvar.load(cfg)) { throw CoreException("Could not load config!"); } m_plugin = new Plugin(); LOG2(INFO, "Using config: " + cfg); if (overrides.size()) { std::stringstream override_config; for (size_t i = 0; i < overrides.size(); i++) { LOG2(INFO, "Overriden: " + overrides[i]); override_config << overrides[i] << ';' << std::endl; } // override config if (!configvar.load(override_config)) throw CoreException("Error when parsing overrides: maybe you forgot to doublequote string values?"); } memset(&m_listenEvent, 0, sizeof(event)); initConstants(); // Write PID to file std::ofstream pid_out((config()->sData("system.pid_file")).c_str()); if (!pid_out.fail()) { pid_out << getpid(); } pid_out.close(); init_plugin_api(); if (config()->bData("system.interface.use_cli")) { // Init our Screen screen()->init(VERSION); } LOG2(INFO, "Welcome to Mineserver v" + VERSION); LOG2(INFO, "Using zlib "+std::string(ZLIB_VERSION)+" libevent "+std::string(event_get_version())); LOG2(INFO, "Generating RSA key pair for protocol encryption"); //Protocol encryption srand(microTime()); if((rsa = RSA_generate_key(1024, 17, 0, 0)) == NULL) { LOG2(INFO, "KEY GENERATION FAILED!"); exit(1); } LOG2(INFO, "RSA key pair generated."); /* Get ASN.1 format public key */ x=X509_new(); pk=EVP_PKEY_new(); EVP_PKEY_assign_RSA(pk,rsa); X509_set_version(x,0); X509_set_pubkey(x,pk); int len; unsigned char *buf; buf = NULL; len = i2d_X509(x, &buf); //Glue + jesus tape, dont ask - Fador publicKey = std::string((char *)(buf+28),len-36); OPENSSL_free(buf); /* END key fetching */ const std::string temp_nums="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890=-"; const std::string temp_hex="0123456789abcdef"; for(int i = 0; i < 4; i++) { encryptionBytes += (char)(temp_nums[rand()%temp_nums.size()]); } for(int i = 0; i < 16; i++) { serverID += (char)(temp_hex[rand()%temp_hex.size()]); } LOG2(INFO, "ServerID: " + serverID); if(!m_config->bData("system.user_validation")) { serverID = "-"; } MapGen* mapgen = new MapGen(); MapGen* nethergen = new NetherGen(); MapGen* heavengen = new HeavenGen(); MapGen* biomegen = new BiomeGen(); MapGen* eximgen = new EximGen(); m_mapGenNames.push_back(mapgen); m_mapGenNames.push_back(nethergen); m_mapGenNames.push_back(heavengen); m_mapGenNames.push_back(biomegen); m_mapGenNames.push_back(eximgen); m_saveInterval = m_config->iData("map.save_interval"); m_only_helmets = m_config->bData("system.armour.helmet_strict"); m_pvp_enabled = m_config->bData("system.pvp.enabled"); m_damage_enabled = m_config->bData("system.damage.enabled"); const char* key = "map.storage.nbt.directories"; // Prefix for worlds config if (m_config->has(key) && (m_config->type(key) == CONFIG_NODE_LIST)) { std::list<std::string> tmp = m_config->mData(key)->keys(); int n = 0; for (std::list<std::string>::const_iterator it = tmp.begin(); it != tmp.end(); ++it) { m_map.push_back(new Map()); Physics* phy = new Physics; phy->map = n; m_physics.push_back(phy); RedstoneSimulation* red = new RedstoneSimulation; red->map = n; m_redstone.push_back(red); int k = m_config->iData((std::string(key) + ".") + (*it)); if ((uint32_t)k >= m_mapGenNames.size()) { std::ostringstream s; s << "Error! Mapgen number " << k << " in config. " << m_mapGenNames.size() << " Mapgens known"; LOG2(INFO, s.str()); } // WARNING: if k is too big this will be an access error! -- louisdx MapGen* m = m_mapGenNames[k]; m_mapGen.push_back(m); n++; } } else { LOG2(WARNING, "Cannot find map.storage.nbt.directories.*"); } if (m_map.size() == 0) throw CoreException("No worlds in Config"); m_chat = new Chat; m_furnaceManager = new FurnaceManager; m_packetHandler = new PacketHandler; m_inventory = new Inventory(m_config->sData("system.path.data") + '/' + "recipes", ".recipe", "ENABLED_RECIPES.cfg"); m_mobs = new Mobs; } // End Mineserver constructor