/* * /help - * * When executed without any arguments, the command displays general tips, * tricks and hints about what the player can do in the server. Otherwise, * it displays detailed information about the supplied command. * * Permissions: * - command.info.help * To execute the command. */ void c_help::execute (player *pl, command_reader& reader) { if (!pl->perm ("command.info.help")) return; // we handle --help and --summary ourselves, instead of passing the work // to the command reader. reader.add_option ("help", "h", true); reader.add_option ("summary", "s"); if (!reader.parse (this, pl, false)) return; if (reader.opt ("summary")->found () && reader.no_args ()) { this->show_summary (pl); return; } else if (reader.opt ("help")->found ()) { auto& opt = *reader.opt ("help"); if (opt.got_args ()) { auto& arg = opt.arg (0); if (!arg.is_int ()) { pl->message ("§c * §7Invalid page number§: §c" + arg.as_str ()); return; } int page = arg.as_int (); this->show_help (pl, page, 12); } else this->show_help (pl, 1, 12); return; } if (reader.arg_count () > 2) { this->show_summary (pl); return; } else if (reader.arg_count () > 0) { command *cmd = pl->get_server ().get_commands ().find (reader.arg (0).c_str ()); if (!cmd || !pl->has (cmd->get_exec_permission ())) { pl->message ("§c * §7Unable to find help for§f: §c" + reader.arg (0)); return; } if (reader.opt ("summary")->found ()) cmd->show_summary (pl); int page = 1; if (reader.arg_count () == 2) { if (!sutils::is_int (reader.arg (1))) { pl->message ("§c * §7Invalid page number§: §c" + reader.arg (1)); return; } page = sutils::to_int (reader.arg (1)); } cmd->show_help (pl, page, 12); return; } for (const std::string& str : pl->get_server ().msgs.help) pl->message (messages::compile (str, messages::environment (pl))); }
/* * /ping - * * Displays to the player how much time it takes for the server to both * send and retreive a single keep alive (ping: 0x00) packet (in ms). * * Permissions: * - command.misc.ping * Needed to execute the command. */ void c_ping::execute (player *pl, command_reader& reader) { if (!pl->perm ("command.misc.ping")) return; if (!reader.parse (this, pl)) return; if (reader.arg_count () > 1) { this->show_summary (pl); return; } if (reader.has_args ()) { player *target = pl->get_server ().get_players ().find (reader.arg (0).c_str ()); if (!target) { pl->message ("§c * §7No such player §f: §c" + reader.arg (0) + "§f."); return; } std::ostringstream ss; ss << "§a" << target->get_username () << "§e's ping§f: §c" << target->get_ping () << " §emilliseconds§f."; pl->message (ss.str ()); return; } std::ostringstream ss; ss << "§ePing§f: §c" << pl->get_ping () << " §emilliseconds§f."; pl->message (ss.str ()); }
/* * /wunload - * * Saves and removes a requested world from the server's online world world * list, optionally removing it from the autoload list as well. * * Permissions: * - command.world.wunload * Needed to execute the command. */ void c_wunload::execute (player *pl, command_reader& reader) { if (!pl->perm ("command.world.wunload")) return; reader.add_option ("autoload", "a"); if (!reader.parse (this, pl)) return; if (reader.no_args () || reader.arg_count () > 1) { this->show_summary (pl); return; } std::string world_name = reader.arg (0); world *wr = pl->get_server ().find_world (world_name.c_str ()); if (!wr) { if (reader.opt ("autoload")->found ()) { if (remove_from_autoload (pl->get_server (), world_name)) pl->message ("§eWorld §b" + world_name + " §ehas been removed from the autoload list§f."); else pl->message ("§cWorld §7" + world_name + " §cis not in the autoload list§7."); } else pl->message ("§c * §7World §b" + world_name + " §7is not loaded§f."); return; } else if (wr == pl->get_server ().get_main_world ()) { pl->message ("§c * §7You can not unload the main world§f!"); return; } world_name.assign (wr->get_name ()); // transfer all players to the server's main world. std::vector<player *> to_transfer; wr->get_players ().populate (to_transfer); for (player *pl : to_transfer) pl->join_world (pl->get_server ().get_main_world ()); pl->get_server ().remove_world (wr); if (reader.opt ("autoload")->found ()) { if (remove_from_autoload (pl->get_server (), world_name)) pl->message ("§eWorld §b" + world_name + " §ehas been removed from the autoload list§f."); else pl->message ("§cWorld §7" + world_name + " §cis not in the autoload list§7."); } pl->get_server ().get_players ().message ( "§cWorld §4" + world_name + " §chas been unloaded§c!"); }
/* * /wload - * * Loads a world from disk onto the server's world list. Doing this enables * players to go to that world using /w. * * Permissions: * - command.world.wload * Needed to execute the command. */ void c_wload::execute (player *pl, command_reader& reader) { if (!pl->perm ("command.world.wload")) return; reader.add_option ("autoload", "a"); if (!reader.parse_args (this, pl)) return; if (reader.no_args () || reader.arg_count () > 1) { this->show_usage (pl); return; } std::string& world_name = reader.arg (0); world *twr = pl->get_server ().find_world (world_name.c_str ()); if (twr) { if (reader.opt ("autoload")->found ()) { if (add_to_autoload (pl->get_server (), world_name)) pl->message ("§eWorld §b" + world_name + " §ehas been added to the autoload list§f."); else pl->message ("§cWorld §7" + world_name + " §cis already autoloaded§7."); } else pl->message ("§c * §eWorld §b" + world_name + " §eis already loaded§f."); return; } std::string prov_name = world_provider::determine ("worlds", world_name.c_str ()); if (prov_name.empty ()) { pl->message ("§c * §eWorld §b" + world_name + " §edoes not exist§f."); return; } world_provider *prov = world_provider::create (prov_name.c_str (), "worlds", world_name.c_str ()); if (!prov) { pl->message ("§c * ERROR§f: §eInvalid provider§f."); return; } const world_information& winf = prov->info (); world_generator *gen = world_generator::create (winf.generator.c_str (), winf.seed); if (!gen) { pl->message ("§c * ERROR§f: §eInvalid generator§f."); return; } pl->get_logger () () << "Loading world \"" << world_name << "\"" << std::endl; world *wr = new world (world_name.c_str (), gen, prov); wr->set_size (winf.width, winf.depth); wr->prepare_spawn (10); wr->start (); if (!pl->get_server ().add_world (wr)) { pl->get_logger () (LT_ERROR) << "Failed to load world \"" << world_name << "\": Already loaded." << std::endl; pl->message ("§c * ERROR§f: §eFailed to load world§f."); delete wr; return; } // add to autoload list if (reader.opt ("autoload")->found ()) { if (add_to_autoload (pl->get_server (), world_name)) pl->message ("§eWorld §b" + world_name + " §ehas been added to the autoload list§f."); else pl->message ("§cWorld §7" + world_name + " §cis already autoloaded§7."); } wr->start (); pl->get_server ().get_players ().message ( "§a * §6World §a" + world_name + " §6has been loaded§f."); }
/* * /wcreate - * * Creates a new world, and if requested, loads it into the current world * list. * * Permissions: * - command.world.wcreate * Needed to execute the command. */ void c_wcreate::execute (player *pl, command_reader& reader) { if (!pl->perm ("command.world.wcreate")) return; reader.add_option ("load", "l"); reader.add_option ("width", "w", true, true); reader.add_option ("depth", "d", true, true); reader.add_option ("provider", "p", true, true); reader.add_option ("generator", "g", true, true); reader.add_option ("seed", "s", true, true); if (!reader.parse (this, pl)) return; if (reader.no_args () || reader.arg_count () > 1) { this->show_summary (pl); return; } //---- /* * Parse arguments: */ // world name std::string& world_name = reader.arg (0); if (!world::is_valid_name (world_name.c_str ())) { pl->message ("§c * §eWorld names must be under §a32 §echaracters long and " "may only contain alpha§f-§enumeric characters§f, §edots§f, " "§ehyphens and underscores§f."); return; } // world width int world_width = 0; auto opt_width = reader.opt ("width"); if (opt_width->found ()) { auto& arg = opt_width->arg (0); if (!arg.is_int ()) { pl->message ("§c * §eArgument to flag §c--width §emust be an integer§f."); return; } world_width = arg.as_int (); if (world_width < 0) world_width = 0; } // world depth int world_depth = 0; auto opt_depth = reader.opt ("depth"); if (opt_depth->found ()) { auto& arg = opt_depth->arg (0); if (!arg.is_int ()) { pl->message ("§c * §eArgument to flag §c--depth §emust be an integer§f."); return; } world_depth = arg.as_int (); if (world_depth < 0) world_depth = 0; } // world provider std::string provider_name ("hw"); auto opt_prov = reader.opt ("provider"); if (opt_prov->found ()) { auto& arg = opt_prov->arg (0); provider_name.assign (arg.as_str ()); } // world generator std::string gen_name ("flatgrass"); auto opt_gen = reader.opt ("generator"); if (opt_gen->found ()) { auto& arg = opt_gen->arg (0); gen_name.assign (arg.as_str ()); } // generator seed int gen_seed = std::chrono::duration_cast<std::chrono::milliseconds> ( std::chrono::high_resolution_clock::now ().time_since_epoch ()).count () & 0x7FFFFFFF; auto opt_seed = reader.opt ("seed"); if (opt_seed->found ()) { auto& arg = opt_seed->arg (0); if (arg.is_int ()) gen_seed = arg.as_int (); else gen_seed = std::hash<std::string> () (arg.as_str ()) & 0x7FFFFFFF; } // load world bool load_world = reader.opt ("load")->found (); //---- if (load_world && (pl->get_server ().find_world (world_name.c_str ()) != nullptr)) { pl->message ("§c * §eA world with the same name is already loaded§f."); return; } world_generator *gen = world_generator::create (gen_name.c_str (), gen_seed); if (!gen) { pl->message ("§c * §eInvalid world generator§f: §c" + gen_name); return; } world_provider *prov = world_provider::create (provider_name.c_str (), "data/worlds", world_name.c_str ()); if (!prov) { pl->message ("§c * §eInvalid world provider§f: §c" + provider_name); delete gen; return; } { std::ostringstream ss; pl->message ("§eCreating a new world with the name of §a" + world_name + "§f:"); ss << "§eWorld dimensions§f: §c"; if (world_width == 0) ss << "§binf"; else ss << "§a" << world_width; ss << " §ex §a256 §ex "; if (world_depth == 0) ss << "§binf"; else ss << "§a" << world_depth; pl->message (ss.str ()); ss.clear (); ss.str (std::string ()); if ((world_width == 0) || (world_depth == 0)) ss << "§eEstimated size §f(§ewhen full§f): §cinfinite"; else { double est_kb = ((world_width * world_depth) / 256) * 7.2375 + 49.7; ss.clear (); ss.str (std::string ()); ss << "§eEstimated size §f(§ewhen full§f): §c~"; if (est_kb >= 1024.0) ss << (est_kb / 1024.0) << "MB"; else ss << est_kb << "KB"; } pl->message (ss.str ()); ss.clear (); ss.str (std::string ()); ss << "§eGenerator§f: §b" << gen_name << "§f, §eProvider§f: §b" << provider_name; pl->message (ss.str ()); ss.clear (); ss.str (std::string ()); ss << "§eWorld seed§f: §a" << gen_seed; pl->message (ss.str ()); } world *wr = new world (pl->get_server (), world_name.c_str (), pl->get_logger (), gen, prov); wr->set_width (world_width); wr->set_depth (world_depth); wr->prepare_spawn (10, true); wr->save_all (); if (load_world) { if (!pl->get_server ().add_world (wr)) { delete wr; pl->message ("§cFailed to load world§7."); } wr->start (); pl->get_server ().get_players ().message ( "§3World §b" + world_name + " §3has been loaded§b!"); } else { delete wr; } }