From d5eaa13227e934747365fa3cc7e6f95d4ef4ed40 Mon Sep 17 00:00:00 2001 From: zOmArRD Date: Mon, 21 Feb 2022 16:58:00 -0400 Subject: [PATCH] Plugin for PM4 (Fixed Version) --- src/Frago9876543210/EasyForms/EasyForms.php | 59 ++++ .../EasyForms/ServerSettingsRequestEvent.php | 42 +++ .../EasyForms/elements/Button.php | 46 +++ .../EasyForms/elements/Dropdown.php | 70 ++++ .../EasyForms/elements/Element.php | 74 +++++ .../EasyForms/elements/Image.php | 47 +++ .../EasyForms/elements/Input.php | 73 +++++ .../EasyForms/elements/Label.php | 30 ++ .../EasyForms/elements/Slider.php | 109 +++++++ .../EasyForms/elements/StepSlider.php | 25 ++ .../EasyForms/elements/Toggle.php | 64 ++++ .../EasyForms/forms/CustomForm.php | 76 +++++ .../EasyForms/forms/CustomFormResponse.php | 96 ++++++ src/Frago9876543210/EasyForms/forms/Form.php | 85 +++++ .../EasyForms/forms/MenuForm.php | 92 ++++++ .../EasyForms/forms/ModalForm.php | 74 +++++ .../EasyForms/forms/ServerSettingsForm.php | 43 +++ src/falkirks/minereset/Mine.php | 302 +++++++++--------- src/falkirks/minereset/MineManager.php | 298 ++++++++++------- src/falkirks/minereset/MineReset.php | 104 +++--- .../minereset/ResetProgressManager.php | 51 +-- .../minereset/command/AboutCommand.php | 19 -- .../minereset/command/CreateCommand.php | 42 ++- .../minereset/command/DestroyCommand.php | 75 +++-- .../minereset/command/EditCommand.php | 40 +-- .../minereset/command/ListCommand.php | 21 +- .../minereset/command/MineCommand.php | 56 ++-- .../minereset/command/ReportCommand.php | 24 +- .../minereset/command/ResetAllCommand.php | 18 +- .../minereset/command/ResetCommand.php | 40 +-- src/falkirks/minereset/command/SetCommand.php | 54 ++-- src/falkirks/minereset/command/SubCommand.php | 23 +- .../exception/InvalidBlockStringException.php | 1 - .../exception/InvalidStateException.php | 1 - .../exception/MineResetException.php | 4 +- .../minereset/listener/CreationListener.php | 84 ++--- .../listener/MineCreationSession.php | 100 +++--- .../listener/RegionBlockerListener.php | 91 +++--- .../minereset/store/AbstractStore.php | 20 +- src/falkirks/minereset/store/ConfigStore.php | 56 ++-- src/falkirks/minereset/store/DataStore.php | 30 +- src/falkirks/minereset/store/EntityStore.php | 20 +- src/falkirks/minereset/store/Reloadable.php | 4 +- src/falkirks/minereset/store/Saveable.php | 3 +- src/falkirks/minereset/task/AboutPullTask.php | 47 --- src/falkirks/minereset/task/ResetTask.php | 104 +++--- .../minereset/util/BlockStringParser.php | 41 +-- .../minereset/util/DebugDumpFactory.php | 32 +- 48 files changed, 2055 insertions(+), 855 deletions(-) create mode 100644 src/Frago9876543210/EasyForms/EasyForms.php create mode 100644 src/Frago9876543210/EasyForms/ServerSettingsRequestEvent.php create mode 100644 src/Frago9876543210/EasyForms/elements/Button.php create mode 100644 src/Frago9876543210/EasyForms/elements/Dropdown.php create mode 100644 src/Frago9876543210/EasyForms/elements/Element.php create mode 100644 src/Frago9876543210/EasyForms/elements/Image.php create mode 100644 src/Frago9876543210/EasyForms/elements/Input.php create mode 100644 src/Frago9876543210/EasyForms/elements/Label.php create mode 100644 src/Frago9876543210/EasyForms/elements/Slider.php create mode 100644 src/Frago9876543210/EasyForms/elements/StepSlider.php create mode 100644 src/Frago9876543210/EasyForms/elements/Toggle.php create mode 100644 src/Frago9876543210/EasyForms/forms/CustomForm.php create mode 100644 src/Frago9876543210/EasyForms/forms/CustomFormResponse.php create mode 100644 src/Frago9876543210/EasyForms/forms/Form.php create mode 100644 src/Frago9876543210/EasyForms/forms/MenuForm.php create mode 100644 src/Frago9876543210/EasyForms/forms/ModalForm.php create mode 100644 src/Frago9876543210/EasyForms/forms/ServerSettingsForm.php delete mode 100644 src/falkirks/minereset/command/AboutCommand.php delete mode 100644 src/falkirks/minereset/task/AboutPullTask.php diff --git a/src/Frago9876543210/EasyForms/EasyForms.php b/src/Frago9876543210/EasyForms/EasyForms.php new file mode 100644 index 0000000..5af4f88 --- /dev/null +++ b/src/Frago9876543210/EasyForms/EasyForms.php @@ -0,0 +1,59 @@ +getServer()->getPluginManager()->registerEvents($this, $this); + } + + /** + * @throws \JsonException + */ + private function sendSetting(Player $player, CustomForm $form) : void{ + $reflection = new ReflectionObject($player); + + $idProperty = $reflection->getProperty("formIdCounter"); //TODO: sync it with SOF3 PR + $idProperty->setAccessible(true); + $id = $idProperty->getValue($player); + + $idProperty->setValue($player, ++$id); + $id--; + + $pk = new ServerSettingsResponsePacket(); + $pk->formId = $id; + $pk->formData = json_encode($form, JSON_THROW_ON_ERROR); + if($player->getNetworkSession()->sendDataPacket($pk)){ + $formsProperty = $reflection->getProperty("forms"); + $formsProperty->setAccessible(true); + + $formsValue = $formsProperty->getValue($player); + $formsValue[$id] = $form; + + $formsProperty->setValue($player, $formsValue); + } + } + + /** + * @throws \JsonException + */ + public function onDataPacketReceive(DataPacketReceiveEvent $e) : void{ + $pk = $e->getPacket(); + if($pk instanceof ServerSettingsRequestPacket){ + ($ev = new ServerSettingsRequestEvent($player = $e->getOrigin()->getPlayer()))->call(); + if(($form = $ev->getForm()) !== null){ + $this->sendSetting($player, $form); + } + } + } +} diff --git a/src/Frago9876543210/EasyForms/ServerSettingsRequestEvent.php b/src/Frago9876543210/EasyForms/ServerSettingsRequestEvent.php new file mode 100644 index 0000000..0408aa7 --- /dev/null +++ b/src/Frago9876543210/EasyForms/ServerSettingsRequestEvent.php @@ -0,0 +1,42 @@ +player = $player; + } + + /** + * @return Player + */ + public function getPlayer() : Player{ + return $this->player; + } + + /** + * @return CustomForm|null + */ + public function getForm() : ?CustomForm{ + return $this->form; + } + + /** + * @param CustomForm|null $form + */ + public function setForm(?CustomForm $form) : void{ + $this->form = $form; + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/elements/Button.php b/src/Frago9876543210/EasyForms/elements/Button.php new file mode 100644 index 0000000..ed05d94 --- /dev/null +++ b/src/Frago9876543210/EasyForms/elements/Button.php @@ -0,0 +1,46 @@ +image = $image; + } + + /** + * @return string|null + */ + public function getType() : ?string{ + return null; + } + + /** + * @return bool + */ + public function hasImage() : bool{ + return $this->image !== null; + } + + /** + * @return array + */ + public function serializeElementData() : array{ + $data = ["text" => $this->text]; + if($this->hasImage()){ + $data["image"] = $this->image; + } + return $data; + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/elements/Dropdown.php b/src/Frago9876543210/EasyForms/elements/Dropdown.php new file mode 100644 index 0000000..620ba05 --- /dev/null +++ b/src/Frago9876543210/EasyForms/elements/Dropdown.php @@ -0,0 +1,70 @@ +options = $options; + $this->default = $default; + } + + /** + * @return array + */ + public function getOptions() : array{ + return $this->options; + } + + /** + * @return string + */ + public function getSelectedOption() : string{ + return $this->options[$this->value]; + } + + /** + * @return int + */ + public function getDefault() : int{ + return $this->default; + } + + /** + * @return string + */ + public function getType() : string{ + return "dropdown"; + } + + /** + * @return array + */ + public function serializeElementData() : array{ + return [ + "options" => $this->options, + "default" => $this->default + ]; + } + + public function validate($value) : void{ + parent::validate($value); + if(!isset($this->options[$value])){ + throw new FormValidationException("Option with index $value does not exist in dropdown"); + } + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/elements/Element.php b/src/Frago9876543210/EasyForms/elements/Element.php new file mode 100644 index 0000000..e39d1c5 --- /dev/null +++ b/src/Frago9876543210/EasyForms/elements/Element.php @@ -0,0 +1,74 @@ +text = $text; + } + + /** + * @return mixed + */ + public function getValue(){ + return $this->value; + } + + /** + * @param mixed $value + */ + public function setValue($value){ + $this->value = $value; + } + + /** + * @return array + */ + final public function jsonSerialize() : array{ + $array = ["text" => $this->getText()]; + if($this->getType() !== null){ + $array["type"] = $this->getType(); + } + return $array + $this->serializeElementData(); + } + + /** + * @return string + */ + public function getText() : string{ + return $this->text; + } + + /** + * @return string|null + */ + abstract public function getType() : ?string; + + /** + * @return array + */ + abstract public function serializeElementData() : array; + + /** + * @param mixed $value + */ + public function validate($value) : void{ + if(!is_int($value)){ + throw new FormValidationException("Expected int, got " . gettype($value)); + } + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/elements/Image.php b/src/Frago9876543210/EasyForms/elements/Image.php new file mode 100644 index 0000000..6fbc81f --- /dev/null +++ b/src/Frago9876543210/EasyForms/elements/Image.php @@ -0,0 +1,47 @@ +type = $type; + $this->data = $data; + } + + /** + * @return string + */ + public function getType() : string{ + return $this->type; + } + + /** + * @return string + */ + public function getData() : string{ + return $this->data; + } + + public function jsonSerialize() : array{ + return [ + "type" => $this->type, + "data" => $this->data + ]; + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/elements/Input.php b/src/Frago9876543210/EasyForms/elements/Input.php new file mode 100644 index 0000000..9b829ed --- /dev/null +++ b/src/Frago9876543210/EasyForms/elements/Input.php @@ -0,0 +1,73 @@ +placeholder = $placeholder; + $this->default = $default; + } + + /** + * @return string + */ + public function getValue() : string{ + return parent::getValue(); + } + + /** + * @return string + */ + public function getPlaceholder() : string{ + return $this->placeholder; + } + + /** + * @return string + */ + public function getDefault() : string{ + return $this->default; + } + + /** + * @return string + */ + public function getType() : string{ + return "input"; + } + + /** + * @return array + */ + public function serializeElementData() : array{ + return [ + "placeholder" => $this->placeholder, + "default" => $this->default + ]; + } + + /** + * @param $value + */ + public function validate($value) : void{ + if(!is_string($value)){ + throw new FormValidationException("Expected string, got " . gettype($value)); + } + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/elements/Label.php b/src/Frago9876543210/EasyForms/elements/Label.php new file mode 100644 index 0000000..be8b3a1 --- /dev/null +++ b/src/Frago9876543210/EasyForms/elements/Label.php @@ -0,0 +1,30 @@ +min > $this->max){ + throw new InvalidArgumentException("Slider min value should be less than max value"); + } + $this->min = $min; + $this->max = $max; + if($default !== null){ + if($default > $this->max or $default < $this->min){ + throw new InvalidArgumentException("Default must be in range $this->min ... $this->max"); + } + $this->default = $default; + }else{ + $this->default = $this->min; + } + if($step <= 0){ + throw new InvalidArgumentException("Step must be greater than zero"); + } + $this->step = $step; + } + + /** + * @return float|int + */ + public function getValue(){ + return parent::getValue(); + } + + /** + * @return float + */ + public function getMin() : float{ + return $this->min; + } + + /** + * @return float + */ + public function getMax() : float{ + return $this->max; + } + + /** + * @return float + */ + public function getStep() : float{ + return $this->step; + } + + /** + * @return float + */ + public function getDefault() : float{ + return $this->default; + } + + /** + * @return string + */ + public function getType() : string{ + return "slider"; + } + + /** + * @return array + */ + public function serializeElementData() : array{ + return [ + "min" => $this->min, + "max" => $this->max, + "default" => $this->default, + "step" => $this->step + ]; + } + + public function validate($value) : void{ + if(!is_int($value) && !is_float($value)){ + throw new FormValidationException("Expected int or float, got " . gettype($value)); + } + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/elements/StepSlider.php b/src/Frago9876543210/EasyForms/elements/StepSlider.php new file mode 100644 index 0000000..1544e5d --- /dev/null +++ b/src/Frago9876543210/EasyForms/elements/StepSlider.php @@ -0,0 +1,25 @@ + $this->getOptions(), + "default" => $this->getDefault() + ]; + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/elements/Toggle.php b/src/Frago9876543210/EasyForms/elements/Toggle.php new file mode 100644 index 0000000..d582315 --- /dev/null +++ b/src/Frago9876543210/EasyForms/elements/Toggle.php @@ -0,0 +1,64 @@ +default = $default; + } + + /** + * @return bool + */ + public function getValue() : bool{ + return parent::getValue(); + } + + /** + * @return bool + */ + public function hasChanged() : bool{ + return $this->default !== $this->value; + } + + /** + * @return bool + */ + public function getDefault() : bool{ + return $this->default; + } + + /** + * @return string + */ + public function getType() : string{ + return "toggle"; + } + + /** + * @return array + */ + public function serializeElementData() : array{ + return [ + "default" => $this->default + ]; + } + + /** + * @param $value + */ + public function validate($value) : void{ + if(!is_bool($value)){ + throw new FormValidationException("Expected bool, got " . gettype($value)); + } + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/forms/CustomForm.php b/src/Frago9876543210/EasyForms/forms/CustomForm.php new file mode 100644 index 0000000..cd3d062 --- /dev/null +++ b/src/Frago9876543210/EasyForms/forms/CustomForm.php @@ -0,0 +1,76 @@ +elements = $elements; + $this->onSubmit($onSubmit); + if($onClose !== null){ + $this->onClose($onClose); + } + } + + /** + * @return string + */ + protected function getType() : string{ + return self::TYPE_CUSTOM_FORM; + } + + /** + * @return callable + */ + protected function getOnSubmitCallableSignature() : callable{ + return function(Player $player, CustomFormResponse $response) : void{}; + } + + /** + * @return array + */ + protected function serializeFormData() : array{ + return ["content" => $this->elements]; + } + + /** + * @param Element ...$elements + * @return self + */ + public function append(Element ...$elements) : self{ + $this->elements = array_merge($this->elements, $elements); + return $this; + } + + final public function handleResponse(Player $player, $data) : void{ + if($data === null){ + if($this->onClose !== null){ + ($this->onClose)($player); + } + }elseif(is_array($data)){ + foreach($data as $index => $value){ + if(!isset($this->elements[$index])){ + throw new FormValidationException("Element at index $index does not exist"); + } + $element = $this->elements[$index]; + $element->validate($value); + $element->setValue($value); + } + ($this->onSubmit)($player, new CustomFormResponse($this->elements)); + }else{ + throw new FormValidationException("Expected array or null, got " . gettype($data)); + } + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/forms/CustomFormResponse.php b/src/Frago9876543210/EasyForms/forms/CustomFormResponse.php new file mode 100644 index 0000000..f316ec9 --- /dev/null +++ b/src/Frago9876543210/EasyForms/forms/CustomFormResponse.php @@ -0,0 +1,96 @@ +elements = $elements; + } + + /** + * @internal + * + * @param string $expected + * + * @return Element|mixed + */ + public function tryGet(string $expected = Element::class){ //why PHP still hasn't templates??? + if (($element = array_shift($this->elements)) instanceof Label) { + return $this->tryGet($expected); //remove useless element + } + + if(!($element instanceof $expected)) { + throw new FormValidationException("Expected a element with of type $expected, got " . get_class($element)); + } + return $element; + } + + /** + * @return Dropdown + */ + public function getDropdown() : Dropdown{ + return $this->tryGet(Dropdown::class); + } + + /** + * @return Input + */ + public function getInput() : Input{ + return $this->tryGet(Input::class); + } + + /** + * @return Slider + */ + public function getSlider() : Slider{ + return $this->tryGet(Slider::class); + } + + /** + * @return StepSlider + */ + public function getStepSlider() : StepSlider{ + return $this->tryGet(StepSlider::class); + } + + /** + * @return Toggle + */ + public function getToggle() : Toggle{ + return $this->tryGet(Toggle::class); + } + + /** + * @return Element[] + */ + public function getElements() : array{ + return $this->elements; + } + + /** + * @return mixed[] + */ + public function getValues() : array{ + $values = []; + foreach($this->elements as $element){ + if($element instanceof Label){ + continue; + } + $values[] = $element instanceof Dropdown ? $element->getSelectedOption() : $element->getValue(); + } + return $values; + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/forms/Form.php b/src/Frago9876543210/EasyForms/forms/Form.php new file mode 100644 index 0000000..1bf0d04 --- /dev/null +++ b/src/Frago9876543210/EasyForms/forms/Form.php @@ -0,0 +1,85 @@ +title = $title; + } + + /** + * @param string $title + * @return self + */ + public function setTitle(string $title) : self{ + $this->title = $title; + return $this; + } + + /** + * @return string + */ + abstract protected function getType() : string; + + /** + * @return callable + */ + abstract protected function getOnSubmitCallableSignature() : callable; + + /** + * @return array + */ + abstract protected function serializeFormData() : array; + + /** + * @param Closure $onSubmit + * @return self + */ + public function onSubmit(Closure $onSubmit) : self{ + Utils::validateCallableSignature($this->getOnSubmitCallableSignature(), $onSubmit); + $this->onSubmit = $onSubmit; + return $this; + } + + /** + * @param Closure $onClose + * @return self + */ + public function onClose(Closure $onClose) : self{ + Utils::validateCallableSignature(function(Player $player) : void{}, $onClose); + $this->onClose = $onClose; + return $this; + } + + /** + * @return array + */ + final public function jsonSerialize() : array{ + return array_merge( + ["title" => $this->title, "type" => $this->getType()], + $this->serializeFormData() + ); + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/forms/MenuForm.php b/src/Frago9876543210/EasyForms/forms/MenuForm.php new file mode 100644 index 0000000..33cd932 --- /dev/null +++ b/src/Frago9876543210/EasyForms/forms/MenuForm.php @@ -0,0 +1,92 @@ +content = $content; + $this->append(...$buttons); + if($onSubmit !== null){ + $this->onSubmit($onSubmit); + } + if($onClose !== null){ + $this->onClose($onClose); + } + } + + /** + * @return string + */ + protected function getType() : string{ + return self::TYPE_MENU; + } + + /** + * @return callable + */ + protected function getOnSubmitCallableSignature() : callable{ + return function(Player $player, Button $selected) : void{}; + } + + /** + * @return array + */ + protected function serializeFormData() : array{ + return [ + "buttons" => $this->buttons, + "content" => $this->content + ]; + } + + /** + * @param Button|string ...$buttons + * @return self + */ + public function append(...$buttons) : self{ + if(isset($buttons[0])){ + if(is_string($buttons[0])){ + $buttons = array_map(function(string $text) : Button{ return new Button($text); }, $buttons); + }else{ + (function(Button ...$_){})(...$buttons); + } + } + $this->buttons = array_merge($this->buttons, $buttons); + return $this; + } + + final public function handleResponse(Player $player, $data) : void{ + if($data === null){ + if($this->onClose !== null){ + ($this->onClose)($player); + } + }elseif(is_int($data)){ + if(!isset($this->buttons[$data])){ + throw new FormValidationException("Button with index $data does not exist"); + } + if($this->onSubmit !== null){ + $button = $this->buttons[$data]; + $button->setValue($data); + ($this->onSubmit)($player, $button); + } + }else{ + throw new FormValidationException("Expected int or null, got " . gettype($data)); + } + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/forms/ModalForm.php b/src/Frago9876543210/EasyForms/forms/ModalForm.php new file mode 100644 index 0000000..4b391ce --- /dev/null +++ b/src/Frago9876543210/EasyForms/forms/ModalForm.php @@ -0,0 +1,74 @@ +content = $content; + $this->onSubmit($onSubmit); + $this->yesButton = $yesButton; + $this->noButton = $noButton; + } + + public static function confirm(string $title, string $text, Closure $onConfirm) : self{ + Utils::validateCallableSignature(function(Player $player) : void{}, $onConfirm); + return new self($title, $text, function(Player $player, bool $response) use ($onConfirm): void{ + if($response){ + $onConfirm($player); + } + }); + } + + /** + * @return string + */ + protected function getType() : string{ + return self::TYPE_MODAL; + } + + /** + * @return callable + */ + protected function getOnSubmitCallableSignature() : callable{ + return function(Player $player, bool $response) : void{}; + } + + /** + * @return array + */ + protected function serializeFormData() : array{ + return [ + "content" => $this->content, + "button1" => $this->yesButton, + "button2" => $this->noButton + ]; + } + + final public function handleResponse(Player $player, $data) : void{ + if($data === null){ + if($this->onClose !== null){ + ($this->onClose)($player); + } + }elseif(is_bool($data)){ + ($this->onSubmit)($player, $data); + }else{ + throw new FormValidationException("Expected bool or null, got " . gettype($data)); + } + } +} \ No newline at end of file diff --git a/src/Frago9876543210/EasyForms/forms/ServerSettingsForm.php b/src/Frago9876543210/EasyForms/forms/ServerSettingsForm.php new file mode 100644 index 0000000..e765bdc --- /dev/null +++ b/src/Frago9876543210/EasyForms/forms/ServerSettingsForm.php @@ -0,0 +1,43 @@ +image = $image; + } + + /** + * @return bool + */ + public function hasImage() : bool{ + return $this->image !== null; + } + + /** + * @return array + */ + public function serializeFormData() : array{ + $data = parent::serializeFormData(); + if($this->hasImage()){ + $data["icon"] = $this->image; + } + return $data; + } +} \ No newline at end of file diff --git a/src/falkirks/minereset/Mine.php b/src/falkirks/minereset/Mine.php index 4865c2b..440cec4 100644 --- a/src/falkirks/minereset/Mine.php +++ b/src/falkirks/minereset/Mine.php @@ -1,4 +1,5 @@ pointA = $pointA; $this->pointB = $pointB; $this->level = $levelName; @@ -66,19 +52,18 @@ public function __construct(MineManager $api, $this->isResetting = false; - - if($this->isValid()) { + if ($this->isValid()) { $this->register(); - } - else{ - $api->getApi()->getLogger()->warning("MineReset has detected corruption of the mines.yml file in mine with name {$this->name}, MineReset will not reset this mine."); + } else { + $api->getApi()->getLogger()->warning("MineReset has detected corruption of the mines.yml file in mine with name $this->name, MineReset will not reset this mine."); } } - public function isValid() : bool { - foreach ($this->data as $id => $percent){ - if(!BlockStringParser::isValid($id) || !is_numeric($percent)){ + public function isValid(): bool + { + foreach ($this->data as $id => $percent) { + if (!BlockStringParser::isValid($id)) { return false; } } @@ -89,46 +74,130 @@ public function isValid() : bool { /** * INTERNAL USE ONLY */ - public function register(){ - if($this->getHandler() === null && $this->resetInterval > 0){ + public function register(): void + { + if ($this->getHandler() === null && $this->resetInterval > 0) { $this->getApi()->getApi()->getScheduler()->scheduleRepeatingTask($this, 20 * $this->resetInterval); } } /** - * INTERNAL USE ONLY + * @return MineManager */ - public function destroy(){ - if($this->getHandler() !== null) { - $this->getApi()->getApi()->getScheduler()->cancelTask($this->getTaskId()); + public function getApi(): MineManager + { + return $this->api; + } + + /** + * @param MineManager $manager + * @param $json + * @param $name + * + * @return Mine + * @throws JsonFieldMissingException + */ + public static function fromJson(MineManager $manager, $json, $name): Mine + { + if (isset($json['pointA'], $json['pointB'], $json['level'], $json['data'])) { + return new Mine($manager, + new Vector3(...$json['pointA']), + new Vector3(...$json['pointB']), + $json['level'], + $name, + $json['data'], + $json['resetInterval'] ?? -1, + $json['warpName'] ?? ""); } + throw new JsonFieldMissingException(); } - public function onRun(int $currentTick){ + public function onRun(): void + { try { $this->reset(); - } - catch(MineResetException $e){ + } catch (MineResetException $e) { $this->getApi()->getApi()->getLogger()->debug("Background reset timer raised an exception --> " . $e->getMessage()); } } + /** + * @param bool $force NOT TESTED + * + * @throws InvalidBlockStringException + * @throws InvalidStateException + * @throws WorldNotFoundException + */ + public function reset(bool $force = false): void + { + if ($this->isResetting() && !$force) { + throw new InvalidStateException(); + } + if ($this->getLevel() === null) { + throw new WorldNotFoundException(); + } + if (!$this->isValid()) { + throw new InvalidBlockStringException(); + } + $this->isResetting = true; + + $chunks = []; + for ($x = $this->getPointA()->getX(); $x - 16 <= $this->getPointB()->getX(); $x += 16) { + for ($z = $this->getPointA()->getZ(); $z - 16 <= $this->getPointB()->getZ(); $z += 16) { + $chunk = $this->getLevel()->getChunk($x >> 4, $z >> 4); + + if (!isset($chunk)) { + return; + } + + $chunks[World::chunkHash($x >> 4, $z >> 4)] = FastChunkSerializer::serializeTerrain($chunk); + } + } + + $resetTask = new ResetTask($this->getName(), $chunks, $this->getPointA(), $this->getPointB(), $this->data, $this->getLevel()->getId()); + $this->getApi()->getApi()->getServer()->getAsyncPool()->submitTask($resetTask); + } + + /** + * @return bool + */ + public function isResetting(): bool + { + return $this->isResetting; + } + + public function getLevel(): ?World + { + return $this->api->getApi()->getServer()->getWorldManager()->getWorldByName($this->level); + } + /** * @return Vector3 */ - public function getPointA(): Vector3{ + public function getPointA(): Vector3 + { return $this->pointA; } /** * @return Vector3 */ - public function getPointB(): Vector3{ + public function getPointB(): Vector3 + { return $this->pointB; } - public function isPointInside(Position $position): bool{ - if($this->getLevel() !== null && $position->getLevel()->getId() !== $this->getLevel()->getId()){ + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + public function isPointInside(Position $position): bool + { + if ($this->getLevel() !== null && $position->getWorld()->getId() !== $this->getLevel()->getId()) { return false; } @@ -140,122 +209,81 @@ public function isPointInside(Position $position): bool{ && $position->getZ() <= $this->getPointB()->getZ(); } - /** - * @return Level | null - */ - public function getLevel(){ - return $this->api->getApi()->getServer()->getLevelByName($this->level); - } - /** * @return string */ - public function getLevelName(): string { + public function getLevelName(): string + { return $this->level; } /** * @return array */ - public function getData(): array{ + public function getData(): array + { return $this->data; } /** * @param array $data + * + * @throws \JsonException */ - public function setData(array $data){ + public function setData(array $data): void + { $this->data = $data; $this->getApi()->offsetSet($this->getName(), $this); } - /** - * @return string - */ - public function getName(): string{ - return $this->name; - } - - /** - * @return MineManager - */ - public function getApi(): MineManager{ - return $this->api; - } - - /** - * @return bool - */ - public function isResetting(){ - return $this->isResetting; - } - - public function hasWarp(){ + public function hasWarp(): bool + { return $this->warpName !== ""; } - public function getWarpName(){ + public function getWarpName(): string + { return $this->warpName; } - /** - * @param bool $force NOT TESTED - * @throws InvalidBlockStringException - * @throws InvalidStateException - * @throws WorldNotFoundException - */ - public function reset($force = false){ - if($this->isResetting() && !$force){ - throw new InvalidStateException(); - } - if($this->getLevel() === null){ - throw new WorldNotFoundException(); - } - if(!$this->isValid()){ - throw new InvalidBlockStringException(); - } - $this->isResetting = true; - - $chunks = []; - $chunkClass = Chunk::class; - for ($x = $this->getPointA()->getX(); $x-16 <= $this->getPointB()->getX(); $x += 16){ - for ($z = $this->getPointA()->getZ(); $z-16 <= $this->getPointB()->getZ(); $z += 16) { - $chunk = $this->getLevel()->getChunk($x >> 4, $z >> 4, true); - - $chunkClass = get_class($chunk); - $chunks[Level::chunkHash($x >> 4, $z >> 4)] = $chunk->fastSerialize(); - } - } - - $resetTask = new ResetTask($this->getName(), $chunks, $this->getPointA(), $this->getPointB(), $this->data, $this->getLevel()->getId(), $chunkClass); - $this->getApi()->getApi()->getServer()->getAsyncPool()->submitTask($resetTask); - } - /** * @return int */ - public function getResetInterval(): int{ + public function getResetInterval(): int + { return $this->resetInterval; } /** * @param int $resetInterval */ - public function setResetInterval(int $resetInterval){ + public function setResetInterval(int $resetInterval): void + { $this->resetInterval = $resetInterval; $this->destroy(); $this->register(); } - public function doneReset(){ + /** + * INTERNAL USE ONLY + */ + public function destroy(): void + { + $this->getHandler()?->cancel(); + } + + public function doneReset(): void + { $this->isResetting = false; } - public function __toString(){ + public function __toString() + { return $this->name; } - public function jsonSerialize(){ + public function jsonSerialize(): array + { return [ 'name' => $this->name, 'pointA' => [$this->pointA->getX(), $this->pointA->getY(), $this->pointA->getZ()], @@ -266,26 +294,4 @@ public function jsonSerialize(){ 'warpName' => $this->warpName ]; } - - /** - * @param MineManager $manager - * @param $json - * @param $name - * @return Mine - * @throws JsonFieldMissingException - */ - public static function fromJson(MineManager $manager, $json, $name): Mine{ - if(isset($json['pointA']) && isset($json['pointB']) && isset($json['level']) && isset($json['data'])){ - $a = new Mine($manager, - new Vector3(...$json['pointA']), - new Vector3(...$json['pointB']), - $json['level'], - $name, - $json['data'], - $json['resetInterval'] ?? -1, - $json['warpName'] ?? ""); - return $a; - } - throw new JsonFieldMissingException(); - } -} +} \ No newline at end of file diff --git a/src/falkirks/minereset/MineManager.php b/src/falkirks/minereset/MineManager.php index a003b00..e2ba683 100644 --- a/src/falkirks/minereset/MineManager.php +++ b/src/falkirks/minereset/MineManager.php @@ -1,76 +1,120 @@ api = $api; $this->store = $store; $this->flag = $flag; $this->mines = []; - if(file_exists($api->getDataFolder() . "mines.yml")){ + if (file_exists($api->getDataFolder() . "mines.yml")) { rename($api->getDataFolder() . "mines.yml", $api->getDataFolder() . "_minesOLD.yml"); $api->getLogger()->info("MineReset is upgrading your old mines.yml to the newest config version"); $api->getLogger()->info("A backup of your old file will be placed at " . TextFormat::BLACK . "_minesOLD.yml" . TextFormat::RESET); $this->triggerConfigUpdate(); } - if($this->flag < 2){ + if ($this->flag < 2) { $this->mines = $this->loadMines(); } } - private function triggerConfigUpdate(){ + /** + * @throws \JsonException + */ + private function triggerConfigUpdate(): void + { $store = new ConfigStore(new Config($this->getApi()->getDataFolder() . "_minesOLD.yml", Config::YAML)); - foreach($store->getIterator() as $name => $data){ + foreach ($store->getIterator() as $name => $data) { $this->mines[$name] = $this->mineFromData($name, $data); } - foreach($this->mines as $mine){ + foreach ($this->mines as $mine) { $this->store->add($mine->getName(), $mine); } $this->saveStore(true); } + /** - * @deprecated + * @return MineReset */ - protected function reloadStore(){ - if($this->flag >= 2 && $this->store instanceof Reloadable){ - $this->store->reload(); + public function getApi(): MineReset + { + return $this->api; + } + + /** + * This method requires the key of the warp in order + * to construct a mine object + * + * @param $name + * @param array $array + * + * @return \falkirks\minereset\Mine|null + * @DEPRECATED + */ + protected function mineFromData($name, array $array): ?Mine + { + if (count($array) === 9 || count($array) === 8) { + if (!$this->getApi()->getServer()->getWorldManager()->isWorldLoaded($array[7])) { + $this->api->getLogger()->warning("A mine with the name " . TextFormat::AQUA . $name . TextFormat::RESET . " is connected to a level which is not loaded. You won't be able to use it until you load the level correctly."); + } + return new Mine($this, + new Vector3(min($array[0], $array[1]), min($array[2], $array[3]), min($array[4], $array[5])), + new Vector3(max($array[0], $array[1]), max($array[2], $array[3]), max($array[4], $array[5])), + $array[7], + $name, + (is_array($array[6]) ? $array[6] : []), + $array[8] ?? -1); } + $this->api->getLogger()->critical("A mine with the name " . TextFormat::AQUA . $name . TextFormat::RESET . " is incomplete. It will be removed automatically when your server stops."); + return null; } - protected function saveStore($force = false){ - if(($this->flag > 0 || $force) && $this->store instanceof Saveable){ + + /** + * @throws \JsonException + */ + protected function saveStore($force = false): void + { + if (($this->flag > 0 || $force) && $this->store instanceof Saveable) { $this->store->save(); } } - protected function loadMines(): array{ + + protected function loadMines(): array + { $out = []; - foreach($this->store->getIterator() as $name => $data){ + foreach ($this->store->getIterator() as $name => $data) { try { $out[$name] = Mine::fromJson($this, $data, $name); - } - catch(JsonFieldMissingException $e){ + } catch (JsonFieldMissingException $e) { $this->getApi()->getLogger()->warning("Mine with name " . $name . " is missing data in save file. Will be deleted on next save."); } //$out[$name] = $this->mineFromData($name, $data); @@ -78,62 +122,64 @@ protected function loadMines(): array{ return $out; } - /** - * WARNING - * This function is for internal use only. - */ - public function saveAll(){ - if($this->flag === 0){ - $this->store->clear(); - foreach($this->mines as $mine){ - $this->store->add($mine->getName(), $mine); - } - $this->saveStore(true); - } - } /** * (PHP 5 >= 5.0.0)
* Whether a offset exists + * * @link http://php.net/manual/en/arrayaccess.offsetexists.php + * * @param mixed $offset

- * An offset to check for. - *

+ * An offset to check for. + *

+ * * @return boolean true on success or false on failure. *

*

* The return value will be casted to boolean if non-boolean was returned. */ - public function offsetExists($offset){ + public function offsetExists(mixed $offset): bool + { return isset($this->mines[$offset]); } + /** * (PHP 5 >= 5.0.0)
* Offset to retrieve + * * @link http://php.net/manual/en/arrayaccess.offsetget.php + * * @param mixed $offset

- * The offset to retrieve. - *

+ * The offset to retrieve. + *

+ * * @return mixed Can return all value types. */ - public function offsetGet($offset){ + public function offsetGet(mixed $offset): mixed + { return $this->mines[$offset] ?? null; } + /** * (PHP 5 >= 5.0.0)
* Offset to set + * * @link http://php.net/manual/en/arrayaccess.offsetset.php + * * @param mixed $offset

- * The offset to assign the value to. - *

- * @param mixed $value

- * The value to set. - *

+ * The offset to assign the value to. + *

+ * @param mixed $value

+ * The value to set. + *

+ * * @return void + * @throws \JsonException */ - public function offsetSet($offset, $value){ - if($value instanceof Mine && $value->getName() === $offset) { + public function offsetSet(mixed $offset, mixed $value): void + { + if ($value instanceof Mine && $value->getName() === $offset) { - if(isset($this->mines[$offset]) && $value !== $this->mines[$offset] && $this->mines[$offset] instanceof Mine){ + if (isset($this->mines[$offset]) && $value !== $this->mines[$offset] && $this->mines[$offset] instanceof Mine) { $this->mines[$offset]->destroy(); } @@ -142,22 +188,27 @@ public function offsetSet($offset, $value){ $this->store->add($offset, $value); $this->saveStore(); } - } - else{ - throw new \RuntimeException("Invalid \$offset for mine data."); + } else { + throw new RuntimeException("Invalid \$offset for mine data."); } } + /** * (PHP 5 >= 5.0.0)
* Offset to unset + * * @link http://php.net/manual/en/arrayaccess.offsetunset.php + * * @param mixed $offset

- * The offset to unset. - *

+ * The offset to unset. + *

+ * * @return void + * @throws \JsonException */ - public function offsetUnset($offset){ - if(isset($this->mines[$offset])) { + public function offsetUnset(mixed $offset): void + { + if (isset($this->mines[$offset])) { if ($this->mines[$offset] instanceof Mine) { $this->mines[$offset]->destroy(); } @@ -168,68 +219,25 @@ public function offsetUnset($offset){ } } } - /** - * This method requires the key of the warp in order - * to construct a mine object - * @param $name - * @param array $array - * @return Mine - * @throws \Exception - * @DEPRECATED - */ - protected function mineFromData($name, array $array){ - if(count($array) === 9 || count($array) === 8) { - if(!$this->getApi()->getServer()->isLevelLoaded($array[7])){ - $this->api->getLogger()->warning("A mine with the name " . TextFormat::AQUA . $name . TextFormat::RESET . " is connected to a level which is not loaded. You won't be able to use it until you load the level correctly."); - } - return new Mine($this, - new Vector3(min($array[0], $array[1]), min($array[2], $array[3]), min($array[4], $array[5])), - new Vector3(max($array[0], $array[1]), max($array[2], $array[3]), max($array[4], $array[5])), - $array[7], - $name, - (is_array($array[6]) ? $array[6] : []), - $array[8] ?? -1); - } - $this->api->getLogger()->critical("A mine with the name " . TextFormat::AQUA . $name . TextFormat::RESET . " is incomplete. It will be removed automatically when your server stops."); - return null; - } - /** - * In order to pass data to a DataStore - * a key is needed. Typically one should - * use $warp->getName() - * @param Mine $mine - * @return array - * @DEPRECATED - */ - protected function mineToData(Mine $mine){ - return [ - $mine->getPointA()->getX(), - $mine->getPointB()->getX(), - $mine->getPointA()->getY(), - $mine->getPointB()->getY(), - $mine->getPointA()->getZ(), - $mine->getPointB()->getZ(), - (count($mine->getData()) > 0 ? $mine->getData() : false), - $mine->getLevelName(), - $mine->getResetInterval() - ]; - } + /** * (PHP 5 >= 5.0.0)
* Retrieve an external iterator + * * @link http://php.net/manual/en/iteratoraggregate.getiterator.php * @return \Traversable An instance of an object implementing Iterator or * Traversable */ - public function getIterator(){ - return new \ArrayIterator($this->mines); + public function getIterator(): \Traversable|ArrayIterator + { + return new ArrayIterator($this->mines); } - public function count(){ + public function count(): int + { return count($this->mines); } - /** * Returns the current storage-mode * ##### @@ -249,40 +257,94 @@ public function count(){ * NO_MEMORY_STORE = 2 * THIS IS NOT SUPPORTED * #### + * * @return int */ - public function getFlag(): int{ + public function getFlag(): int + { return $this->flag; } + /** * returns the current data store + * * @return DataStore */ - public function getStore(): DataStore{ + public function getStore(): DataStore + { return $this->store; } + /** * Injects a new DataStore for warps * ! This will inject your code into MineReset, potentially breaking! + * * @param DataStore $store */ - public function setStore(DataStore $store){ + public function setStore(DataStore $store): void + { $this->saveAll(); $this->store = $store; $this->mines = $this->loadMines(); } /** - * @return MineReset + * WARNING + * This function is for internal use only. + * + * @throws \JsonException */ - public function getApi(): MineReset{ - return $this->api; + public function saveAll(): void + { + if ($this->flag === 0) { + $this->store->clear(); + foreach ($this->mines as $mine) { + $this->store->add($mine->getName(), $mine); + } + $this->saveStore(true); + } } /** * @return Mine[] */ - public function getMines(): array{ + public function getMines(): array + { return $this->mines; } + + /** + * @deprecated + */ + protected function reloadStore(): void + { + if ($this->flag >= 2 && $this->store instanceof Reloadable) { + $this->store->reload(); + } + } + + /** + * In order to pass data to a DataStore + * a key is needed. Typically one should + * use $warp->getName() + * + * @param Mine $mine + * + * @return array + * @DEPRECATED + */ + protected function mineToData(Mine $mine): array + { + return [ + $mine->getPointA()->getX(), + $mine->getPointB()->getX(), + $mine->getPointA()->getY(), + $mine->getPointB()->getY(), + $mine->getPointA()->getZ(), + $mine->getPointB()->getZ(), + (count($mine->getData()) > 0 ? $mine->getData() : false), + $mine->getLevelName(), + $mine->getResetInterval() + ]; + } } \ No newline at end of file diff --git a/src/falkirks/minereset/MineReset.php b/src/falkirks/minereset/MineReset.php index 069bb8e..9c13dcf 100644 --- a/src/falkirks/minereset/MineReset.php +++ b/src/falkirks/minereset/MineReset.php @@ -1,8 +1,7 @@ getDataFolder()); - $this->debugDumpFactory = new DebugDumpFactory($this); $this->mineManager = new MineManager($this, new ConfigStore(new Config($this->getDataFolder() . "mines.json", Config::JSON, []))); @@ -69,7 +64,6 @@ public function onEnable(){ $this->mainCommand = new MineCommand($this); $this->getServer()->getCommandMap()->register("minereset", $this->mainCommand); - $this->mainCommand->registerSubCommand("about", new AboutCommand($this), ['a']); $this->mainCommand->registerSubCommand("report", new ReportCommand($this), []); $this->mainCommand->registerSubCommand("list", new ListCommand($this), ['l']); $this->mainCommand->registerSubCommand("create", new CreateCommand($this), ['c']); @@ -79,77 +73,83 @@ public function onEnable(){ $this->mainCommand->registerSubCommand("reset-all", new ResetAllCommand($this), ['ra']); $this->mainCommand->registerSubCommand("edit", new EditCommand($this), ['e']); - if(!self::supportsChunkSetting()){ + if (!self::supportsChunkSetting()) { $this->getLogger()->warning("Your server does not support setting chunks without unloading them. This will cause tiles and entities to be lost when resetting mines. Upgrade to a newer pmmp to resolve this."); } } - public function onDisable(){ + private static function detectChunkSetting(): void + { + if (self::$supportsChunkSetting === null) { + $class = new ReflectionClass(World::class); + $func = $class->getMethod("setChunk"); + $filename = $func->getFileName(); + $start_line = $func->getStartLine() - 1; + $end_line = $func->getEndLine(); + $length = $end_line - $start_line; + + $source = file($filename); + $body = implode("", array_slice($source, $start_line, $length)); + self::$supportsChunkSetting = str_contains($body, 'removeEntity'); + } + } + + public static function supportsChunkSetting(): bool + { + return static::$supportsChunkSetting; + } + + public function onDisable(): void + { $this->mineManager->saveAll(); } /** * @return MineManager */ - public function getMineManager(): MineManager{ + public function getMineManager(): MineManager + { return $this->mineManager; } /** * @return ResetProgressManager */ - public function getResetProgressManager(): ResetProgressManager{ + public function getResetProgressManager(): ResetProgressManager + { return $this->resetProgressManager; } /** * @return MineCommand */ - public function getMainCommand(): MineCommand{ + public function getMainCommand(): MineCommand + { return $this->mainCommand; } /** * @return CreationListener */ - public function getCreationListener(): CreationListener{ + public function getCreationListener(): CreationListener + { return $this->creationListener; } /** * @return RegionBlockerListener */ - public function getRegionBlockerListener(): RegionBlockerListener{ + public function getRegionBlockerListener(): RegionBlockerListener + { return $this->regionBlockerListener; } /** * @return DebugDumpFactory */ - public function getDebugDumpFactory(): DebugDumpFactory{ + public function getDebugDumpFactory(): DebugDumpFactory + { return $this->debugDumpFactory; } - - - - - public static function supportsChunkSetting(): bool { - return static::$supportsChunkSetting; - } - - private static function detectChunkSetting(){ - if(self::$supportsChunkSetting === null) { - $class = new \ReflectionClass(Level::class); - $func = $class->getMethod("setChunk"); - $filename = $func->getFileName(); - $start_line = $func->getStartLine() - 1; - $end_line = $func->getEndLine(); - $length = $end_line - $start_line; - - $source = file($filename); - $body = implode("", array_slice($source, $start_line, $length)); - self::$supportsChunkSetting = strpos($body, 'removeEntity') !== false; - } - } } \ No newline at end of file diff --git a/src/falkirks/minereset/ResetProgressManager.php b/src/falkirks/minereset/ResetProgressManager.php index 7788620..d38c8ca 100644 --- a/src/falkirks/minereset/ResetProgressManager.php +++ b/src/falkirks/minereset/ResetProgressManager.php @@ -1,59 +1,64 @@ api = $api; $this->subscriptions = []; } - public function notifyProgress(string $progress, string $mineName){ - if(isset($this->subscriptions[$mineName])){ - foreach ($this->subscriptions[$mineName] as $sender){ - $sender->sendMessage("RESET {$mineName}: {$progress}"); + public function notifyProgress(string $progress, string $mineName): void + { + if (isset($this->subscriptions[$mineName])) { + foreach ($this->subscriptions[$mineName] as $sender) { + $sender->sendMessage("RESET $mineName: $progress"); } } } - public function notifyComplete(string $mineName){ - if(isset($this->getApi()->getMineManager()[$mineName])){ + public function notifyComplete(string $mineName): void + { + if (isset($this->getApi()->getMineManager()[$mineName])) { $this->getApi()->getMineManager()[$mineName]->doneReset(); } - if(isset($this->subscriptions[$mineName])){ - foreach ($this->subscriptions[$mineName] as $sender){ - $sender->sendMessage("Reset of {$mineName} has completed."); + if (isset($this->subscriptions[$mineName])) { + foreach ($this->subscriptions[$mineName] as $sender) { + $sender->sendMessage("Reset of $mineName has completed."); } unset($this->subscriptions[$mineName]); } } - public function addObserver(string $mineName, CommandSender $sender){ - if(!isset($this->subscriptions[$mineName])){ - $this->subscriptions[$mineName] = []; - } - $this->subscriptions[$mineName][] = $sender; - } - /** * @return MineReset */ - public function getApi(): MineReset{ + public function getApi(): MineReset + { return $this->api; } - + public function addObserver(string $mineName, CommandSender $sender): void + { + if (!isset($this->subscriptions[$mineName])) { + $this->subscriptions[$mineName] = []; + } + $this->subscriptions[$mineName][] = $sender; + } } \ No newline at end of file diff --git a/src/falkirks/minereset/command/AboutCommand.php b/src/falkirks/minereset/command/AboutCommand.php deleted file mode 100644 index c6bb99b..0000000 --- a/src/falkirks/minereset/command/AboutCommand.php +++ /dev/null @@ -1,19 +0,0 @@ -hasPermission("minereset.command.about")) { - $this->getApi()->getServer()->getAsyncPool()->submitTask(new AboutPullTask($sender)); - } - else{ - $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); - } - } -} \ No newline at end of file diff --git a/src/falkirks/minereset/command/CreateCommand.php b/src/falkirks/minereset/command/CreateCommand.php index 57c5965..bf95c07 100644 --- a/src/falkirks/minereset/command/CreateCommand.php +++ b/src/falkirks/minereset/command/CreateCommand.php @@ -1,34 +1,42 @@ hasPermission("minereset.command.create")) - return $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); + public function execute(CommandSender $sender, $commandLabel, array $args): void + { + if (!$sender->hasPermission("minereset.command.create")) { + $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); + return; + } - if (!($sender instanceof Player)) - return $sender->sendMessage(TextFormat::RED . "This command can only be run in-game." . TextFormat::RESET); + if (!($sender instanceof Player)) { + $sender->sendMessage(TextFormat::RED . "This command can only be run in-game." . TextFormat::RESET); + return; + } - if(!isset($args[0])) - return $sender->sendMessage("Usage: /mine create "); + if (!isset($args[0])) { + $sender->sendMessage("Usage: /mine create "); + return; + } - if($this->getApi()->getCreationListener()->playerHasSession($sender)) - return $sender->sendMessage("Hold up! You are already in the process of creating a mine. You need to finish that first."); + if ($this->getApi()->getCreationListener()->playerHasSession($sender)) { + $sender->sendMessage("Hold up! You are already in the process of creating a mine. You need to finish that first."); + return; + } - if(isset($this->getApi()->getMineManager()[$args[0]])) - return $sender->sendMessage("That mine already exists. You must run \"/mine destroy {$args[0]}\" before creating a new one."); + if (isset($this->getApi()->getMineManager()[$args[0]])) { + $sender->sendMessage("That mine already exists. You must run \"/mine destroy $args[0]\" before creating a new one."); + return; + } $this->getApi()->getCreationListener()->addSession(new MineCreationSession($args[0], $sender)); $sender->sendMessage("Tap a block to set position A."); - return true; } } \ No newline at end of file diff --git a/src/falkirks/minereset/command/DestroyCommand.php b/src/falkirks/minereset/command/DestroyCommand.php index 3d93538..6b1d451 100644 --- a/src/falkirks/minereset/command/DestroyCommand.php +++ b/src/falkirks/minereset/command/DestroyCommand.php @@ -1,16 +1,17 @@ offset = 0; $this->senders = []; } - public function doDelete(CommandSender $sender, $name){ - unset($this->getApi()->getMineManager()[$name]); - unset($this->senders[$sender->getName()]); - $sender->sendMessage("{$name[0]} has been destroyed."); + public function doDelete(CommandSender $sender, string $name): void + { + unset($this->getApi()->getMineManager()[$name], $this->senders[$sender->getName()]); + $sender->sendMessage("$name[0] has been destroyed."); } - private function formDelete(CommandSender $sender, $name){ - $form = new class("Are you sure?", "You are about to delete the mine called $name.") extends ModalForm { - public function onSubmit(Player $player, $response) : void{ - if($response){ - $this->parent->doDelete($player, $this->name); + private function formDelete(Player $sender, string $name): void + { + $form = new ModalForm("Are you sure?", "You are about to delete the mine called $name.", + function (Player $player, bool $response) use ($name): void { + if ($response) { + $this->doDelete($player, $name); } - } - }; - $form->parent = $this; - $form->name = $name; + }); $sender->sendForm($form); } - private function basicDelete(CommandSender $sender, $name){ - $str = DestroyCommand::DESTROY_STRINGS[$this->offset]; + private function basicDelete(CommandSender $sender, string $name): void + { + $str = self::DESTROY_STRINGS[$this->offset]; $sender->sendMessage("Run: " . TextFormat::AQUA . "/mine destroy $name $str" . TextFormat::RESET); $sender->sendMessage("To destroy mines faster, you can edit the config file directly."); $this->senders[$sender->getName()] = $str; - if ($this->offset === count(DestroyCommand::DESTROY_STRINGS) - 1) { + if ($this->offset === count(self::DESTROY_STRINGS) - 1) { $this->offset = -1; } @@ -65,27 +66,31 @@ private function basicDelete(CommandSender $sender, $name){ } - public function execute(CommandSender $sender, $commandLabel, array $args){ - if(!$sender->hasPermission("minereset.command.destroy")) - return $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); + public function execute(CommandSender $sender, $commandLabel, array $args): void + { + if (!$sender->hasPermission("minereset.command.destroy")) { + $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); + return; + } - if (!isset($args[0])) - return $sender->sendMessage("Usage: /mine destroy "); + if (!isset($args[0])) { + $sender->sendMessage("Usage: /mine destroy "); + return; + } $name = $args[0]; - if(!isset($this->getApi()->getMineManager()[$name])) - return $sender->sendMessage("{$args[0]} is not a valid mine."); + if (!isset($this->getApi()->getMineManager()[$name])) { + $sender->sendMessage("$args[0] is not a valid mine."); + return; + } - if($sender instanceof Player && $this->formsSupported()){ + if ($sender instanceof Player) { $this->formDelete($sender, $name); - } - else if (isset($args[1]) && isset($this->senders[$sender->getName()]) && $this->senders[$sender->getName()] === $args[1]) { + } else if (isset($args[1], $this->senders[$sender->getName()]) && $this->senders[$sender->getName()] === $args[1]) { $this->doDelete($sender, $name); } else { $this->basicDelete($sender, $name); } - - return true; } } \ No newline at end of file diff --git a/src/falkirks/minereset/command/EditCommand.php b/src/falkirks/minereset/command/EditCommand.php index fbf040c..e01e6fd 100644 --- a/src/falkirks/minereset/command/EditCommand.php +++ b/src/falkirks/minereset/command/EditCommand.php @@ -2,43 +2,35 @@ namespace falkirks\minereset\command; - -use falkirks\minereset\task\AboutPullTask; -use Frago9876543210\EasyForms\elements\custom\Dropdown; -use Frago9876543210\EasyForms\elements\custom\Input; -use Frago9876543210\EasyForms\elements\custom\Label; +use Frago9876543210\EasyForms\elements\Dropdown; +use Frago9876543210\EasyForms\elements\Input; +use Frago9876543210\EasyForms\elements\Label; use Frago9876543210\EasyForms\forms\CustomForm; -use Frago9876543210\EasyForms\forms\ModalForm; +use Frago9876543210\EasyForms\forms\CustomFormResponse; use pocketmine\command\CommandSender; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; -class EditCommand extends SubCommand{ - public function execute(CommandSender $sender, $commandLabel, array $args){ - if($sender->hasPermission("minereset.command.edit")) { - if($sender instanceof Player && $this->formsSupported()){ - $sender->sendForm(new class("Mine: a", [ +class EditCommand extends SubCommand +{ + public function execute(CommandSender $sender, $commandLabel, array $args): void + { + if ($sender->hasPermission("minereset.command.edit")) { + if ($sender instanceof Player) { + $form = new CustomForm("Mine: a", [ new Dropdown("Select product", ["beer", "cheese", "cola"]), new Input("Mine name", "a"), new Input("Reset interval", "-1"), new Label("Reset interval is in seconds"), //popElement() does not work with label new Input("Warp name", ""), new Label("Name of the warp to link with the mine"), - ]) extends CustomForm { - public function onSubmit(Player $player, $response) : void{ - parent::onSubmit($player, $response); - $player->sendMessage("cool!"); - } + ], function (Player $player, CustomFormResponse $response): void { + $player->sendMessage("cool!"); }); + $sender->sendForm($form); } - else { - $sender->sendMessage(TextFormat::RED . "You must install EasyForms to use this command." . TextFormat::RESET); - } - } - else{ + } else { $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); } - - } } \ No newline at end of file diff --git a/src/falkirks/minereset/command/ListCommand.php b/src/falkirks/minereset/command/ListCommand.php index 0f33a24..5e5a142 100644 --- a/src/falkirks/minereset/command/ListCommand.php +++ b/src/falkirks/minereset/command/ListCommand.php @@ -1,30 +1,29 @@ hasPermission("minereset.command.list")) { +class ListCommand extends SubCommand +{ + public function execute(CommandSender $sender, $commandLabel, array $args): void + { + if ($sender->hasPermission("minereset.command.list")) { $sender->sendMessage("---- Mines ----"); foreach ($this->getApi()->getMineManager() as $mine) { if ($mine instanceof Mine) { - if(!$mine->isValid()){ + if (!$mine->isValid()) { $sender->sendMessage("* " . TextFormat::RED . $mine . TextFormat::RESET); - } - else if($mine->isResetting()){ + } else if ($mine->isResetting()) { $sender->sendMessage("* " . TextFormat::BLUE . $mine . TextFormat::RESET); - } - else { + } else { $sender->sendMessage("* " . $mine); } } } - } - else{ + } else { $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); } } diff --git a/src/falkirks/minereset/command/MineCommand.php b/src/falkirks/minereset/command/MineCommand.php index 8fccc7c..834fa51 100644 --- a/src/falkirks/minereset/command/MineCommand.php +++ b/src/falkirks/minereset/command/MineCommand.php @@ -2,59 +2,53 @@ namespace falkirks\minereset\command; - use falkirks\minereset\MineReset; use pocketmine\command\Command; use pocketmine\command\CommandSender; -use pocketmine\command\PluginIdentifiableCommand; -use pocketmine\Player; -use pocketmine\plugin\Plugin; -class MineCommand extends Command implements PluginIdentifiableCommand { - /** @var MineReset */ - protected $api; +class MineCommand extends Command +{ + /** @var MineReset */ + protected MineReset $api; /** @var SubCommand[] */ - protected $subCommands; - public function __construct(MineReset $api){ + protected array $subCommands; + + public function __construct(MineReset $api) + { parent::__construct("mine", "Mine reset command", "/mine [parameters]"); $this->setPermission("mine.command"); $this->api = $api; $this->subCommands = []; } + /** * @param CommandSender $sender - * @param string $commandLabel - * @param string[] $args + * @param string $commandLabel + * @param string[] $args * - * @return mixed + * @return void */ - public function execute(CommandSender $sender, string $commandLabel, array $args){ - if(!$this->testPermission($sender)){ - return null; - } - if(count($args) > 0 && array_key_exists($args[0], $this->subCommands)){ - return $this->subCommands[array_shift($args)]->execute($sender, $commandLabel, $args); + public function execute(CommandSender $sender, string $commandLabel, array $args): void + { + if (!$this->testPermission($sender)) { + return; } - else{ - $sender->sendMessage($this->getUsage()); - return null; + if (count($args) > 0 && array_key_exists($args[0], $this->subCommands)) { + $this->subCommands[array_shift($args)]->execute($sender, $commandLabel, $args); + return; } - } - /** - * @return \pocketmine\plugin\Plugin - */ - public function getPlugin(): Plugin{ - return $this->api; + $sender->sendMessage($this->getUsage()); } - public function registerSubCommand(string $name, SubCommand $command, $aliases = []){ + public function registerSubCommand(string $name, SubCommand $command, $aliases = []): void + { $this->subCommands[$name] = $command; - foreach ($aliases as $alias){ - if(!isset($this->subCommands[$alias])){ + foreach ($aliases as $alias) { + if (!isset($this->subCommands[$alias])) { $this->registerSubCommand($alias, $command); } } } -} +} \ No newline at end of file diff --git a/src/falkirks/minereset/command/ReportCommand.php b/src/falkirks/minereset/command/ReportCommand.php index 81917b7..459e289 100644 --- a/src/falkirks/minereset/command/ReportCommand.php +++ b/src/falkirks/minereset/command/ReportCommand.php @@ -2,29 +2,32 @@ namespace falkirks\minereset\command; - -use falkirks\minereset\task\AboutPullTask; use pocketmine\command\CommandSender; -use pocketmine\command\ConsoleCommandSender; +use pocketmine\console\ConsoleCommandSender; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; -class ReportCommand extends SubCommand{ - public function execute(CommandSender $sender, $commandLabel, array $args){ - if($sender->hasPermission("minereset.command.report")) { +class ReportCommand extends SubCommand +{ + /** + * @throws \JsonException + */ + public function execute(CommandSender $sender, $commandLabel, array $args): void + { + if ($sender->hasPermission("minereset.command.report")) { $data = $this->getApi()->getDebugDumpFactory()->generate(); if ($sender instanceof ConsoleCommandSender) { $issueContent = "\n\n(Explain your problem here)\n\n```\n$data\n```"; $url = "https://github.com/Falkirks/MineReset/issues/new" . (count($args) > 0 ? "?title=" . urlencode(implode(" ", $args)) . "\&" : "?") . "body=" . urlencode($issueContent); switch (Utils::getOS()) { case 'win': - `start $url`; + shell_exec("start \$url"); break; case 'mac': - `open $url`; + shell_exec("open \$url"); break; case 'linux': - `xdg-open $url`; + shell_exec("xdg-open \$url"); break; default: $sender->sendMessage("Copy and paste the following URL into your browser to start a report."); @@ -36,8 +39,7 @@ public function execute(CommandSender $sender, $commandLabel, array $args){ } $sender->sendMessage("--- MineReset Data ---"); $sender->sendMessage($data); - } - else{ + } else { $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); } } diff --git a/src/falkirks/minereset/command/ResetAllCommand.php b/src/falkirks/minereset/command/ResetAllCommand.php index f001856..bfaafb0 100644 --- a/src/falkirks/minereset/command/ResetAllCommand.php +++ b/src/falkirks/minereset/command/ResetAllCommand.php @@ -1,4 +1,5 @@ hasPermission("minereset.command.resetall")) { +class ResetAllCommand extends SubCommand +{ + public function execute(CommandSender $sender, $commandLabel, array $args): void + { + if ($sender->hasPermission("minereset.command.resetall")) { $success = 0; foreach ($this->getApi()->getMineManager() as $mine) { if ($mine instanceof Mine) { - try{ + try { $mine->reset(); $success++; $this->getApi()->getResetProgressManager()->addObserver($mine->getName(), $sender); - } catch (MineResetException $exception){ + } catch (MineResetException) { $sender->sendMessage(TextFormat::RED . "Error raised for {$mine->getName()}, you can reset this mine directly for more info." . TextFormat::RESET); } } } $count = count($this->getApi()->getMineManager()); - $sender->sendMessage("Queued reset for {$success}/{$count} mines."); - } - else{ + $sender->sendMessage("Queued reset for $success/$count mines."); + } else { $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); } } diff --git a/src/falkirks/minereset/command/ResetCommand.php b/src/falkirks/minereset/command/ResetCommand.php index c40985b..f2e4a87 100644 --- a/src/falkirks/minereset/command/ResetCommand.php +++ b/src/falkirks/minereset/command/ResetCommand.php @@ -1,4 +1,5 @@ hasPermission("minereset.command.reset")) - return $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); +class ResetCommand extends SubCommand +{ + public function execute(CommandSender $sender, $commandLabel, array $args): void + { + if (!$sender->hasPermission("minereset.command.reset")) { + $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); + return; + } - if (!isset($args[0])) - return $sender->sendMessage("Usage: /mine reset "); + if (!isset($args[0])) { + $sender->sendMessage("Usage: /mine reset "); + return; + } $mine = $this->getApi()->getMineManager()[$args[0]]; // fetch mine from the manager - if($mine === null) - return $sender->sendMessage("{$args[0]} is not a valid mine."); + if ($mine === null) { + $sender->sendMessage("$args[0] is not a valid mine."); + return; + } - try{ + try { $mine->reset(); - $sender->sendMessage("Queued reset for {$args[0]}."); + $sender->sendMessage("Queued reset for $args[0]."); $this->getApi()->getResetProgressManager()->addObserver($args[0], $sender); - } - catch (InvalidStateException $e){ + } catch (InvalidStateException) { $sender->sendMessage(TextFormat::RED . "Failed to queue reset due to bad state." . TextFormat::RESET); $sender->sendMessage(" --> this means the mine is already resetting"); @@ -34,16 +42,14 @@ public function execute(CommandSender $sender, $commandLabel, array $args){ $sender->sendMessage(" --> then try restarting the server "); $sender->sendMessage("You can run /mine report to report bugs on github."); - } - catch (WorldNotFoundException $e){ + } catch (WorldNotFoundException) { $sender->sendMessage(TextFormat::RED . "Failed to queue reset due to level not found." . TextFormat::RESET); $sender->sendMessage(" --> this means that the level called [{$mine->getLevelName()}] is not loaded"); $sender->sendMessage(" --> perhaps you have changed the level name? or forgotten to load it? "); $sender->sendMessage("You can run /mine report to report bugs on github."); - } - catch(InvalidBlockStringException $e){ + } catch (InvalidBlockStringException) { $sender->sendMessage(TextFormat::RED . "Failed to queue reset due to invalid ratio date." . TextFormat::RESET); $sender->sendMessage(" --> this means the saved data for the mine is invalid"); @@ -52,7 +58,5 @@ public function execute(CommandSender $sender, $commandLabel, array $args){ $sender->sendMessage("You can run /mine report to report bugs on github."); } - - return true; } } \ No newline at end of file diff --git a/src/falkirks/minereset/command/SetCommand.php b/src/falkirks/minereset/command/SetCommand.php index 025cfc2..7e228d9 100644 --- a/src/falkirks/minereset/command/SetCommand.php +++ b/src/falkirks/minereset/command/SetCommand.php @@ -1,41 +1,56 @@ hasPermission("minereset.command.set")) - return $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); - if (!isset($args[0])) - return $sender->sendMessage("Usage: /mine set "); +class SetCommand extends SubCommand +{ + public function execute(CommandSender $sender, $commandLabel, array $args): void + { + if (!$sender->hasPermission("minereset.command.set")) { + $sender->sendMessage(TextFormat::RED . "You do not have permission to run this command." . TextFormat::RESET); + return; + } + if (!isset($args[0])) { + $sender->sendMessage("Usage: /mine set < data>"); + return; + } $name = $args[0]; - if (!isset($this->getApi()->getMineManager()[$args[0]])) - return $sender->sendMessage("{$args[0]} is not a valid mine."); + if (!isset($this->getApi()->getMineManager()[$args[0]])) { + $sender->sendMessage("$args[0] is not a valid mine."); + return; + } - if(!isset($args[2])) - return $sender->sendMessage("You must provide at least one block with a chance value."); + if (!isset($args[2])) { + $sender->sendMessage("You must provide at least one block with a chance value."); + return; + } $sets = array_slice($args, 1); $save = []; //FIXME Allows bad ordering by treating every input as block string - if(!array_reduce($sets, function ($carry, $curr){ return $carry && BlockStringParser::isValid($curr); }, true)) - return $sender->sendMessage(TextFormat::RED . "Part of your format is not a number." . TextFormat::RESET); - if(count($sets) % 2 !== 0) - return $sender->sendMessage(TextFormat::RED . "Your format string looks incorrect." . TextFormat::RESET); + if (!array_reduce($sets, static function ($carry, $curr) { return $carry && BlockStringParser::isValid($curr); }, true)) { + $sender->sendMessage(TextFormat::RED . "Part of your format is not a number." . TextFormat::RESET); + return; + } + if (count($sets) % 2 !== 0) { + $sender->sendMessage(TextFormat::RED . "Your format string looks incorrect." . TextFormat::RESET); + return; + } $total = 0; foreach ($sets as $key => $item) { if (strpos($item, "%")) { - return $sender->sendMessage(TextFormat::RED . "Your format string looks incorrect." . TextFormat::RESET); + $sender->sendMessage(TextFormat::RED . "Your format string looks incorrect." . TextFormat::RESET); + return; } if ($key & 1) { $total += $item; @@ -47,11 +62,12 @@ public function execute(CommandSender $sender, $commandLabel, array $args){ } } - if($total !== 100) - return $sender->sendMessage(TextFormat::RED . "The percents on your mine must add to 100, but they add to $total." . TextFormat::RESET); + if ($total !== 100) { + $sender->sendMessage(TextFormat::RED . "The percents on your mine must add to 100, but they add to $total." . TextFormat::RESET); + return; + } $this->getApi()->getMineManager()[$name]->setData($save); $sender->sendMessage(TextFormat::GREEN . "Mine has been setted. Use /mine reset $name to see your changes."); - return true; } } \ No newline at end of file diff --git a/src/falkirks/minereset/command/SubCommand.php b/src/falkirks/minereset/command/SubCommand.php index 295e595..e50b751 100644 --- a/src/falkirks/minereset/command/SubCommand.php +++ b/src/falkirks/minereset/command/SubCommand.php @@ -1,34 +1,39 @@ api = $api; } abstract public function execute(CommandSender $sender, $commandLabel, array $args); + public function formsSupported(): bool + { + return $this->getApi()->getServer()->getPluginManager()->getPlugin("EasyForms") instanceof Plugin; + } + /** * @return MineReset */ - public function getApi(): MineReset{ + public function getApi(): MineReset + { return $this->api; } - - public function formsSupported(): bool{ - return $this->getApi()->getServer()->getPluginManager()->getPlugin("EasyForms") instanceof Plugin; - } } \ No newline at end of file diff --git a/src/falkirks/minereset/exception/InvalidBlockStringException.php b/src/falkirks/minereset/exception/InvalidBlockStringException.php index 070f20b..3bea182 100644 --- a/src/falkirks/minereset/exception/InvalidBlockStringException.php +++ b/src/falkirks/minereset/exception/InvalidBlockStringException.php @@ -3,7 +3,6 @@ namespace falkirks\minereset\exception; - class InvalidBlockStringException extends MineResetException { diff --git a/src/falkirks/minereset/exception/InvalidStateException.php b/src/falkirks/minereset/exception/InvalidStateException.php index e1ef393..b5c5e87 100644 --- a/src/falkirks/minereset/exception/InvalidStateException.php +++ b/src/falkirks/minereset/exception/InvalidStateException.php @@ -4,7 +4,6 @@ namespace falkirks\minereset\exception; - class InvalidStateException extends MineResetException { diff --git a/src/falkirks/minereset/exception/MineResetException.php b/src/falkirks/minereset/exception/MineResetException.php index ec1c6e0..3a66186 100644 --- a/src/falkirks/minereset/exception/MineResetException.php +++ b/src/falkirks/minereset/exception/MineResetException.php @@ -3,7 +3,9 @@ namespace falkirks\minereset\exception; -class MineResetException extends \Exception +use Exception; + +class MineResetException extends Exception { } \ No newline at end of file diff --git a/src/falkirks/minereset/listener/CreationListener.php b/src/falkirks/minereset/listener/CreationListener.php index 27298d0..9e37bef 100644 --- a/src/falkirks/minereset/listener/CreationListener.php +++ b/src/falkirks/minereset/listener/CreationListener.php @@ -1,96 +1,104 @@ api = $api; $this->sessions = []; } /** - * @priority LOW + * @priority LOW * @ignoreCancelled true * * @param PlayerInteractEvent $event + * + * @throws \falkirks\minereset\exception\InvalidStateException */ - public function onBlockTap(PlayerInteractEvent $event){ - if($event->getAction() !== PlayerInteractEvent::RIGHT_CLICK_BLOCK){ + public function onBlockTap(PlayerInteractEvent $event) + { + if ($event->getAction() !== PlayerInteractEvent::RIGHT_CLICK_BLOCK) { return; } $session = $this->getPlayerSession($event->getPlayer()); - if($session !== null){ - if($session->getLevel() === null || $session->getLevel()->getId() === $event->getPlayer()->getLevel()->getId()) { - $session->setNextPoint($event->getBlock()); - $session->setLevel($event->getPlayer()->getPosition()->getLevel()); + if ($session !== null) { + if ($session->getLevel() === null || $session->getLevel()->getId() === $event->getPlayer()->getWorld()->getId()) { + $session->setNextPoint($event->getBlock()->getPosition()); + $session->setLevel($event->getPlayer()->getPosition()->getWorld()); - if($session->canGenerate()){ + if ($session->canGenerate()) { $mine = $session->generate($this->getApi()->getMineManager()); $event->getPlayer()->sendMessage("You have created a mine called " . $mine->getName() . "."); $event->getPlayer()->sendMessage("You can set it using /mine set " . $mine->getName() . " "); - unset($this->sessions[array_search($session, $this->sessions)]); - } - else{ + unset($this->sessions[array_search($session, $this->sessions, true)]); + } else { $event->getPlayer()->sendMessage("You have set position A. Tap another block to set position B."); } + } else { + $event->getPlayer()->sendMessage(TextFormat::RED . "Failed to create mine due to level switch" . TextFormat::RESET); + unset($this->sessions[array_search($session, $this->sessions, true)]); } - else{ - $event->getPlayer()->sendMessage(TextFormat::RED . "Failed to create mine due to level switch". TextFormat::RESET); - unset($this->sessions[array_search($session, $this->sessions)]); + } + } + + public function getPlayerSession(Player $player) + { + foreach ($this->sessions as $session) { + if ($session->getPlayer()->getName() === $player->getName()) { + return $session; } } + return null; } /** * @return MineReset */ - public function getApi(): MineReset{ + public function getApi(): MineReset + { return $this->api; } - public function playerHasSession(Player $player): bool { - foreach ($this->sessions as $session){ - if($session->getPlayer()->getName() === $player->getName()){ - return true; - } + public function addSession(MineCreationSession $session): bool + { + if (!$this->playerHasSession($session->getPlayer())) { + $this->sessions[] = $session; + return true; } return false; } - public function getPlayerSession(Player $player){ - foreach ($this->sessions as $session){ - if($session->getPlayer()->getName() === $player->getName()){ - return $session; + public function playerHasSession(Player $player): bool + { + foreach ($this->sessions as $session) { + if ($session->getPlayer()->getName() === $player->getName()) { + return true; } } - return null; - } - - - public function addSession(MineCreationSession $session): bool { - if(!$this->playerHasSession($session->getPlayer())) { - $this->sessions[] = $session; - return true; - } return false; } diff --git a/src/falkirks/minereset/listener/MineCreationSession.php b/src/falkirks/minereset/listener/MineCreationSession.php index 7dd7a41..f45a68b 100644 --- a/src/falkirks/minereset/listener/MineCreationSession.php +++ b/src/falkirks/minereset/listener/MineCreationSession.php @@ -2,31 +2,29 @@ namespace falkirks\minereset\listener; - +use falkirks\minereset\exception\InvalidStateException; use falkirks\minereset\Mine; use falkirks\minereset\MineManager; -use pocketmine\level\Level; use pocketmine\math\Vector3; -use pocketmine\Player; - -class MineCreationSession{ - /** @var string */ - private $name; - /** @var Player */ - private $player; - /** @var Vector3 */ - private $pointA; - /** @var Vector3 */ - private $pointB; - /** @var Level */ - private $level; +use pocketmine\player\Player; +use pocketmine\world\World; + +class MineCreationSession +{ + private string $name; + private Player $player; + private ?Vector3 $pointA; + private ?Vector3 $pointB; + private ?World $level; /** * MineCreationSession constructor. + * * @param string $name * @param Player $player */ - public function __construct(string $name, Player $player){ + public function __construct(string $name, Player $player) + { $this->name = $name; $this->player = $player; $this->pointA = null; @@ -37,92 +35,92 @@ public function __construct(string $name, Player $player){ /** * @return string */ - public function getName(): string{ + public function getName(): string + { return $this->name; } - /** - * @return Player - */ - public function getPlayer(): Player{ + public function getPlayer(): Player + { return $this->player; } - /** - * @param Player $player - */ - public function setPlayer(Player $player){ + public function setPlayer(Player $player): void + { $this->player = $player; } /** * @return Vector3 | null */ - public function getPointA(){ + public function getPointA(): ?Vector3 + { return $this->pointA; } /** * @param Vector3 $pointA */ - public function setPointA(Vector3 $pointA){ + public function setPointA(Vector3 $pointA): void + { $this->pointA = $pointA; } /** * @return Vector3 | null */ - public function getPointB(){ + public function getPointB(): ?Vector3 + { return $this->pointB; } /** * @param Vector3 $pointB */ - public function setPointB(Vector3 $pointB){ + public function setPointB(Vector3 $pointB): void + { $this->pointB = $pointB; } - /** - * @return Level | null - */ - public function getLevel(){ + public function getLevel(): ?World + { return $this->level; } - /** - * @param Level $level - */ - public function setLevel(Level $level){ + public function setLevel(World $level): void + { $this->level = $level; } - public function setNextPoint(Vector3 $point){ - if($this->pointA === null){ + public function setNextPoint(Vector3 $point): void + { + if ($this->pointA === null) { $this->setPointA($point); - } - else if($this->pointB === null){ + } else if ($this->pointB === null) { $this->setPointB($point); } } - public function canGenerate() : bool { - return $this->pointA !== null && $this->pointB !== null && $this->level !== null; - } - - public function generate(MineManager $owner): Mine{ - if($this->canGenerate()){ + /** + * @throws \falkirks\minereset\exception\InvalidStateException + */ + public function generate(MineManager $owner): Mine + { + if ($this->canGenerate()) { $mine = new Mine($owner, new Vector3(min($this->pointA->getFloorX(), $this->pointB->getFloorX()), min($this->pointA->getFloorY(), $this->pointB->getFloorY()), min($this->pointA->getFloorZ(), $this->pointB->getFloorZ())), new Vector3(max($this->pointA->getFloorX(), $this->pointB->getFloorX()), max($this->pointA->getFloorY(), $this->pointB->getFloorY()), max($this->pointA->getFloorZ(), $this->pointB->getFloorZ())), - $this->level->getName(), + $this->level->getFolderName(), $this->name); $owner[$this->name] = $mine; return $mine; } - else{ - throw new \InvalidStateException(); - } + + throw new InvalidStateException(); } + public function canGenerate(): bool + { + return $this->pointA !== null && $this->pointB !== null && $this->level !== null; + } } \ No newline at end of file diff --git a/src/falkirks/minereset/listener/RegionBlockerListener.php b/src/falkirks/minereset/listener/RegionBlockerListener.php index 88540c2..07ef8f6 100644 --- a/src/falkirks/minereset/listener/RegionBlockerListener.php +++ b/src/falkirks/minereset/listener/RegionBlockerListener.php @@ -1,6 +1,6 @@ api = $api; } - public function teleportPlayer(Player $player, Mine $mine){ - - $swarp = $this->getApi()->getServer()->getPluginManager()->getPlugin('SimpleWarp'); - if($mine->hasWarp() && $swarp instanceof SimpleWarp){ - $swarp->getApi()->warpPlayerTo($player, $mine->getWarpName()); - } else { - $player->teleport($player->getLevel()->getSafeSpawn($player->getPosition())); - } - } - - - public function clearMine(string $mineName){ + public function clearMine(string $mineName): void + { /** @var Mine $mine */ $mine = $this->getApi()->getMineManager()[$mineName]; - if($mine !== null){ - foreach ($this->getApi()->getServer()->getOnlinePlayers() as $player){ - if($mine->isPointInside($player->getPosition())){ + if ($mine !== null) { + foreach ($this->getApi()->getServer()->getOnlinePlayers() as $player) { + if ($mine->isPointInside($player->getPosition())) { $this->teleportPlayer($player, $mine); $player->sendMessage("You have teleported to escape a resetting mine."); } @@ -50,36 +42,45 @@ public function clearMine(string $mineName){ } /** - * @priority HIGH - * - * @param BlockPlaceEvent $event + * @return MineReset */ - public function onBlockPlace(BlockPlaceEvent $event){ + public function getApi(): MineReset + { + return $this->api; + } - $mine = $this->getResettingMineAtPosition($event->getBlock()); - if($mine != null){ - $event->getPlayer()->sendMessage(TextFormat::RED . "A mine is currently resetting in this area. You may not place blocks." . TextFormat::RESET); - $event->setCancelled(); + + /** @noinspection NotOptimalIfConditionsInspection */ + /** @noinspection PhpUndefinedClassInspection */ + public function teleportPlayer(Player $player, Mine $mine): void + { + $swarp = $this->getApi()->getServer()->getPluginManager()->getPlugin('SimpleWarp'); + if ($mine->hasWarp() && $swarp instanceof SimpleWarp) { + $swarp->getApi()->warpPlayerTo($player, $mine->getWarpName()); + } else { + $player->teleport($player->getWorld()->getSafeSpawn($player->getPosition())); } } /** * @priority HIGH * - * @param BlockBreakEvent $event + * @param BlockPlaceEvent $event */ - public function onBlockDestroy(BlockBreakEvent $event){ + public function onBlockPlace(BlockPlaceEvent $event): void + { - $mine = $this->getResettingMineAtPosition($event->getBlock()); - if($mine != null){ - $event->getPlayer()->sendMessage(TextFormat::RED . "A mine is currently resetting in this area. You may not break blocks." . TextFormat::RESET); - $event->setCancelled(); + $mine = $this->getResettingMineAtPosition($event->getBlock()->getPosition()); + if ($mine !== null) { + $event->getPlayer()->sendMessage(TextFormat::RED . "A mine is currently resetting in this area. You may not place blocks." . TextFormat::RESET); + $event->cancel(); } } - private function getResettingMineAtPosition(Position $position){ + private function getResettingMineAtPosition(Position $position) + { foreach ($this->getApi()->getMineManager() as $mine) { - if($mine->isResetting() && $mine->isPointInside($position)){ + if ($mine->isResetting() && $mine->isPointInside($position)) { return $mine; } } @@ -87,10 +88,18 @@ private function getResettingMineAtPosition(Position $position){ } /** - * @return MineReset + * @priority HIGH + * + * @param BlockBreakEvent $event */ - public function getApi(): MineReset{ - return $this->api; + public function onBlockDestroy(BlockBreakEvent $event): void + { + + $mine = $this->getResettingMineAtPosition($event->getBlock()->getPosition()); + if ($mine !== null) { + $event->getPlayer()->sendMessage(TextFormat::RED . "A mine is currently resetting in this area. You may not break blocks." . TextFormat::RESET); + $event->cancel(); + } } diff --git a/src/falkirks/minereset/store/AbstractStore.php b/src/falkirks/minereset/store/AbstractStore.php index 4ff287f..8a8c4f7 100644 --- a/src/falkirks/minereset/store/AbstractStore.php +++ b/src/falkirks/minereset/store/AbstractStore.php @@ -1,4 +1,5 @@ $mine){ +abstract class AbstractStore implements DataStore +{ + public function addAll($mines): void + { + foreach ($mines as $name => $mine) { $this->add($name, $mine); } } - public function removeAll($mines){ - foreach($mines as $mine){ + + public function removeAll($mines): void + { + foreach ($mines as $mine) { $this->remove($mine); } } - public function exists($name): bool{ + + public function exists($name): bool + { return $this->get($name) !== null; } } \ No newline at end of file diff --git a/src/falkirks/minereset/store/ConfigStore.php b/src/falkirks/minereset/store/ConfigStore.php index 1bbfa46..9f4d915 100644 --- a/src/falkirks/minereset/store/ConfigStore.php +++ b/src/falkirks/minereset/store/ConfigStore.php @@ -1,52 +1,60 @@ config = $config; } /** * Adds a new mine and returns the old one + * * @param $name - * @param $warp - * @return bool|mixed + * @param $mine + * + * @throws \JsonException */ - public function add($name, $mine){ + public function add($name, $mine) + { $past = $this->config->get($name, null); $this->config->set($name, $mine); $this->config->save(); return $past; } - /** - * Gets mine with $name - * @param $name - * @return bool|mixed - */ - public function get($name){ + public function get($name) + { return $this->config->get($name, null); } /** * Removes a mine with $name and returns it + * * @param $name + * * @return bool|mixed + * @throws \JsonException */ - public function remove($name){ + public function remove($name): mixed + { $past = $this->config->get($name, null); $this->config->remove($name); $this->config->save(); @@ -55,8 +63,11 @@ public function remove($name){ /** * Clears all mines + * + * @throws \JsonException */ - public function clear(){ + public function clear(): void + { $this->config->setAll([]); $this->config->save(); } @@ -64,22 +75,29 @@ public function clear(){ /** * Reloads the mines from YAML */ - public function reload(){ + public function reload(): void + { $this->config->reload(); } + /** * Returns something which can be used to iterate * over the store. - * @return mixed + * + * @return array */ - public function getIterator(){ + public function getIterator(): array + { return $this->config->getAll(); } /** * Saves mines to file + * + * @throws \JsonException */ - public function save(){ + public function save(): void + { $this->config->save(); } } \ No newline at end of file diff --git a/src/falkirks/minereset/store/DataStore.php b/src/falkirks/minereset/store/DataStore.php index af69506..a6e5db4 100644 --- a/src/falkirks/minereset/store/DataStore.php +++ b/src/falkirks/minereset/store/DataStore.php @@ -1,4 +1,5 @@ api = $api; $this->store = []; } - public function storeEntities($mineName, $entities){ + public function storeEntities($mineName, $entities) + { $this->store[$mineName] = $entities; } - public function retrieveEntities($mineName){ - if(isset($this->store[$mineName])){ + public function retrieveEntities($mineName) + { + if (isset($this->store[$mineName])) { $entities = $this->store[$mineName]; unset($this->store[$mineName]); return $entities; diff --git a/src/falkirks/minereset/store/Reloadable.php b/src/falkirks/minereset/store/Reloadable.php index 9ed43ea..bf1ece8 100644 --- a/src/falkirks/minereset/store/Reloadable.php +++ b/src/falkirks/minereset/store/Reloadable.php @@ -1,7 +1,9 @@ storeLocal($sender); - } - - - public function onRun() : void { - if(method_exists(Utils::class, "getURL")){ - $this->setResult(Utils::getURL(AboutPullTask::ABOUT_URL)); - } - else { - $this->setResult(Internet::getURL(AboutPullTask::ABOUT_URL)); - } - - } - - public function onCompletion(Server $server = null) : void { - $sender = $this->fetchLocal(); - if($sender instanceof CommandSender) { - $result = $this->getResult(); - if ($result !== false) { - $sender->sendMessage($this->getResult()); - } else { - $sender->sendMessage("MineReset by Falkirks. This is a fancy plugin that allows you to make resettable mines."); - } - } - } - - -} diff --git a/src/falkirks/minereset/task/ResetTask.php b/src/falkirks/minereset/task/ResetTask.php index 9e9d5a7..215b99b 100644 --- a/src/falkirks/minereset/task/ResetTask.php +++ b/src/falkirks/minereset/task/ResetTask.php @@ -1,63 +1,66 @@ name = $name; $this->chunks = serialize($chunks); $this->a = $a; $this->b = $b; $this->ratioData = serialize($data); $this->levelId = $levelId; - $this->chunkClass = $chunkClass; $this->parserClass = BlockStringParser::class; } + /** * Actions to execute when run * * @return void + * @throws \Exception */ - public function onRun() : void { - $chunkClass = $this->chunkClass; + public function onRun(): void + { /** @var Chunk[] $chunks */ - $chunks = unserialize($this->chunks); - foreach($chunks as $hash => $binary){ - $chunks[$hash] = $chunkClass::fastDeserialize($binary); + $chunks = unserialize($this->chunks, [""]); + foreach ($chunks as $hash => $binary) { + $chunks[$hash] = FastChunkSerializer::serializeTerrain($binary); } $sum = []; - $id = array_map([$this->parserClass, "parse"], array_keys(unserialize($this->ratioData))); + $id = array_map([$this->parserClass, "parse"], array_keys(unserialize($this->ratioData, [""]))); - $m = array_values(unserialize($this->ratioData)); + $m = array_values(unserialize($this->ratioData, [""])); $sum[0] = $m[0]; - for ($l = 1, $mCount = count($m); $l < $mCount; $l++) + for ($l = 1, $mCount = count($m); $l < $mCount; $l++) { $sum[$l] = $sum[$l - 1] + $m[$l]; + } $sumCount = count($sum); @@ -65,7 +68,7 @@ public function onRun() : void { $posA = $this->a; $posB = $this->b; - $totalBlocks = ($posB->x - $posA->x + 1)*($posB->y - $posA->y + 1)*($posB->z - $posA->z + 1); + $totalBlocks = ($posB->x - $posA->x + 1) * ($posB->y - $posA->y + 1) * ($posB->z - $posA->z + 1); $interval = $totalBlocks / 8; //TODO determine the interval programmatically $lastUpdate = 0; $currentBlocks = 0; @@ -82,14 +85,14 @@ public function onRun() : void { $chunkX = $x >> 4; for ($z = $posA->getZ(), $z2 = $posB->getZ(); $z <= $z2; $z++) { $chunkZ = $z >> 4; - if($currentChunk === null or $chunkX !== $currentChunkX or $chunkZ !== $currentChunkZ){ + if ($currentChunk === null or $chunkX !== $currentChunkX or $chunkZ !== $currentChunkZ) { $currentChunkX = $chunkX; $currentChunkZ = $chunkZ; $currentSubChunk = null; - $hash = Level::chunkHash($chunkX, $chunkZ); + $hash = World::chunkHash($chunkX, $chunkZ); $currentChunk = $chunks[$hash]; - if($currentChunk === null){ + if ($currentChunk === null) { continue; } } @@ -97,27 +100,26 @@ public function onRun() : void { for ($y = $posA->getY(), $y2 = $posB->getY(); $y <= $y2; $y++) { $chunkY = $y >> 4; - if($currentSubChunk === null or $chunkY !== $currentChunkY){ + if ($currentSubChunk === null || $chunkY !== $currentChunkY) { $currentChunkY = $chunkY; $currentSubChunk = $currentChunk->getSubChunk($chunkY, true); - if($currentSubChunk === null){ + if ($currentSubChunk === null) { continue; } } - $a = rand(0, end($sum)); + $a = random_int(0, end($sum)); for ($l = 0; $l < $sumCount; $l++) { if ($a <= $sum[$l]) { - $currentSubChunk->setBlock($x & 0x0f, $y & 0x0f, $z & 0x0f, $id[$l][0] & 0xff, $id[$l][1] & 0xff); + $currentSubChunk->setFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f, $id[$l][0] << Block::INTERNAL_METADATA_BITS | $id[$l][1] & 0xff); $currentBlocks++; - if($lastUpdate + $interval <= $currentBlocks){ - if(method_exists($this, 'publishProgress')) { + if ($lastUpdate + $interval <= $currentBlocks) { + if (method_exists($this, 'publishProgress')) { $this->publishProgress(round(($currentBlocks / $totalBlocks) * 100) . "%"); } $lastUpdate = $currentBlocks; } - break; } } @@ -126,20 +128,17 @@ public function onRun() : void { } $this->setResult($chunks); } - /** - * @param Server $server - */ - public function onCompletion(Server $server = null) : void { - if($server === null){ - $server = Server::getInstance(); - } + + public function onCompletion(): void + { + $server = Server::getInstance(); $chunks = $this->getResult(); $plugin = $server->getPluginManager()->getPlugin("MineReset"); - if($plugin instanceof MineReset and $plugin->isEnabled()) { - $level = $server->getLevel($this->levelId); - if ($level instanceof Level) { + if ($plugin instanceof MineReset && $plugin->isEnabled()) { + $level = $server->getWorldManager()->getWorld($this->levelId); + if ($level instanceof World) { foreach ($chunks as $hash => $chunk) { - Level::getXZ($hash, $x, $z); + World::getXZ($hash, $x, $z); $level->setChunk($x, $z, $chunk, !MineReset::supportsChunkSetting()); } @@ -149,17 +148,12 @@ public function onCompletion(Server $server = null) : void { } } - /** - * @param mixed $server - * @param mixed $progress - */ - public function onProgressUpdate($server, $progress = null): void { - if($progress === null){ - $progress = $server; - $server = Server::getInstance(); - } + + public function onProgressUpdate($progress): void + { + $server = Server::getInstance(); $plugin = $server->getPluginManager()->getPlugin("MineReset"); - if($plugin instanceof MineReset and $plugin->isEnabled()) { + if ($plugin instanceof MineReset && $plugin->isEnabled()) { $plugin->getResetProgressManager()->notifyProgress($progress, $this->name); } } diff --git a/src/falkirks/minereset/util/BlockStringParser.php b/src/falkirks/minereset/util/BlockStringParser.php index c9998f3..17935a6 100644 --- a/src/falkirks/minereset/util/BlockStringParser.php +++ b/src/falkirks/minereset/util/BlockStringParser.php @@ -8,28 +8,23 @@ namespace falkirks\minereset\util; - use falkirks\minereset\exception\InvalidBlockStringException; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; +use ReflectionClass; -class BlockStringParser{ +class BlockStringParser +{ private static $blockMap; - private static function ensureMap(){ - if(!is_array(self::$blockMap)) { - self::$blockMap = (new \ReflectionClass(BlockIds::class))->getConstants(); - } - } - - - public static function isValid(string $str): bool { + public static function isValid(string $str): bool + { self::ensureMap(); - if(is_numeric($str) || isset(self::$blockMap[strtoupper($str)])){ + if (is_numeric($str) || isset(self::$blockMap[strtoupper($str)])) { return true; } $arr = explode(":", $str); - if(count($arr) === 2 && is_numeric($arr[1])){ + if (count($arr) === 2 && is_numeric($arr[1])) { return is_numeric($arr[0]) || isset(self::$blockMap[strtoupper($arr[0])]); } @@ -37,33 +32,43 @@ public static function isValid(string $str): bool { } + private static function ensureMap(): void + { + if (!is_array(self::$blockMap)) { + self::$blockMap = (new ReflectionClass(BlockLegacyIds::class))->getConstants(); + } + } + /** * @param string $str + * * @return array * @throws InvalidBlockStringException */ - public static function parse(string $str): array{ + public static function parse(string $str): array + { self::ensureMap(); if (is_numeric($str)) { return [$str, 0]; } - elseif(isset(self::$blockMap[strtoupper($str)])){ + + if (isset(self::$blockMap[strtoupper($str)])) { return [self::$blockMap[strtoupper($str)], 0]; } $arr = explode(":", $str); if (count($arr) === 2 && is_numeric($arr[1])) { - if(is_numeric($arr[0])){ + if (is_numeric($arr[0])) { return [$arr[0], $arr[1]]; } - elseif(isset(self::$blockMap[strtoupper($arr[0])])){ + + if (isset(self::$blockMap[strtoupper($arr[0])])) { return [self::$blockMap[strtoupper($arr[0])], $arr[1]]; } } throw new InvalidBlockStringException(); } - } \ No newline at end of file diff --git a/src/falkirks/minereset/util/DebugDumpFactory.php b/src/falkirks/minereset/util/DebugDumpFactory.php index 81331a0..95d6038 100644 --- a/src/falkirks/minereset/util/DebugDumpFactory.php +++ b/src/falkirks/minereset/util/DebugDumpFactory.php @@ -3,23 +3,35 @@ namespace falkirks\minereset\util; -use falkirks\minereset\Mine; use falkirks\minereset\MineReset; -class DebugDumpFactory{ +class DebugDumpFactory +{ /** @var MineReset */ - private $api; + private MineReset $api; /** * DebugDump constructor. */ - public function __construct(MineReset $mineReset){ + public function __construct(MineReset $mineReset) + { $this->api = $mineReset; } + /** + * @throws \JsonException + */ + public function __toString() + { + return $this->generate(); + } - public function generate(): string { + /** + * @throws \JsonException + */ + public function generate(): string + { return implode("\n", [ "SERVER VERSION: " . $this->getApi()->getServer()->getPocketMineVersion(), "API: " . $this->getApi()->getServer()->getApiVersion(), @@ -28,19 +40,15 @@ public function generate(): string { "MineReset Version: " . $this->getApi()->getDescription()->getVersion(), "PLUGINS: " . implode(",", array_keys($this->getApi()->getServer()->getPluginManager()->getPlugins())), "storage-mode: " . $this->getApi()->getMineManager()->getFlag(), - json_encode($this->getApi()->getMineManager()->getMines(), JSON_PRETTY_PRINT) + json_encode($this->getApi()->getMineManager()->getMines(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT) ]); } - - function __toString(){ - return $this->generate(); - } - /** * @return MineReset */ - public function getApi(): MineReset{ + public function getApi(): MineReset + { return $this->api; } } \ No newline at end of file