Пример #1
0
		/* 
		 * /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_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);
					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);
					delete prov;
					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;
				}
		}