Skip to content

Commit 873be5f

Browse files
authored
Merge pull request #40 from tedo0627/selector
corresponds to selector
2 parents 492bcf9 + 9517e5b commit 873be5f

25 files changed

+1088
-9
lines changed

RedstoneCircuit/src/redstone/blockEntities/BlockEntityCommandBlock.php

+59-9
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
use redstone\blocks\BlockCommandChain;
3939
use redstone\blocks\BlockCommandRepeating;
4040

41+
use redstone\selector\CommandSelector;
42+
4143
use redstone\inventories\CommandInventory;
4244

4345
class BlockEntityCommandBlock extends Spawnable implements InventoryHolder, Container, Nameable, CommandSender {
@@ -170,9 +172,34 @@ public function dispatch() : void {
170172

171173
$target->timings->startTiming();
172174

175+
for ($i = 0; $i < count($args); ++$i) {
176+
$str = $args[$i];
177+
if (strlen($str) == 0) {
178+
continue;
179+
}
180+
181+
if (substr($str, 0, 1) != "@") {
182+
continue;
183+
}
184+
185+
$selector = new CommandSelector();
186+
$entities = $selector->getEntities($this, $str);
187+
if (count($entities) == 0) {
188+
continue;
189+
}
190+
191+
$args[$i] = $entities;
192+
}
193+
194+
$commands = $this->getSelectorCommand($sentCommandLabel, $args);
173195
$conditions = false;
174-
try{
175-
$conditions = $target->execute($this, $sentCommandLabel, $args);
196+
try {
197+
foreach ($commands as $command) {
198+
$bool = $target->execute($this, $sentCommandLabel, $command);
199+
if ($bool) {
200+
$conditions = true;
201+
}
202+
}
176203
}catch(InvalidCommandSyntaxException $e){
177204
$this->sendMessage($this->getServer()->getLanguage()->translateString("commands.generic.usage", [$target->getUsage()]));
178205
}finally{
@@ -194,6 +221,30 @@ public function dispatch() : void {
194221
return;
195222
}
196223

224+
private function getSelectorCommand(string $label, array $args) : array {
225+
$array = [];
226+
$check = false;
227+
for ($i = 0; $i < count($args); ++$i) {
228+
$arg = $args[$i];
229+
if (is_string($arg)) {
230+
continue;
231+
}
232+
233+
foreach ($arg as $entity) {
234+
$copy = $args;
235+
$copy[$i] = $entity instanceof Player ? $entity->getName() : strval($entity->getId());
236+
$array = array_merge($array, $this->getSelectorCommand($label, $copy));
237+
$check = true;
238+
}
239+
}
240+
241+
if (!$check) {
242+
$array[] = $args;
243+
}
244+
245+
return $array;
246+
}
247+
197248
public function isNormal() : bool {
198249
return $this->getCommandBlockMode() == 0;
199250
}
@@ -280,7 +331,12 @@ public function setPowered(bool $power) : void {
280331
$this->powered = $power;
281332
}
282333

283-
//interface CommandSender
334+
// interface method
335+
336+
private $attachments = [];
337+
338+
private $permissions = [];
339+
284340

285341
public function sendMessage($message) {
286342
if($message instanceof TextContainer){
@@ -303,12 +359,6 @@ public function setScreenLineHeight(int $height = null) {
303359

304360
}
305361

306-
//interface Permissible
307-
308-
private $attachments = [];
309-
310-
private $permissions = [];
311-
312362
public function isOp() : bool{
313363
return true;
314364
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<?php
2+
3+
namespace redstone\selector;
4+
5+
use pocketmine\command\CommandSender;
6+
7+
8+
use redstone\selector\arguments\DistanceArgument;
9+
use redstone\selector\arguments\EntityTypeArgument;
10+
use redstone\selector\arguments\GamemodeArgument;
11+
use redstone\selector\arguments\IArgument;
12+
use redstone\selector\arguments\LevelArgument;
13+
use redstone\selector\arguments\LimitArgument;
14+
use redstone\selector\arguments\NameArgument;
15+
use redstone\selector\arguments\WorldArgument;
16+
use redstone\selector\arguments\XPositionArgument;
17+
use redstone\selector\arguments\XRelativePositionArgument;
18+
use redstone\selector\arguments\XRotationArgument;
19+
use redstone\selector\arguments\YPositionArgument;
20+
use redstone\selector\arguments\YRelativePositionArgument;
21+
use redstone\selector\arguments\YRotationArgument;
22+
use redstone\selector\arguments\ZPositionArgument;
23+
use redstone\selector\arguments\ZRelativePositionArgument;
24+
25+
use redstone\selector\variables\AllEntityVariable;
26+
use redstone\selector\variables\AllPlayerVariable;
27+
use redstone\selector\variables\IVariable;
28+
use redstone\selector\variables\NearestPlayerVariable;
29+
use redstone\selector\variables\RandomPlayerVariable;
30+
use redstone\selector\variables\SenderVariable;
31+
32+
class CommandSelector {
33+
34+
private $variables = [];
35+
private $arguments = [];
36+
37+
public function __construct() {
38+
$this->initVariables();
39+
$this->initArgument();
40+
}
41+
42+
private function initVariables() : void {
43+
$this->registerVariable(new AllEntityVariable());
44+
$this->registerVariable(new AllPlayerVariable());
45+
$this->registerVariable(new NearestPlayerVariable());
46+
$this->registerVariable(new RandomPlayerVariable());
47+
$this->registerVariable(new SenderVariable());
48+
}
49+
50+
private function initArgument() : void {
51+
$this->registerArgument(new DistanceArgument());
52+
$this->registerArgument(new EntityTypeArgument());
53+
$this->registerArgument(new GamemodeArgument());
54+
$this->registerArgument(new LevelArgument());
55+
$this->registerArgument(new LimitArgument());
56+
$this->registerArgument(new NameArgument());
57+
$this->registerArgument(new WorldArgument());
58+
$this->registerArgument(new XPositionArgument());
59+
$this->registerArgument(new XRelativePositionArgument());
60+
$this->registerArgument(new XRotationArgument());
61+
$this->registerArgument(new YPositionArgument());
62+
$this->registerArgument(new YRelativePositionArgument());
63+
$this->registerArgument(new YRotationArgument());
64+
$this->registerArgument(new ZPositionArgument());
65+
$this->registerArgument(new ZRelativePositionArgument());
66+
}
67+
68+
public function registerVariable(IVariable $variable) : void {
69+
$this->variables[$variable->getVariable()] = $variable;
70+
}
71+
72+
public function existVariable(string $key) : bool {
73+
return array_key_exists($key, $this->variables);
74+
}
75+
76+
public function getVariable(string $key) : ?IVariable {
77+
if ($this->existVariable($key)) {
78+
return $this->variables[$key];
79+
}
80+
return null;
81+
}
82+
83+
public function removeVariable(string $key) : void {
84+
unset($this->variables[$key]);
85+
}
86+
87+
public function registerArgument(IArgument $argument) : void {
88+
$this->arguments[$argument->getArgument()] = $argument;
89+
}
90+
91+
public function existArgument(string $key) : bool {
92+
return array_key_exists($key, $this->arguments);
93+
}
94+
95+
public function getArgument(string $key) : ?IArgument {
96+
if ($this->existArgument($key)) {
97+
return $this->arguments[$key];
98+
}
99+
return null;
100+
}
101+
102+
public function removeArgument(string $key) : void {
103+
unset($this->arguments[$key]);
104+
}
105+
106+
public function getEntities(CommandSender $sender, string $args) : array {
107+
$key = substr($args, 1, 1);
108+
if (!array_key_exists($key, $this->variables)) {
109+
return [];
110+
}
111+
112+
$variable = $this->variables[$key];
113+
114+
$arguments = [];
115+
if (strlen($args) > 6) { //@p[r=1] > 6
116+
$str = substr($args, 2, strlen($args) - 2);
117+
if ($str[0] == "[" && $str[strlen($str) - 1] = "]") {
118+
$str = substr($str, 1, -1);
119+
$str = preg_replace("/ /", "", $str);
120+
$split = explode(",", $str);
121+
foreach ($split as $s) {
122+
$pair = explode("=", $s);
123+
if (count($pair) < 2) {
124+
continue;
125+
}
126+
127+
$key = $pair[0];
128+
if (substr($key, -1) == "!") {
129+
$key = substr($key, 0, -1);
130+
}
131+
132+
if (!array_key_exists($key, $this->arguments)) {
133+
continue;
134+
}
135+
136+
$arguments[] = $this->arguments[$key];
137+
}
138+
}
139+
}
140+
141+
$players = $variable->getEntities($sender, $args, $arguments);
142+
foreach ($arguments as $arg) {
143+
$players = $arg->selectgetEntities($sender, $args, $arguments, $players);
144+
}
145+
146+
return $players;
147+
}
148+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace redstone\selector\arguments;
4+
5+
use pocketmine\command\CommandSender;
6+
7+
abstract class BaseArgument implements IArgument {
8+
9+
public abstract function getArgument() : string;
10+
11+
public function getValue(string $argument) : string {
12+
$key = $this->getArgument();
13+
14+
$str = strstr($argument, "[");
15+
$str = substr($str, 1, -1);
16+
$str = preg_replace("/ /", "", $str);
17+
$split = explode(",", $str);
18+
foreach ($split as $s) {
19+
$pair = explode("=", $s);
20+
if (count($pair) < 2) {
21+
continue;
22+
}
23+
24+
$k = $pair[0];
25+
if (substr($k, -1) == "!") {
26+
$k = substr($k, 0, -1);
27+
}
28+
29+
if ($k == $key) {
30+
return $pair[1];
31+
}
32+
}
33+
34+
return "";
35+
}
36+
37+
public function isExcluded(string $argument) : bool {
38+
$key = $this->getArgument();
39+
40+
$str = strstr($argument, "[");
41+
$str = substr($str, 1, -1);
42+
$str = preg_replace("/ /", "", $str);
43+
$split = explode(",", $str);
44+
foreach ($split as $s) {
45+
$pair = explode("=", $s);
46+
if (count($pair) < 2) {
47+
continue;
48+
}
49+
50+
if ($pair[0] == $key) {
51+
continue;
52+
}
53+
54+
return substr($pair[0], -1) == "!";
55+
}
56+
57+
return false;
58+
}
59+
60+
public abstract function selectgetEntities(CommandSender $sender, string $argument, array $arguments, array $entities) : array;
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
namespace redstone\selector\arguments;
4+
5+
use pocketmine\command\CommandSender;
6+
7+
use pocketmine\level\Position;
8+
9+
class DistanceArgument extends BaseArgument {
10+
11+
public function getArgument() : string {
12+
return "r";
13+
}
14+
15+
public function selectgetEntities(CommandSender $sender, string $argument, array $arguments, array $entities) : array {
16+
if (!($sender instanceof Position)) {
17+
return [];
18+
}
19+
20+
$array = [];
21+
$value = $this->getValue($argument);
22+
if (ctype_digit($value)) {
23+
$rage = floatval($value);
24+
foreach ($entities as $entity) {
25+
if ($entity->distance($sender) == $rage) {
26+
$array[] = $entity;
27+
}
28+
}
29+
return $array;
30+
}
31+
32+
$split = explode("..", $value);
33+
if (count($split) < 2) {
34+
return [];
35+
}
36+
37+
if ($split[0] == "") {
38+
$rage = floatval($split[1]);
39+
foreach ($entities as $entity) {
40+
if ($entity->distance($sender) <= $rage) {
41+
$array[] = $entity;
42+
}
43+
}
44+
return $array;
45+
}
46+
47+
if ($split[1] == "") {
48+
$rage = floatval($split[0]);
49+
foreach ($entities as $entity) {
50+
if ($entity->distance($sender) >= $rage) {
51+
$array[] = $entity;
52+
}
53+
}
54+
return $array;
55+
}
56+
57+
$min = floatval($split[0]);
58+
$max = floatval($split[1]);
59+
60+
foreach ($entities as $entity) {
61+
$distance = $entity->distance($sender);
62+
if ($min <= $distance && $distance <= $max) {
63+
$array[] = $entity;
64+
}
65+
}
66+
return $array;
67+
}
68+
}

0 commit comments

Comments
 (0)