60    public function __construct(
 
   61        private string $dataPath
 
   64    public function run() : bool{
 
   65        $this->message(
VersionInfo::NAME . 
" set-up wizard");
 
   68            $langs = Language::getLanguageList();
 
   70            $this->error(
"No language files found, please use provided builds or clone the repository recursively.");
 
   74        $this->message(
"Please select a language");
 
   75        foreach(Utils::stringifyKeys($langs) as $short => $native){
 
   76            $this->writeLine(
" $native => $short");
 
   80            $lang = strtolower($this->getInput(
"Language", 
"eng"));
 
   81            if(!isset($langs[$lang])){
 
   82                $this->error(
"Couldn't find the language");
 
   85        }
while($lang === 
null);
 
   87        $this->lang = 
new Language($lang);
 
   89        $this->message($this->lang->translate(KnownTranslationFactory::language_has_been_selected()));
 
   91        if(!$this->showLicense()){
 
   96        $config = 
new Config(Path::join($this->dataPath, 
"server.properties"), Config::PROPERTIES);
 
   97        $config->set(ServerProperties::LANGUAGE, $lang);
 
  100        if(strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::skip_installer()), 
"n", 
"y/N")) === 
"y"){
 
  101            $this->printIpDetails();
 
  108        $this->generateBaseConfig($config);
 
  109        $this->generateUserFiles($config);
 
  110        $this->networkFunctions($config);
 
  113        $this->printIpDetails();
 
  120    private function showLicense() : bool{
 
  121        $this->message($this->lang->translate(KnownTranslationFactory::welcome_to_pocketmine(VersionInfo::NAME)));
 
  124  This program is free software: you can redistribute it and/or modify
 
  125  it under the terms of the GNU Lesser General Public License as published by
 
  126  the Free Software Foundation, either version 3 of the License, or
 
  127  (at your option) any later version.
 
  131        if(strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::accept_license()), 
"n", 
"y/N")) !== 
"y"){
 
  132            $this->error($this->lang->translate(KnownTranslationFactory::you_have_to_accept_the_license(VersionInfo::NAME)));
 
  141    private function welcome() : void{
 
  142        $this->message($this->lang->translate(KnownTranslationFactory::setting_up_server_now()));
 
  143        $this->message($this->lang->translate(KnownTranslationFactory::default_values_info()));
 
  144        $this->message($this->lang->translate(KnownTranslationFactory::server_properties()));
 
  147    private function askPort(Translatable $prompt, 
int $default) : int{
 
  149            $port = (int) $this->getInput($this->lang->translate($prompt), (
string) $default);
 
  150            if($port <= 0 || $port > 65535){
 
  151                $this->error($this->lang->translate(KnownTranslationFactory::invalid_port()));
 
  159    private function generateBaseConfig(Config $config) : void{
 
  160        $config->set(ServerProperties::MOTD, ($name = $this->getInput($this->lang->translate(KnownTranslationFactory::name_your_server()), Server::DEFAULT_SERVER_NAME)));
 
  162        $this->message($this->lang->translate(KnownTranslationFactory::port_warning()));
 
  164        $config->set(ServerProperties::SERVER_PORT_IPV4, $this->askPort(KnownTranslationFactory::server_port_v4(), Server::DEFAULT_PORT_IPV4));
 
  165        $config->set(ServerProperties::SERVER_PORT_IPV6, $this->askPort(KnownTranslationFactory::server_port_v6(), Server::DEFAULT_PORT_IPV6));
 
  167        $this->message($this->lang->translate(KnownTranslationFactory::gamemode_info()));
 
  170            $input = (int) $this->getInput($this->lang->translate(KnownTranslationFactory::default_gamemode()), 
"0");
 
  171            $gamemode = match($input){
 
  172                0 => GameMode::SURVIVAL,
 
  173                1 => GameMode::CREATIVE,
 
  176        }
while($gamemode === 
null);
 
  178        $config->set(ServerProperties::GAME_MODE, $gamemode->name);
 
  180        $config->set(ServerProperties::MAX_PLAYERS, (
int) $this->getInput($this->lang->translate(KnownTranslationFactory::max_players()), (
string) Server::DEFAULT_MAX_PLAYERS));
 
  182        $config->set(ServerProperties::VIEW_DISTANCE, (
int) $this->getInput($this->lang->translate(KnownTranslationFactory::view_distance()), (
string) Server::DEFAULT_MAX_VIEW_DISTANCE));
 
  185    private function generateUserFiles(Config $config) : void{
 
  186        $this->message($this->lang->translate(KnownTranslationFactory::op_info()));
 
  188        $op = strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::op_who()), 
""));
 
  190            $this->error($this->lang->translate(KnownTranslationFactory::op_warning()));
 
  192            $ops = 
new Config(Path::join($this->dataPath, 
"ops.txt"), Config::ENUM);
 
  193            $ops->set($op, 
true);
 
  197        $this->message($this->lang->translate(KnownTranslationFactory::whitelist_info()));
 
  199        if(strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::whitelist_enable()), 
"n", 
"y/N")) === 
"y"){
 
  200            $this->error($this->lang->translate(KnownTranslationFactory::whitelist_warning()));
 
  201            $config->set(ServerProperties::WHITELIST, 
true);
 
  203            $config->set(ServerProperties::WHITELIST, 
false);
 
  207    private function networkFunctions(Config $config) : void{
 
  208        $this->error($this->lang->translate(KnownTranslationFactory::query_warning1()));
 
  209        $this->error($this->lang->translate(KnownTranslationFactory::query_warning2()));
 
  210        if(strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::query_disable()), 
"n", 
"y/N")) === 
"y"){
 
  211            $config->set(ServerProperties::ENABLE_QUERY, 
false);
 
  213            $config->set(ServerProperties::ENABLE_QUERY, 
true);
 
  217    private function printIpDetails() : void{
 
  218        $this->message($this->lang->translate(KnownTranslationFactory::ip_get()));
 
  220        $externalIP = Internet::getIP();
 
  221        if($externalIP === 
false){
 
  222            $externalIP = 
"unknown (server offline)";
 
  225            $internalIP = Internet::getInternalIP();
 
  226        }
catch(InternetException $e){
 
  227            $internalIP = 
"unknown (" . $e->getMessage() . 
")";
 
  230        $this->error($this->lang->translate(KnownTranslationFactory::ip_warning($externalIP, $internalIP)));
 
  231        $this->error($this->lang->translate(KnownTranslationFactory::ip_confirm()));
 
  235    private function endWizard() : void{
 
  236        $this->message($this->lang->translate(KnownTranslationFactory::you_have_finished()));
 
  237        $this->message($this->lang->translate(KnownTranslationFactory::pocketmine_plugins()));
 
  238        $this->message($this->lang->translate(KnownTranslationFactory::pocketmine_will_start(VersionInfo::NAME)));
 
  246    private function writeLine(
string $line = 
"") : void{
 
  247        echo $line . PHP_EOL;
 
  250    private function readLine() : string{
 
  251        return trim((string) fgets(STDIN));
 
  254    private function message(
string $message) : void{
 
  255        $this->writeLine(
"[*] " . $message);
 
  258    private function error(
string $message) : void{
 
  259        $this->writeLine(
"[!] " . $message);
 
  262    private function getInput(
string $message, 
string $default = 
"", 
string $options = 
"") : string{
 
  263        $message = 
"[?] " . $message;
 
  265        if($options !== 
"" || $default !== 
""){
 
  266            $message .= 
" (" . ($options === 
"" ? $default : $options) . 
")";
 
  272        $input = $this->readLine();
 
  274        return $input === 
"" ? $default : $input;