PocketMine-MP 5.23.3 git-f7687af337d001ddbcc47b8e773f014a33faa662
Loading...
Searching...
No Matches
SetupWizard.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
29
34use pocketmine\player\GameMode;
42use Symfony\Component\Filesystem\Path;
43use function fgets;
44use function sleep;
45use function strtolower;
46use function trim;
47use const PHP_EOL;
48use const STDIN;
49
52 public const DEFAULT_NAME = Server::DEFAULT_SERVER_NAME;
54 public const DEFAULT_PORT = Server::DEFAULT_PORT_IPV4;
56 public const DEFAULT_PLAYERS = Server::DEFAULT_MAX_PLAYERS;
57
58 private Language $lang;
59
60 public function __construct(
61 private string $dataPath
62 ){}
63
64 public function run() : bool{
65 $this->message(VersionInfo::NAME . " set-up wizard");
66
67 try{
68 $langs = Language::getLanguageList();
70 $this->error("No language files found, please use provided builds or clone the repository recursively.");
71 return false;
72 }
73
74 $this->message("Please select a language");
75 foreach(Utils::stringifyKeys($langs) as $short => $native){
76 $this->writeLine(" $native => $short");
77 }
78
79 do{
80 $lang = strtolower($this->getInput("Language", "eng"));
81 if(!isset($langs[$lang])){
82 $this->error("Couldn't find the language");
83 $lang = null;
84 }
85 }while($lang === null);
86
87 $this->lang = new Language($lang);
88
89 $this->message($this->lang->translate(KnownTranslationFactory::language_has_been_selected()));
90
91 if(!$this->showLicense()){
92 return false;
93 }
94
95 //this has to happen here to prevent user avoiding agreeing to license
96 $config = new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES);
97 $config->set(ServerProperties::LANGUAGE, $lang);
98 $config->save();
99
100 if(strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::skip_installer()), "n", "y/N")) === "y"){
101 $this->printIpDetails();
102 return true;
103 }
104
105 $this->writeLine();
106 $this->welcome();
107
108 $this->generateBaseConfig($config);
109 $this->generateUserFiles($config);
110 $this->networkFunctions($config);
111 $config->save();
112
113 $this->printIpDetails();
114
115 $this->endWizard();
116
117 return true;
118 }
119
120 private function showLicense() : bool{
121 $this->message($this->lang->translate(KnownTranslationFactory::welcome_to_pocketmine(VersionInfo::NAME)));
122 echo <<<LICENSE
123
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.
128
129LICENSE;
130 $this->writeLine();
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)));
133 sleep(5);
134
135 return false;
136 }
137
138 return true;
139 }
140
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()));
145 }
146
147 private function askPort(Translatable $prompt, int $default) : int{
148 while(true){
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()));
152 continue;
153 }
154
155 return $port;
156 }
157 }
158
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)));
161
162 $this->message($this->lang->translate(KnownTranslationFactory::port_warning()));
163
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));
166
167 $this->message($this->lang->translate(KnownTranslationFactory::gamemode_info()));
168
169 do{
170 $input = (int) $this->getInput($this->lang->translate(KnownTranslationFactory::default_gamemode()), "0");
171 $gamemode = match($input){
172 0 => GameMode::SURVIVAL,
173 1 => GameMode::CREATIVE,
174 default => null
175 };
176 }while($gamemode === null);
177 //TODO: this probably shouldn't use the enum name directly
178 $config->set(ServerProperties::GAME_MODE, $gamemode->name);
179
180 $config->set(ServerProperties::MAX_PLAYERS, (int) $this->getInput($this->lang->translate(KnownTranslationFactory::max_players()), (string) Server::DEFAULT_MAX_PLAYERS));
181
182 $config->set(ServerProperties::VIEW_DISTANCE, (int) $this->getInput($this->lang->translate(KnownTranslationFactory::view_distance()), (string) Server::DEFAULT_MAX_VIEW_DISTANCE));
183 }
184
185 private function generateUserFiles(Config $config) : void{
186 $this->message($this->lang->translate(KnownTranslationFactory::op_info()));
187
188 $op = strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::op_who()), ""));
189 if($op === ""){
190 $this->error($this->lang->translate(KnownTranslationFactory::op_warning()));
191 }else{
192 $ops = new Config(Path::join($this->dataPath, "ops.txt"), Config::ENUM);
193 $ops->set($op, true);
194 $ops->save();
195 }
196
197 $this->message($this->lang->translate(KnownTranslationFactory::whitelist_info()));
198
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);
202 }else{
203 $config->set(ServerProperties::WHITELIST, false);
204 }
205 }
206
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);
212 }else{
213 $config->set(ServerProperties::ENABLE_QUERY, true);
214 }
215 }
216
217 private function printIpDetails() : void{
218 $this->message($this->lang->translate(KnownTranslationFactory::ip_get()));
219
220 $externalIP = Internet::getIP();
221 if($externalIP === false){
222 $externalIP = "unknown (server offline)";
223 }
224 try{
225 $internalIP = Internet::getInternalIP();
226 }catch(InternetException $e){
227 $internalIP = "unknown (" . $e->getMessage() . ")";
228 }
229
230 $this->error($this->lang->translate(KnownTranslationFactory::ip_warning($externalIP, $internalIP)));
231 $this->error($this->lang->translate(KnownTranslationFactory::ip_confirm()));
232 $this->readLine();
233 }
234
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)));
239
240 $this->writeLine();
241 $this->writeLine();
242
243 sleep(4);
244 }
245
246 private function writeLine(string $line = "") : void{
247 echo $line . PHP_EOL;
248 }
249
250 private function readLine() : string{
251 return trim((string) fgets(STDIN));
252 }
253
254 private function message(string $message) : void{
255 $this->writeLine("[*] " . $message);
256 }
257
258 private function error(string $message) : void{
259 $this->writeLine("[!] " . $message);
260 }
261
262 private function getInput(string $message, string $default = "", string $options = "") : string{
263 $message = "[?] " . $message;
264
265 if($options !== "" || $default !== ""){
266 $message .= " (" . ($options === "" ? $default : $options) . ")";
267 }
268 $message .= ": ";
269
270 echo $message;
271
272 $input = $this->readLine();
273
274 return $input === "" ? $default : $input;
275 }
276}