PageRenderTime 27ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Plugins/WorldManager/src/MineBlock/WorldManager/WorldManager.php

https://gitlab.com/Skull3x/MineBlock
PHP | 431 lines | 416 code | 15 blank | 0 comment | 77 complexity | dfd453c473fd94f03156dd1b263ede74 MD5 | raw file
  1. <?php
  2. namespace MineBlock\WorldManager;
  3. use pocketmine\plugin\PluginBase;
  4. use pocketmine\command\Command;
  5. use pocketmine\command\CommandSender;
  6. use pocketmine\event\Listener;
  7. use pocketmine\utils\Config;
  8. use pocketmine\utils\TextFormat;
  9. use pocketmine\event\block\BlockBreakEvent;
  10. use pocketmine\event\block\BlockPlaceEvent;
  11. use pocketmine\event\player\PlayerInteractEvent;
  12. use pocketmine\level\Position;
  13. use pocketmine\Player;
  14. use pocketmine\level\generator\Generator;
  15. use pocketmine\event\player\PlayerDeathEvent;
  16. use pocketmine\event\entity\EntityDamageEvent;
  17. use pocketmine\event\entity\EntityDamageByEntityEvent;
  18. use pocketmine\entity\Arrow;
  19. class WorldManager extends PluginBase implements Listener{
  20. public function onEnable(){
  21. $this->getServer()->getPluginManager()->registerEvents($this, $this);
  22. $this->loadYml();
  23. $this->loadWorlds();
  24. }
  25. public function onCommand(CommandSender $sender, Command $cmd, $label, array $sub){
  26. $ik = $this->isKorean();
  27. $rm = TextFormat::RED . "Usage: /";
  28. $wm = $this->wm;
  29. switch(strtolower($cmd->getName())){
  30. case "worldmanager":
  31. if(!isset($sub[0])) return false;
  32. $mm = "[WorldManager] ";
  33. $rm .= "WorldManager ";
  34. switch(strtolower($sub[0])){
  35. case "generate":
  36. case "generator":
  37. case "g":
  38. case "생성":
  39. case "add":
  40. case "a":
  41. case "추가":
  42. if(!isset($sub[1])){
  43. $r = $rm . ($ik ? "생성 <이름> <타입> <시드>": "Generate <Name> <Type> <Seed>");
  44. }else{
  45. $seed = isset($sub[3]) ? $sub[3]: null;
  46. $gn = $this->getServer()->getLevelType();
  47. $this->getServer()->setConfigString("level-type", isset($sub[2]) ? $sub[2]: null);
  48. $this->getServer()->generateLevel(strtolower($sub[1]), $seed);
  49. $this->getServer()->setConfigString("level-type", $gn);
  50. $r = $mm . ($ik ? "월드가 생성되었습니다. 월드명: ": "World is generate. World: ") . strtolower($sub[1]);
  51. }
  52. break;
  53. case "load":
  54. case "l":
  55. case "로딩":
  56. case "로드":
  57. case "불러오기":
  58. if(!isset($sub[1])){
  59. $r = $rm . ($ik ? "로드 <이름>": "Load <Name>");
  60. }else{
  61. $ln = strtolower($sub[1]);
  62. if(!$this->getServer()->loadLevel($ln)){
  63. $r = $mm . $ln . ($ik ? "는 잘못된 월드명입니다.": "is invalid world name");
  64. }else{
  65. $wm["Load"][$ln] = true;
  66. $r = $mm . ($ik ? "$ln 월드를 로딩햇습니다.": "Load $ln world");
  67. }
  68. }
  69. break;
  70. case "list":
  71. case "목록":
  72. $page = 1;
  73. if(isset($sub[0]) && is_numeric($sub[0])) $page = max(floor($sub[0]), 1);
  74. $list = array_chunk($this->getServer()->getLevels(), 5, true);
  75. if($page >= ($c = count($list))) $page = $c;
  76. $r = $mm . ($ik ? "월드 목록 (페이지": "World List (Page") . " $page/$c) \n";
  77. $num = ($page - 1) * 5;
  78. if($c > 0){
  79. foreach($list[$page - 1] as $v){
  80. $num++;
  81. $r .= " [$num] " . $v->getName() . " : " . $v->getFolderName() . "\n";
  82. }
  83. }
  84. break;
  85. case "spawn":
  86. case "s":
  87. case "스폰":
  88. $wm["MainSpawn"] = !$wm["MainSpawn"];
  89. $r = $mm . ($wm["MainSpawn"] ? ($ik ? "스폰시 메인월드에서 스폰합니다.": "Main spawn is On"): ($ik ? "스폰시 해당 월드에서 스폰합니다.": "Main spawn is off"));
  90. break;
  91. default:
  92. return false;
  93. break;
  94. }
  95. break;
  96. case "worldprotect":
  97. if(!isset($sub[0])) return false;
  98. $mm = "[WorldProtect] ";
  99. $rm .= "WorldProtect ";
  100. $wp = $wm["Protect"];
  101. switch(strtolower($sub[0])){
  102. case "add":
  103. case "a":
  104. case "추가":
  105. if(!isset($sub[1]) || !$sub[1]){
  106. $r = $rm . ($ik ? "추가 <월드명>": "Add(A) <WorldName>");
  107. }else{
  108. $w = strtolower($sub[1]);
  109. if(!in_array($w, $wp)) $wp[] = $w;
  110. $r = $mm . ($ik ? " 추가됨 ": "Add") . " : $w";
  111. }
  112. break;
  113. case "del":
  114. case "d":
  115. case "삭제":
  116. case "제거":
  117. if(!isset($sub[1])){
  118. $r = $rm . ($ik ? "제거 <월드명>": "Del(D) <WorldName>");
  119. }else{
  120. $w = strtolower($sub[1]);
  121. if(!in_array($w, $wp)){
  122. $r = " [$w] " . ($ik ? "목록에 존재하지 않습니다.\n $rm 목록 ": "does not exist.\n $rm List(L)");
  123. }else{
  124. foreach($wp as $k => $v){
  125. if($v == $w){
  126. unset($wp[$k]);
  127. $r = $mm . ($ik ? " 제거됨 ": "Del") . " : $w";
  128. break;
  129. }
  130. }
  131. }
  132. }
  133. break;
  134. case "reset":
  135. case "r":
  136. case "리셋":
  137. case "초기화":
  138. $wp = [];
  139. $r = $mm . ($ik ? " 리셋됨.": " Reset");
  140. break;
  141. case "list":
  142. case "l":
  143. case "목록":
  144. case "리스트":
  145. $page = 1;
  146. if(isset($sub[0]) && is_numeric($sub[0])) $page = max(floor($sub[0]), 1);
  147. $list = array_chunk($wp, 5, true);
  148. if($page >= ($c = count($list))) $page = $c;
  149. $r = $mm . ($ik ? "월드보호 목록 (페이지": "WorldProtect List (Page") . " $page/$c) \n";
  150. $num = ($page - 1) * 5;
  151. if($c > 0){
  152. foreach($list[$page - 1] as $v){
  153. $num++;
  154. $r .= " [$num] $v\n";
  155. }
  156. }
  157. break;
  158. default:
  159. return false;
  160. break;
  161. }
  162. $wm["Protect"] = $wp;
  163. break;
  164. case "worldpvp":
  165. if(!isset($sub[0])) return false;
  166. $mm = "[WorldPVP] ";
  167. $rm .= "WorldPVP ";
  168. $wpvp = $wm["PVP"];
  169. switch(strtolower($sub[0])){
  170. case "add":
  171. case "a":
  172. case "추가":
  173. if(!isset($sub[1]) || !$sub[1]){
  174. $r = $rm . ($ik ? "추가 <월드명>": "Add(A) <WorldName>");
  175. }else{
  176. $w = strtolower($sub[1]);
  177. if(!in_array($w, $wpvp)) $wpvp[] = $w;
  178. $r = $mm . ($ik ? " 추가됨 ": "Add") . " : $w";
  179. }
  180. break;
  181. case "del":
  182. case "d":
  183. case "삭제":
  184. case "제거":
  185. if(!isset($sub[1])){
  186. $r = $rm . ($ik ? "제거 <월드명>": "Del(D) <WorldName>");
  187. }else{
  188. $w = strtolower($sub[1]);
  189. if(!in_array($w, $wpvp)){
  190. $r = " [$w] " . ($ik ? "목록에 존재하지 않습니다.\n $rm 목록 ": "does not exist.\n $rm List(L)");
  191. }else{
  192. foreach($wpvp as $k => $v){
  193. if($v == $w){
  194. unset($wpvp[$k]);
  195. $r = $mm . ($ik ? " 제거됨 ": "Del") . " : $w";
  196. break;
  197. }
  198. }
  199. }
  200. }
  201. break;
  202. case "reset":
  203. case "r":
  204. case "리셋":
  205. case "초기화":
  206. $wpvp = [];
  207. $r = $mm . ($ik ? " 리셋됨.": " Reset");
  208. break;
  209. case "list":
  210. case "l":
  211. case "목록":
  212. case "리스트":
  213. $page = 1;
  214. if(isset($sub[0]) && is_numeric($sub[0])) $page = max(floor($sub[0]), 1);
  215. $list = array_chunk($wpvp, 5, true);
  216. if($page >= ($c = count($list))) $page = $c;
  217. $r = $mm . ($ik ? "PVP 월드 목록 (페이지": "PVP World List (Page") . " $page/$c) \n";
  218. $num = ($page - 1) * 5;
  219. if($c > 0){
  220. foreach($list[$page - 1] as $v){
  221. $num++;
  222. $r .= " [$num] $v\n";
  223. }
  224. }
  225. break;
  226. default:
  227. return false;
  228. break;
  229. }
  230. $wm["PVP"] = $wpvp;
  231. break;
  232. case "worldinv":
  233. if(!isset($sub[0])) return false;
  234. $mm = "[WorldInv] ";
  235. $rm .= "WorldInv ";
  236. $winv = $wm["Inv"];
  237. switch(strtolower($sub[0])){
  238. case "add":
  239. case "a":
  240. case "추가":
  241. if(!isset($sub[1]) || !$sub[1]){
  242. $r = $rm . ($ik ? "추가 <월드명>": "Add(A) <WorldName>");
  243. }else{
  244. $w = strtolower($sub[1]);
  245. if(!in_array($w, $winv)) $winv[] = $w;
  246. $r = $mm . ($ik ? " 추가됨 ": "Add") . " : $w";
  247. }
  248. break;
  249. case "del":
  250. case "d":
  251. case "삭제":
  252. case "제거":
  253. if(!isset($sub[1])){
  254. $r = $rm . ($ik ? "제거 <월드명>": "Del(D) <WorldName>");
  255. }else{
  256. $w = strtolower($sub[1]);
  257. if(!in_array($w, $winv)){
  258. $r = " [$w] " . ($ik ? "목록에 존재하지 않습니다.\n $rm 목록 ": "does not exist.\n $rm List(L)");
  259. }else{
  260. foreach($winv as $k => $v){
  261. if($v == $w){
  262. unset($winv[$k]);
  263. $r = $mm . ($ik ? " 제거됨 ": "Del") . " : $w";
  264. break;
  265. }
  266. }
  267. }
  268. }
  269. break;
  270. case "reset":
  271. case "r":
  272. case "리셋":
  273. case "초기화":
  274. $winv = [];
  275. $r = $mm . ($ik ? " 리셋됨.": " Reset");
  276. break;
  277. case "list":
  278. case "l":
  279. case "목록":
  280. case "리스트":
  281. $page = 1;
  282. if(isset($sub[0]) && is_numeric($sub[0])) $page = max(floor($sub[0]), 1);
  283. $list = array_chunk($winv, 5, true);
  284. if($page >= ($c = count($list))) $page = $c;
  285. $r = $mm . ($ik ? "인벤세이브 월드 목록 (페이지": "InventorySave World List (Page") . " $page/$c) \n";
  286. $num = ($page - 1) * 5;
  287. if($c > 0){
  288. foreach($list[$page - 1] as $v){
  289. $num++;
  290. $r .= " [$num] $v\n";
  291. }
  292. }
  293. break;
  294. default:
  295. return false;
  296. break;
  297. }
  298. $wm["Inv"] = $winv;
  299. break;
  300. case "setspawn":
  301. if(isset($sub[0]) && $player = $this->getServer()->getPlayer($sub[0]))
  302. ;
  303. else $player = $sender;
  304. $ln = strtolower($player->getLevel()->getFolderName());
  305. $wm["Spawn"][$ln] = $player->x . ":" . $player->y . ":" . $player->z;
  306. $r = "[SetSpawn] " . ($ik ? "스폰 설정되었습니다. 월드명: $ln , 좌표: ": "Spawn set. World: $ln , Position: ") . $wm["Spawn"][$ln];
  307. break;
  308. case "spawn":
  309. if($wm["MainSpawn"]) $world = $this->getServer()->getDefaultLevel();
  310. else $world = $sender->getLevel();
  311. $sender->teleport($world->getSpawn());
  312. $r = "[Spawn] " . ($ik ? "스폰으로 텔레포트되었습니다. 월드명: ": "Teleport to spawn. World: ") . $world->getFolderName();
  313. break;
  314. }
  315. if(isset($r)) $sender->sendMessage($r);
  316. if($this->wm !== $wm){
  317. $this->wm = $wm;
  318. $this->saveYml();
  319. }
  320. $this->loadWorlds();
  321. return true;
  322. }
  323. public function onPlayerDeath(PlayerDeathEvent $event){
  324. if(in_array(strtolower($event->getEntity()->getLevel()->getFolderName()), $this->wm["Inv"])) $event->setKeepInventory(true);
  325. }
  326. public function onEntityDamage(EntityDamageEvent $event){
  327. $p = $event->getEntity();
  328. if($event->isCancelled() || !$p instanceof Player || $event->getCause() > 11) return;
  329. $w = strtolower($p->getLevel()->getFolderName());
  330. if($event instanceof EntityDamageByEntityEvent){
  331. if(!in_array($w, $this->wm["PVP"])){
  332. $dmg = $event->getDamager();
  333. if($dmg instanceof Player){
  334. if(!$dmg->hasPermission("mineblock.worldmanager.worldpvp.pvp")){
  335. $event->setCancelled();
  336. $dmg->sendMessage("[PVP Manager] PVP 권한이 없습니다.");
  337. }
  338. }
  339. }
  340. }
  341. }
  342. public function onBlockBreak(BlockBreakEvent $event){
  343. if(!$event->isCancelled()) $this->OnBlockEvent($event);
  344. }
  345. public function onBlockPlace(BlockPlaceEvent $event){
  346. if(!$event->isCancelled()) $this->onBlockEvent($event);
  347. }
  348. public function onPlayerInteract(PlayerInteractEvent $event){
  349. if(!$event->isCancelled()) $this->onBlockEvent($event);
  350. }
  351. public function onBlockEvent($event){
  352. if(in_array(strtolower($event->getBlock()->getLevel()->getFolderName()), $this->wm["Protect"]) && !$event->getPlayer()->hasPermission("mineblock.worldmanager.worldprotect.block")){
  353. $event->getPlayer()->sendMessage("[WorldProtect] " . ($this->isKorean() ? "이 월드는 보호상태입니다.": "This world is protected"));
  354. $event->setCancelled();
  355. }
  356. }
  357. public function getLevelByName($name){
  358. $levels = $this->getServer()->getLevels();
  359. foreach($levels as $l){
  360. if(strtolower($l->getFolderName()) == strtolower($name)) return $l;
  361. }
  362. foreach($levels as $l){
  363. if(strtolower($l->getName()) == strtolower($name)) return $l;
  364. }
  365. if($this->getServer()->loadLevel($name) != false) return $this->getServer()->getLevelByName($name);
  366. return false;
  367. }
  368. public function loadWorlds(){
  369. $wm = $this->wm;
  370. foreach($wm["Load"] as $l => $b){
  371. if(!($level = $this->getLevelByName($l))){
  372. unset($wm["Load"][$l]);
  373. }else{
  374. if($b){
  375. $this->getServer()->loadLevel($l);
  376. }else{
  377. $this->getServer()->unloadLevel($level);
  378. }
  379. }
  380. }
  381. foreach($this->getServer()->getLevels() as $l){
  382. $ln = strtolower($l->getFolderName());
  383. if(!isset($wm["Load"][$ln])) $wm["Load"][$ln] = true;
  384. if(!isset($wm["Spawn"][$ln])){
  385. $s = $l->getSafeSpawn();
  386. $wm["Spawn"][$ln] = floor($s->x) . ":" . floor($s->y) . ":" . floor($s->z);
  387. }
  388. }
  389. if($this->wm !== $wm){
  390. $this->wm = $wm;
  391. $this->saveYml();
  392. }
  393. foreach($this->wm["Spawn"] as $k => $v){
  394. if(!$l = $this->getLevelByName($k)) continue;
  395. $s = explode(":", $v);
  396. $l->setSpawn(new Position($s[0], $s[1], $s[2], $l));
  397. }
  398. }
  399. public function loadYml(){
  400. @mkdir($this->getServer()->getDataPath() . "/plugins/! MineBlock/");
  401. $this->wm = (new Config($this->getServer()->getDataPath() . "/plugins/! MineBlock/" . "WorldManager.yml", Config::YAML, ["MainSpawn" => true,"Load" => [],"Spawn" => [],"Protect" => [],"PVP" => [],"Inv" => []]))->getAll();
  402. }
  403. public function saveYml(){
  404. ksort($this->wm["Load"]);
  405. ksort($this->wm["Spawn"]);
  406. sort($this->wm["Protect"]);
  407. $wm = new Config($this->getServer()->getDataPath() . "/plugins/! MineBlock/" . "WorldManager.yml", Config::YAML);
  408. $wm->setAll($this->wm);
  409. $wm->save();
  410. }
  411. public function isKorean(){
  412. @mkdir($this->getServer()->getDataPath() . "/plugins/! MineBlock/");
  413. if(!isset($this->ik)) $this->ik = (new Config($this->getServer()->getDataPath() . "/plugins/! MineBlock/" . "! Korean.yml", Config::YAML, ["Korean" => false]))->get("Korean");
  414. return $this->ik;
  415. }
  416. }