Compare commits

..

196 Commits

Author SHA1 Message Date
9a7d94cd1c Merge branch 'major-next' into command-alias-handling 2025-08-03 16:20:29 +01:00
e630fc2dd6 Merge remote-tracking branch 'origin/minor-next' into major-next 2025-07-31 13:00:12 +01:00
79e3f2b281 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/16533775916
2025-07-26 00:03:00 +00:00
7fbd868bc1 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/16484425188
2025-07-24 00:03:17 +00:00
c02feba056 Merge remote-tracking branch 'origin/minor-next' into major-next 2025-07-10 01:58:34 +01:00
a3efaad328 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/16012796137
2025-07-02 16:00:27 +00:00
98f0417611 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15889715513
2025-06-26 00:03:07 +00:00
afcd6b4e12 Merge remote-tracking branch 'origin/minor-next' into major-next 2025-06-25 01:07:16 +01:00
68126b308a Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15800888918
2025-06-22 00:03:38 +00:00
e4b6f96535 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15789835501
2025-06-21 00:02:58 +00:00
f8ed7efb3f Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15746137301
2025-06-19 00:03:12 +00:00
6340d12881 Merge branch 'minor-next' into major-next 2025-06-18 19:56:54 +01:00
6d32ea5850 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15598290427
2025-06-12 00:02:57 +00:00
8229ee1812 ChunkLoader is now a final class (#6730) 2025-06-11 21:02:31 +01:00
950fb48bcb Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15523860509
2025-06-09 00:03:27 +00:00
9e773ed439 PHPUnit migrated to attributes :( 2025-06-08 19:19:17 +01:00
6b5ff5016e Fixed double loading of PluginDescription
closes #4593
closes #6723
2025-06-08 19:09:12 +01:00
215da7e3f4 PHP 8.3 package bumps 2025-06-08 18:58:42 +01:00
c3ea6edc22 Bump minimum PHP version to 8.3 2025-06-08 18:49:27 +01:00
0330b25768 Merge branch 'minor-next' into major-next 2025-06-08 18:44:54 +01:00
d5a1007c80 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15288247521
2025-05-28 00:03:15 +00:00
dca2665e17 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15243296100
2025-05-26 00:02:56 +00:00
05eda887b1 Item: make setter methods fluent (#6678)
- `Item::clearCustomBlockData` previously, the instance was returned, but the return type has been changed
- `Item::setCanPlaceOn`, `Item::setCanDestroy` and `Item::setKeepOnDeath` now return `$this`
2025-05-25 10:35:26 +02:00
18b6b1742c Rename PlayerExhaustEvent to EntityExhaustEvent (#6674)
Removed the `getPlayer` function
2025-05-25 10:04:33 +02:00
b20d1b84b5 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15232190072
2025-05-25 00:03:31 +00:00
de1573728e Merge branch 'major-next' into command-alias-handling 2025-05-24 15:36:57 +01:00
a8e898b13b Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15221216334
2025-05-24 00:02:50 +00:00
d907d72e9b Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15090310700
2025-05-18 00:03:34 +00:00
9d532b6e95 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/15087062558
2025-05-17 16:31:33 +00:00
bb7bfee0cd Remove ServerEvent class (#6695) 2025-05-14 08:06:22 +02:00
88cdc2eb67 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14951134662
2025-05-11 01:49:35 +00:00
112bcf7af9 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14940598161
2025-05-10 01:40:10 +00:00
1c70cee72e Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14931383427
2025-05-09 14:38:29 +00:00
7847524df6 Merge branch 'minor-next' into major-next 2025-05-08 02:28:09 +01:00
bc54380876 CS 2025-05-04 17:22:51 +01:00
8035d6619d Merge branch 'major-next' into command-alias-handling 2025-05-04 17:22:27 +01:00
1d26b21fe0 Merge branch 'minor-next' into major-next 2025-05-04 17:21:24 +01:00
91dad0a5b5 Merge branch 'major-next' into command-alias-handling 2025-05-04 17:10:12 +01:00
eb3922fc7e shut 2025-05-04 17:10:01 +01:00
912a5d6ad0 Remove TODO 2025-05-04 16:45:25 +01:00
2a42e2c75d Drop PluginLoader from Plugin, expose path instead
we already had this anyway, and it's already being reflected into.
Instead of DevTools checking for FolderPluginLoader instances, it
could just check if the file is a directory instead.
2025-05-04 16:44:28 +01:00
7eff658ade Add ability to register & unregister specific command aliases for existing commands 2025-05-04 16:07:31 +01:00
084774e56c Don't allow registering the same command instance twice 2025-05-04 15:48:24 +01:00
579aecfad7 First step in restructuring command alias handling
This decouples Command from CommandMap, and moves the burden of tracking registered
aliases to CommandMap. This allows lots of simplification, and also solves a few
weird usage message issues.

- Active (registered) aliases are now tracked via CommandMapEntry
- Commands overriding other commands' aliases now update the original command's registered alias list properly
- Command alias lists now include prefixed aliases
- Prefixed aliases are now included in command data provided to the client
- Server-side /pocketmine:help is now visible on the client
- Permission testing can now provide context that's more relevant to the command invocation - e.g. if a user doesn't have /time set permission, it'll now show a more specific message where previously it would just show that the permission for /time was denied
- User-specified label is now used for permission messages instead of command name - this is more consistent with user expectations
- /help can now see prefixed aliases
- Removed magic alias registration behaviour for VanillaCommand that I don't think anyone expected
- Aliases are now provided to CommandMap via register() parameters, instead of being retrieved from the provided Command
- Command->get/setAliases(), get/setLabel() and getName() are removed
- Command->getName() pushed down to PluginCommand, as it's only useful for CommandExecutors as a command ID and shouldn't be used anywhere else
2025-05-04 15:23:25 +01:00
3de604ef95 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14816570368
2025-05-04 01:51:27 +00:00
cb4364f8fd Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14786989960
2025-05-02 01:42:53 +00:00
5bfa40618d Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14768020274
2025-05-01 01:50:54 +00:00
8e1426e25e Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14687149888
2025-04-27 01:46:41 +00:00
d86943fa8c Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14565559872
2025-04-21 01:45:18 +00:00
baee0110c7 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14544397106
2025-04-19 01:36:21 +00:00
5617347949 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14482870321
2025-04-16 01:41:53 +00:00
0bbe56beb4 Merge branch 'minor-next' into major-next 2025-04-06 20:01:23 +01:00
94caea97e0 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14287788168
2025-04-06 01:43:19 +00:00
ad95f392c1 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14233077278
2025-04-03 01:38:27 +00:00
9af3cde03f Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14120132647
2025-03-28 01:37:50 +00:00
72f1391bd9 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14049692123
2025-03-25 01:38:30 +00:00
a90e5a6aa2 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/14014323991
2025-03-23 01:42:16 +00:00
df5f87e309 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13913481960
2025-03-18 01:37:04 +00:00
510ef94698 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13878654456
2025-03-16 01:41:31 +00:00
d3f40b7b0c Merge branch 'minor-next' into major-next 2025-03-15 20:37:37 +00:00
dae3e2b336 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13868087288
2025-03-15 01:26:48 +00:00
f2fa5933ea Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13825107599
2025-03-13 01:36:48 +00:00
95a324755b Merge branch 'minor-next' into major-next 2025-03-10 01:31:34 +00:00
1d13054608 Merge branch 'minor-next' into major-next 2025-03-09 01:18:55 +00:00
ec140f7861 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13666455727
2025-03-05 01:27:21 +00:00
66f5bdcb94 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13610829991
2025-03-02 01:38:08 +00:00
5d24d8de0b Merge branch 'minor-next' into major-next 2025-02-26 17:32:14 +00:00
1ad08e2432 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13488997706
2025-02-24 01:26:36 +00:00
a43ebcf217 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13403469065
2025-02-19 01:24:13 +00:00
c637d852e2 Merge branch 'minor-next' into major-next 2025-02-18 01:26:08 +00:00
c58c64de85 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13360931724
2025-02-17 01:26:25 +00:00
694aa17cc9 Merge branch 'minor-next' into major-next 2025-02-16 23:18:56 +00:00
c9441e1078 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13276594014
2025-02-12 02:16:01 +00:00
b0ac8863c4 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13191240897
2025-02-07 01:23:45 +00:00
e9df0baffb Merge branch 'minor-next' of github.com:pmmp/PocketMine-MP into major-next 2025-02-05 01:37:00 +00:00
b3723b5b3e Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13104521333
2025-02-03 01:23:13 +00:00
b370b5458f Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13094301661
2025-02-02 01:26:09 +00:00
8af2d05ec0 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/13001707314
2025-01-28 01:21:44 +00:00
4d186b52da Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12920308572
2025-01-23 01:22:04 +00:00
e6ff55823f Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12899221905
2025-01-22 01:23:50 +00:00
d556389b11 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12839491049
2025-01-18 01:19:33 +00:00
976fc63567 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12701510185
2025-01-10 01:26:17 +00:00
02ac512b4e Merge branch 'minor-next' into major-next 2025-01-08 15:25:12 +00:00
708784b0a2 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12643390650
2025-01-07 01:24:48 +00:00
3f7f11b812 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12615442245
2025-01-05 01:37:23 +00:00
984e995659 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12606221104
2025-01-04 01:22:34 +00:00
46604b26f2 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12510342531
2024-12-27 01:23:48 +00:00
6b2fb9c4f8 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12498201064
2024-12-26 01:23:26 +00:00
80b761627a Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12487960388
2024-12-25 01:23:10 +00:00
882d8c4ab9 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12475368381
2024-12-24 01:24:08 +00:00
1c35987ead Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12450134566
2024-12-22 01:37:17 +00:00
88ae00fc4d Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12440895736
2024-12-21 01:22:55 +00:00
47a1aa6470 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12423751811
2024-12-20 01:24:32 +00:00
3e69ee87e4 Remove deprecated stuff
except Permission subscriptions; turns out we still need those
perhaps they should be marked @internal
2024-12-19 00:14:18 +00:00
a2a2ec9d8b Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12364667325
2024-12-17 01:39:12 +00:00
3a0f15ef0d Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12344337356
2024-12-16 01:42:31 +00:00
7a2427ace2 Merge branch 'minor-next' of github.com:pmmp/PocketMine-MP into major-next 2024-12-14 02:40:03 +00:00
f82c8dd3d3 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12307996607
2024-12-13 01:40:43 +00:00
851bbd7384 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12268005529
2024-12-11 01:40:03 +00:00
1ee52b69b0 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12247725255
2024-12-10 01:41:10 +00:00
851f7a9d80 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12227347339
2024-12-09 01:42:26 +00:00
6d2329128a Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12191303914
2024-12-06 01:38:37 +00:00
07045dd424 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12184052098
2024-12-05 16:35:59 +00:00
c5b0df4578 Merge remote-tracking branch 'origin/minor-next' into major-next 2024-12-05 16:07:28 +00:00
5e9dbace90 Merge branch 'minor-next' into major-next 2024-12-05 10:13:24 +00:00
205aabe11f Fixed merge error 2024-12-04 15:27:09 +00:00
3091e1325f Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12151373979
2024-12-04 01:39:59 +00:00
779e80a961 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12131296321
2024-12-03 01:39:33 +00:00
007673cb96 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12111121061
2024-12-02 01:41:02 +00:00
0dae786a21 feat(Server): add a setter for maxPlayers (#6261) 2024-12-01 20:24:50 +00:00
02d181d0c8 Merge branch 'minor-next' into major-next 2024-12-01 15:02:36 +00:00
2fc6bbe84e Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12092463227
2024-11-30 01:35:08 +00:00
002383be89 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12077579940
2024-11-29 01:37:53 +00:00
00bdb6be73 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12060967026
2024-11-28 01:37:50 +00:00
c3c917bb05 Merge branch 'minor-next' into major-next 2024-11-27 17:56:45 +00:00
a078f653f4 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12042121495
2024-11-27 01:39:13 +00:00
ed33983792 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12022106146
2024-11-26 01:36:42 +00:00
15eaf67a0c Merge branch 'minor-next' into major-next 2024-11-25 14:36:25 +00:00
d72941c36c Update IceBomb.php 2024-11-24 23:56:44 +00:00
e51903d7ea Merge branch 'minor-next' into major-next 2024-11-24 23:51:07 +00:00
3e9a96b43a Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11990667732
2024-11-23 21:49:02 +00:00
9fce27eaa8 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11990103798
2024-11-23 20:14:24 +00:00
7208733d62 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11989715327
2024-11-23 19:10:14 +00:00
c61434d87b Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11964819241
2024-11-22 01:36:17 +00:00
dcc258706f Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11944832380
2024-11-21 01:27:14 +00:00
820e2d4a2f Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11924942897
2024-11-20 01:27:32 +00:00
0fb1415f7f Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11904511045
2024-11-19 01:36:12 +00:00
a6534ecbbb Fixed merge error 2024-11-17 01:55:46 +00:00
330bcd2423 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11874902000
2024-11-17 01:39:53 +00:00
e71b9e8dc6 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11866065217
2024-11-16 01:37:29 +00:00
9e2d91bae6 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11865975725
2024-11-16 01:26:32 +00:00
b6f55b78a9 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11862895039
2024-11-15 20:21:33 +00:00
ab5176baf9 Merge branch 'minor-next' into major-next 2024-11-14 23:16:44 +00:00
ef6fce4091 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11824307499
2024-11-13 19:21:19 +00:00
cc335889f3 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11802296296
2024-11-12 17:14:26 +00:00
80b7f6aba4 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11769186885
2024-11-10 22:56:09 +00:00
82c5a3160c Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11652590245
2024-11-03 15:33:37 +00:00
85de28d6c3 Merge branch 'minor-next' into major-next 2024-11-03 14:02:06 +00:00
1ef854f2d1 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/11392123557
2024-10-17 19:59:15 +00:00
082af9978c Merge branch 'minor-next' into major-next 2024-09-23 15:08:45 -05:00
e8620ef94d Restore travis.sh execute permission 2024-09-22 21:59:40 -05:00
83a91634c3 Merge branch 'minor-next' into sync-major-next 2024-09-22 21:44:31 -05:00
3c73bd22dd Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/10458521667
2024-08-19 18:03:25 +00:00
0e1824451b Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/10442250915
2024-08-18 16:50:43 +00:00
6c5ae634fd Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/10373700926
2024-08-13 16:37:46 +00:00
041944ed16 Merge 'minor-next' into 'major-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/10371827817
2024-08-13 14:36:02 +00:00
603527c6e8 Merge branch 'minor-next' of github.com:pmmp/PocketMine-MP into major-next 2024-08-13 13:39:00 +00:00
1ac08ea73b Remove enchant properties that no longer exists on PM6 (#6417) 2024-08-10 08:51:06 -05:00
c9e8d382c5 Merge branch 'minor-next' of github.com:pmmp/PocketMine-MP into major-next 2024-08-09 13:33:07 +01:00
12179aa03a Merge branch 'minor-next' into major-next 2024-05-06 15:42:49 +01:00
e781c64540 Merge branch 'minor-next' into major-next 2024-03-14 12:47:18 +00:00
644693ffee Merge branch 'minor-next' into major-next 2024-02-12 11:55:36 +00:00
6b66cbfb1c Merge branch 'minor-next' into major-next 2023-12-20 15:26:57 +00:00
4d337add7c Merge branch 'minor-next' into major-next 2023-12-14 14:03:09 +00:00
9d75c45bf5 Merge branch 'minor-next' into major-next 2023-11-09 18:06:06 +00:00
c7a537abbb Merge branch 'minor-next' into major-next 2023-11-01 18:03:04 +00:00
54694df48c Merge branch 'minor-next' into major-next 2023-11-01 16:39:55 +00:00
15aae721cd Merge branch 'minor-next' into major-next 2023-10-26 12:57:24 +01:00
d565be93a8 Merge branch 'minor-next' into major-next 2023-10-24 11:57:30 +01:00
e32a90be72 Make Player->getFirstPlayed() and Player->getLastPlayed() return DateTimeImmutable (#6042) 2023-10-17 16:26:21 +01:00
d4d7d02067 Merge branch 'minor-next' into major-next 2023-10-16 21:29:11 +01:00
a45e143e81 Merge branch 'minor-next' into major-next 2023-09-21 13:29:58 +01:00
05981d2669 Merge branch 'minor-next' into major-next 2023-09-20 19:15:08 +01:00
fa9bba470c RegistryTrait: use native parameter types for __callStatic() arguments (#5944) 2023-09-08 12:03:03 +01:00
361626d236 Merge branch 'minor-next' into major-next 2023-09-08 11:27:09 +01:00
16d8522245 Farewell EnumTrait, you served us well 2023-09-08 11:26:11 +01:00
a4f3476190 Merge branch 'minor-next' into major-next 2023-09-08 11:22:44 +01:00
e96e68d221 Merge branch 'minor-next' into major-next 2023-09-07 20:33:35 +01:00
f1a6d71cc1 Merge branch 'minor-next' into major-next 2023-09-07 20:30:58 +01:00
89f42c80d4 Strip out deprecated stuff 2023-09-07 20:26:04 +01:00
cd6b780d31 Merge branch 'minor-next' into major-next 2023-09-07 20:10:31 +01:00
ed61a68013 Entity: make getNetworkTypeId non-static (#6037)
This was static to permit ItemFactory to register spawn eggs for all known entity types in early PM4. However, nowadays we provide a callback to the spawn egg instead, and spawn eggs must be manually implemented, so this is no longer needed.

In addition, having this static forces everyone to make a new entity class for every unique type of entity, which isn't ideal.
2023-09-06 15:26:32 +01:00
4dc9d696d0 Merge branch 'minor-next' into major-next 2023-09-06 13:03:51 +01:00
258038c9a9 Merge branch 'minor-next' into major-next 2023-08-21 16:08:32 +01:00
5c915a3dfe Merge branch 'minor-next' into major-next 2023-08-18 12:33:54 +01:00
8c594fd126 Merge branch 'minor-next' into major-next 2023-08-15 17:41:50 +01:00
9fd6653f36 Remove deprecated APIs 2023-08-09 16:38:09 +01:00
32d67080e5 Merge branch 'minor-next' into major-next 2023-08-09 16:35:32 +01:00
ed9d057ca2 Merge branch 'minor-next' into major-next 2023-08-08 18:27:58 +01:00
5ec0e0f20b Merge branch 'minor-next' into major-next 2023-08-08 17:48:23 +01:00
cb251069dd PluginLoader: rename parameters 2023-08-07 16:39:54 +01:00
e0ad39b70a Remove ResourceProvider cruft
this had no obvious reason for existing, and with #5958 looming, this will become altogether useless anyway.
2023-08-07 16:14:01 +01:00
9997b614bc Merge branch 'minor-next' into major-next 2023-08-01 12:53:53 +01:00
89f8f421a6 Server: stop discriminating against folder plugins when generating crashdumps
in PM6, non-development plugins may appear in folder form.
2023-07-26 10:47:39 +01:00
c4ff6d7757 Merge branch 'minor-next' into major-next 2023-07-24 16:45:55 +01:00
3c0e7ae492 Merge branch 'minor-next' into major-next 2023-07-24 12:07:55 +01:00
b944205f60 Remove useless checks for plugins disabling other plugins (#5931) 2023-07-24 11:31:19 +01:00
2ab3393568 Unlink DevTools submodule and remove references
we don't need this as a submodule anymore, since it's not used in the core.
2023-07-20 11:29:06 +01:00
1e1b95e1b8 uh oh 2023-07-19 18:06:44 +01:00
62465fa676 Integrate FolderPluginLoader
the motivation for this is described in #5917

a new version of DevTools will be required, as the current version will cause the server to abort during startup with this change due to duplicated plugin loading.
2023-07-19 18:05:41 +01:00
aac5944396 Accept Translatable permission messages in Command (#5830) 2023-07-19 16:38:15 +01:00
74cfd687d7 CraftingManagerFromDataHelper: Fix parameter name typo (#5870)
due to named parameters, this change must target PM6
2023-07-19 11:05:52 +01:00
f2f30143b0 Merge branch 'minor-next' into major-next 2023-07-18 22:22:43 +01:00
d98adf127f Merge branch 'minor-next' into major-next 2023-07-17 16:13:28 +01:00
280bf60830 Merge branch 'minor-next' into major-next 2023-07-14 13:28:07 +01:00
1ffa945fbf Disallow plugins disabling other plugins (#5872) 2023-07-13 13:44:28 +01:00
279 changed files with 4870 additions and 8496 deletions

View File

@ -4,11 +4,6 @@ on:
release:
types:
- published
workflow_dispatch:
inputs:
release:
description: 'Tag name to build'
required: true
jobs:
build:
@ -33,28 +28,16 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Clone pmmp/PocketMine-Docker repository
uses: actions/checkout@v5
uses: actions/checkout@v4
with:
repository: pmmp/PocketMine-Docker
fetch-depth: 1
- name: Get tag name
- name: Get tag names
id: tag-name
run: |
if [[ "${{ github.event_name }}" == "release" ]]; then
echo TAG_NAME="${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo TAG_NAME="${{ github.event.inputs.release }}" >> $GITHUB_OUTPUT
else
echo "Unsupported event type: ${{ github.event_name }}"
exit 1
fi
- name: Parse version
id: version
run: |
VERSION="${{ steps.tag-name.outputs.TAG_NAME }}"
VERSION=$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{')
echo TAG_NAME=$VERSION >> $GITHUB_OUTPUT
echo MAJOR=$(echo $VERSION | cut -d. -f1) >> $GITHUB_OUTPUT
echo MINOR=$(echo $VERSION | cut -d. -f1-2) >> $GITHUB_OUTPUT
@ -88,8 +71,8 @@ jobs:
push: true
context: ./pocketmine-mp
tags: |
${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.version.outputs.MAJOR }}
ghcr.io/${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.version.outputs.MAJOR }}
${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.tag-name.outputs.MAJOR }}
ghcr.io/${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.tag-name.outputs.MAJOR }}
build-args: |
PMMP_TAG=${{ steps.tag-name.outputs.TAG_NAME }}
PMMP_REPO=${{ github.repository }}
@ -101,8 +84,8 @@ jobs:
push: true
context: ./pocketmine-mp
tags: |
${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.version.outputs.MINOR }}
ghcr.io/${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.version.outputs.MINOR }}
${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.tag-name.outputs.MINOR }}
ghcr.io/${{ steps.docker-repo-name.outputs.NAME }}:${{ steps.tag-name.outputs.MINOR }}
build-args: |
PMMP_TAG=${{ steps.tag-name.outputs.TAG_NAME }}
PMMP_REPO=${{ github.repository }}

View File

@ -18,7 +18,7 @@ jobs:
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup PHP
uses: pmmp/setup-php-action@3.2.0
@ -41,7 +41,7 @@ jobs:
run: composer install --prefer-dist --no-interaction
- name: Clone extension stubs
uses: actions/checkout@v5
uses: actions/checkout@v4
with:
repository: pmmp/phpstorm-stubs
path: extension-stubs

View File

@ -4,23 +4,18 @@ on:
release:
types:
- published
workflow_dispatch:
inputs:
release:
description: 'Release to make notification for'
required: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup PHP and tools
uses: shivammathur/setup-php@2.35.4
uses: shivammathur/setup-php@2.34.1
with:
php-version: 8.2
php-version: 8.3
- name: Restore Composer package cache
uses: actions/cache@v4
@ -35,17 +30,9 @@ jobs:
- name: Install Composer dependencies
run: composer install --no-dev --prefer-dist --no-interaction --ignore-platform-reqs
- name: Get tag name
- name: Get actual tag name
id: tag-name
run: |
if [[ "${{ github.event_name }}" == "release" ]]; then
echo TAG_NAME="${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo TAG_NAME="${{ github.event.inputs.release }}" >> $GITHUB_OUTPUT
else
echo "Unsupported event type: ${{ github.event_name }}"
exit 1
fi
run: echo TAG_NAME=$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{') >> $GITHUB_OUTPUT
- name: Run webhook post script
run: php .github/workflows/discord-release-embed.php ${{ github.repository }} ${{ steps.tag-name.outputs.TAG_NAME }} ${{ github.token }} ${{ secrets.DISCORD_RELEASE_WEBHOOK }} ${{ secrets.DISCORD_NEWS_PING_ROLE_ID }}

View File

@ -30,7 +30,7 @@ jobs:
valid: ${{ steps.validate.outputs.DEV_BUILD == 'false' }}
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Check IS_DEVELOPMENT_BUILD flag
id: validate
@ -46,12 +46,12 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@2.35.4
uses: shivammathur/setup-php@2.34.1
with:
php-version: 8.2
php-version: 8.3
- name: Restore Composer package cache
uses: actions/cache@v4

View File

@ -18,7 +18,7 @@ on:
- "*"
env:
PHP_VERSION: "8.2"
PHP_VERSION: "8.3"
jobs:
skip:
@ -82,12 +82,12 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
submodules: true
- name: Setup PHP
uses: shivammathur/setup-php@2.35.4
uses: shivammathur/setup-php@2.34.1
with:
php-version: ${{ env.PHP_VERSION }}

View File

@ -27,7 +27,7 @@ jobs:
fail-fast: false
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup PHP
uses: pmmp/setup-php-action@3.2.0
@ -59,7 +59,7 @@ jobs:
fail-fast: false
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup PHP
uses: pmmp/setup-php-action@3.2.0
@ -91,7 +91,7 @@ jobs:
fail-fast: false
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
submodules: true
@ -125,7 +125,7 @@ jobs:
fail-fast: false
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup PHP
uses: pmmp/setup-php-action@3.2.0

View File

@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php: ["8.1", "8.2", "8.3", "8.4"]
php: ["8.3"]
uses: ./.github/workflows/main-php-matrix.yml
with:
@ -25,10 +25,10 @@ jobs:
fail-fast: false
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Setup PHP and tools
uses: shivammathur/setup-php@2.35.4
uses: shivammathur/setup-php@2.34.1
with:
php-version: 8.3
tools: php-cs-fixer:3.75
@ -45,7 +45,7 @@ jobs:
fail-fast: false
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v4
- name: Run ShellCheck
uses: ludeeus/action-shellcheck@2.0.0

View File

@ -4,11 +4,6 @@ on:
release:
types:
- published
workflow_dispatch:
inputs:
release:
description: 'Release to publish info for'
required: true
jobs:
build:
@ -19,22 +14,14 @@ jobs:
- name: Install jq
run: sudo apt update && sudo apt install jq -y
- uses: actions/checkout@v5
- uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/update.pmmp.io
ssh-key: ${{ secrets.UPDATE_PMMP_IO_DEPLOY_KEY }}
- name: Get tag name
- name: Get actual tag name
id: tag-name
run: |
if [[ "${{ github.event_name }}" == "release" ]]; then
echo TAG_NAME="${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo TAG_NAME="${{ github.event.inputs.release }}" >> $GITHUB_OUTPUT
else
echo "Unsupported event type: ${{ github.event_name }}"
exit 1
fi
run: echo TAG_NAME=$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{') >> $GITHUB_OUTPUT
- name: Download new release information
run: curl -f -L ${{ github.server_url }}/${{ github.repository }}/releases/download/${{ steps.tag-name.outputs.TAG_NAME }}/build_info.json -o new_build_info.json

3
.gitmodules vendored
View File

@ -1,6 +1,3 @@
[submodule "tests/plugins/DevTools"]
path = tests/plugins/DevTools
url = https://github.com/pmmp/DevTools.git
[submodule "build/php"]
path = build/php
url = https://github.com/pmmp/php-build-scripts.git

View File

@ -5,7 +5,7 @@ $finder = PhpCsFixer\Finder::create()
->in(__DIR__ . '/build')
->in(__DIR__ . '/tests')
->in(__DIR__ . '/tools')
->notPath('plugins/DevTools')
//JsonMapper will break if the FQNs in the doc comments for these are shortened :(
->notPath('crafting/json')
->notPath('inventory/json')

View File

@ -73,7 +73,7 @@ PocketMine-MP is free, but it requires a lot of time and effort from unpaid volu
You can support development using the following methods:
- [Patreon](https://www.patreon.com/pocketminemp)
- Bitcoin (BTC): `bc1q2v5ngyf8ugyd55kqa9ep35g2rv342ueqm6ks33`
- Bitcoin (BTC): `171u8K9e4FtU6j3e5sqNoxKUgEw9qWQdRV`
- Stellar Lumens (XLM): `GAAC5WZ33HCTE3BFJFZJXONMEIBNHFLBXM2HJVAZHXXPYA3HP5XPPS7T`
Thanks for your support!

View File

@ -1,25 +0,0 @@
# 5.32.0
Released 6th August 2025.
This is a support release for Minecraft: Bedrock Edition 1.21.100.
**Plugin compatibility:** Plugins for previous 5.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` or `pocketmine\data` namespace.
Do not update plugin minimum API versions unless you need new features added in this release.
**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.**
Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly.
## General
- Added support for Minecraft: Bedrock Edition 1.21.100.
- Removed support for earlier versions.
## Fixes
- Fixed deadlock on RakLib thread crash (e.g. due to port binding failure).
# 5.32.1
Released 14th August 2025.
## Fixes
- Hardened checks when processing resource pack sending during player logins.
- Fixed content log warning about crafting recipe with missing ID.
- Fixed packets in a batch still being processed after one of them caused the session to be terminated.

View File

@ -1,135 +0,0 @@
# 5.33.0
Released 30th August 2025.
This is a minor feature release containing internals improvements, API improvements and new gameplay features.
**Plugin compatibility:** Plugins for previous 5.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` or `pocketmine\data` namespace.
Do not update plugin minimum API versions unless you need new features added in this release.
**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.**
Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly.
## Performance
- Worlds now remember when a chunk isn't generated. This reduces world I/O during world generation.
- `BlockObjectToStateSerializer` now creates fewer objects in certain cases.
## Gameplay
- The following blocks have been added and/or are now properly supported:
- Hanging signs
- Illager banners
## Tools
- `generate-bedrock-data-from-packets.php` now represents items as strings directly when only an ID is present. This significantly improves readability in `BedrockData` and reduces file sizes.
## API
### `pocketmine\block`
- Added (and implemented) interfaces for many common block properties, to allow `instanceof` to be used:
- `Ageable`: for blocks with age, such as crops
- `AnyFacing`: for blocks which can face up, down, and horizontal directions (not the same as `HorizontalFacing`!)
- `Colored`: for blocks with 16 `DyeColor` variants
- `CoralMaterial`: for coral blocks, provides access to coral type and dead/alive
- `HorizontalFacing`: for blocks which can **only** face horizontal directions (not the same as `AnyFacing`!)
- `Lightable`: for light-source blocks which can be turned on and off, e.g. redstone lamp
- `MultiAnyFacing`: for blocks which can appear in multiple faces of the same block (including up, down, and horizontal faces), e.g. glow lichen
- `PillarRotation`: for blocks which can be oriented on an axis, e.g. logs
- `PoweredByRedstone`: for blocks which receive power from a redstone component, e.g. redstone lamp
- `SignLikeRotation`: for blocks which can be rotated 16 ways, e.g. signs, banners
- `WoodMaterial`: for blocks made from wood
- These interfaces have been implemented on many blocks. For the sake of brevity, they are not listed here, but you can expect to see them wherever the corresponding traits were used.
- The following classes have been added:
- `BaseOminousBanner`
- `CeilingCenterHangingSign` - both chains connected to the same point on the block above, can face 16 directions
- `CeilingEdgesHangingSign` - each chain connected to separate edges of the block above, can face 4 directions
- `OminousFloorBanner` - floor version of illager banner, can face 16 directions
- `OminousWallBanner` - wall version of illager banner, can face 4 directions
- `WallHangingSign` - hangs from a horizontal beam, can face 4 directions
- The following API methods have been added:
- `public ChiseledBookshelf->setSlots(list<ChiseledBookshelfSlot> $slots) : $this`
- `public static VanillaBlocks` methods:
- `ACACIA_CEILING_CENTER_HANGING_SIGN() : CeilingCenterHangingSign`
- `ACACIA_CEILING_EDGES_HANGING_SIGN() : CeilingEdgesHangingSign`
- `ACACIA_WALL_HANGING_SIGN() : WallHangingSign`
- `BIRCH_CEILING_CENTER_HANGING_SIGN() : CeilingCenterHangingSign`
- `BIRCH_CEILING_EDGES_HANGING_SIGN() : CeilingEdgesHangingSign`
- `BIRCH_WALL_HANGING_SIGN() : WallHangingSign`
- `CHERRY_CEILING_CENTER_HANGING_SIGN() : CeilingCenterHangingSign`
- `CHERRY_CEILING_EDGES_HANGING_SIGN() : CeilingEdgesHangingSign`
- `CHERRY_WALL_HANGING_SIGN() : WallHangingSign`
- `CRIMSON_CEILING_CENTER_HANGING_SIGN() : CeilingCenterHangingSign`
- `CRIMSON_CEILING_EDGES_HANGING_SIGN() : CeilingEdgesHangingSign`
- `CRIMSON_WALL_HANGING_SIGN() : WallHangingSign`
- `DARK_OAK_CEILING_CENTER_HANGING_SIGN() : CeilingCenterHangingSign`
- `DARK_OAK_CEILING_EDGES_HANGING_SIGN() : CeilingEdgesHangingSign`
- `DARK_OAK_WALL_HANGING_SIGN() : WallHangingSign`
- `JUNGLE_CEILING_CENTER_HANGING_SIGN() : CeilingCenterHangingSign`
- `JUNGLE_CEILING_EDGES_HANGING_SIGN() : CeilingEdgesHangingSign`
- `JUNGLE_WALL_HANGING_SIGN() : WallHangingSign`
- `MANGROVE_CEILING_CENTER_HANGING_SIGN() : CeilingCenterHangingSign`
- `MANGROVE_CEILING_EDGES_HANGING_SIGN() : CeilingEdgesHangingSign`
- `MANGROVE_WALL_HANGING_SIGN() : WallHangingSign`
- `OAK_CEILING_CENTER_HANGING_SIGN() : CeilingCenterHangingSign`
- `OAK_CEILING_EDGES_HANGING_SIGN() : CeilingEdgesHangingSign`
- `OAK_WALL_HANGING_SIGN() : WallHangingSign`
- `OMINOUS_FLOOR_BANNER() : OminousFloorBanner`
- `OMINOUS_WALL_BANNER() : OminousWallBanner`
- `PALE_OAK_CEILING_CENTER_HANGING_SIGN() : CeilingCenterHangingSign`
- `PALE_OAK_CEILING_EDGES_HANGING_SIGN() : CeilingEdgesHangingSign`
- `PALE_OAK_WALL_HANGING_SIGN() : WallHangingSign`
- `SPRUCE_CEILING_CENTER_HANGING_SIGN() : CeilingCenterHangingSign`
- `SPRUCE_CEILING_EDGES_HANGING_SIGN() : CeilingEdgesHangingSign`
- `SPRUCE_WALL_HANGING_SIGN() : WallHangingSign`
- `WARPED_CEILING_CENTER_HANGING_SIGN() : CeilingCenterHangingSign`
- `WARPED_CEILING_EDGES_HANGING_SIGN() : CeilingEdgesHangingSign`
- `WARPED_WALL_HANGING_SIGN() : WallHangingSign`
- `public AgeableTrait->getMaxAge() : int` (included by all growable plant-like blocks, e.g. crops)
### `pocketmine\data\bedrock\block\convert`
- A new system for symmetric block serializers and deserializers has been introduced.
- This allows registering both a serializer and a deserializer with the same code, meaning way less code
- It also eliminates information duplication and potential inconsistencies, improving maintainability.
- A proper way to deal with flattened IDs (e.g. color blocks) has been introduced which _doesn't_ require hardcoding a giant mess of IDs
- This symmetric system covers 99% of blocks which have a 1:1 association between PM and vanilla blocks, or 1:N where IDs are flattened
- However, there are still some special cases which require registering separate serializers and deserializers (usually in cases where the PM implementation deviates from Mojang where Mojang's implementation sucks, such as hanging signs or big dripleaf).
- No backwards compatibility breaks are expected as a result of this change. However, it's recommended to migrate old code to this new system for maintainability.
- The following new classes have been added:
- `BlockSerializerDeserializerRegistrar` - handles unified registration of block serializers and deserializers, based on a provided block model
- `FlattenedIdModel` - represents a block with some properties baked into its Minecraft ID, e.g. coral or color blocks
- `Model` - represents a regular block with all properties in its `states` NBT
- `property\BoolFromStringProperty<TBlock>` - property mapping a bool value from a string NBT state
- `property\BoolProperty<TBlock>`
- `property\CommonProperties` - singleton containing commonly-used block property definitions and groups, e.g. facing, stair properties
- `property\EnumFromRawStateMap<TEnum, TRaw>` - maps a raw NBT value to a PHP `enum` and vice versa
- `property\IntFromRawStateMap<TRaw>` - maps a raw NBT value to PM integer constants and vice versa
- `property\IntProperty<TBlock>` - an integer range property with a min, max, and optional offset
- `property\Property<TBlock>` - interface implemented by all property definitions accepted by a `Model` or `FlattenedIdModel`
- `property\StateMap<TValue, TRaw>` - interface implemented by classes accepted by mapping properties, e.g. `BoolFromStringProperty`
- `property\StringProperty<TBlock>` - interface implemented by properties whose raw outputs are strings - these can be used as ID components in `FlattenedIdModel`
- `property\ValueFromIntProperty<TBlock, TValue>` - property mapping a generic PM value from an int NBT state
- `property\ValueFromStringProperty<TBlock, TValue>` - same as above, but for a string NBT state
- `property\ValueSetFromIntProperty<TBlock, TOption>` - a property mapping an `int[]` or `enum[]` from a set of flags in NBT states
- `property\ValueMappings` - singleton containing commonly-needed `StateMap`s
- The following classes have been deprecated:
- `BlockStateDeserializerHelper`
- `BlockStateSerializerHelper`
- The following methods have been deprecated:
- All methods for decoding mapped property types in `BlockStateReader`, e.g. `readFacingDirection()`
- All methods for encoding mapped property types in `BlockStateWriter`, e.g. `writeFacingDirection()`
- All specific blocktype mapping functions in `BlockStateToObjectDeserializer`, e.g. `mapStairs()`
- All specific blocktype mapping functions in `BlockObjectToStateSerializer`, e.g. `mapStairs()`
### `pocketmine\item`
- The following hooks have been added:
- `public Item->getPlacementTransaction(Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : ?BlockTransaction` - allows more complex logic for itemblocks to place blocks, without duplicating their placement conditions (used for hanging signs)
### `pocketmine\world`
- `World->setChunk()` now verifies that blockstate IDs in the provided chunk are all registered in `RuntimeBlockStateRegistry`. This should provide earlier detection for custom block registration errors by plugins.
## Internals
- `BlockStateUpgrader` is now almost entirely independent from `BlockStateData`. It's anticipated that the upgrader library will be separable from the core in the future.
- `Block->readStateFromWorld()` is now triggered on chunk load for any position containing a tile. This should allow more effective updating of blocks with properties in their tiles.
# 5.33.1
Released 31st August 2025.
## Fixes
- Fixed banners placed in prior versions getting their tiles deleted (due to missing `Type` tags).

View File

@ -5,7 +5,7 @@
"homepage": "https://pmmp.io",
"license": "LGPL-3.0",
"require": {
"php": "^8.1",
"php": "^8.3",
"php-64bit": "*",
"ext-chunkutils2": "^0.3.1",
"ext-crypto": "^0.3.1",
@ -34,9 +34,9 @@
"adhocore/json-comment": "~1.2.0",
"netresearch/jsonmapper": "~v5.0.0",
"pocketmine/bedrock-block-upgrade-schema": "~5.1.0+bedrock-1.21.60",
"pocketmine/bedrock-data": "~6.0.0+bedrock-1.21.100",
"pocketmine/bedrock-item-upgrade-schema": "~1.15.0+bedrock-1.21.100",
"pocketmine/bedrock-protocol": "~40.0.0+bedrock-1.21.100",
"pocketmine/bedrock-data": "~5.2.0+bedrock-1.21.93",
"pocketmine/bedrock-item-upgrade-schema": "~1.14.0+bedrock-1.21.50",
"pocketmine/bedrock-protocol": "~39.1.0+bedrock-1.21.93",
"pocketmine/binaryutils": "^0.2.1",
"pocketmine/callback-validator": "^1.0.2",
"pocketmine/color": "^0.3.0",
@ -49,13 +49,13 @@
"pocketmine/raklib-ipc": "~1.0.0",
"pocketmine/snooze": "^0.5.0",
"ramsey/uuid": "~4.9.0",
"symfony/filesystem": "~6.4.0"
"symfony/filesystem": "~7.3.0"
},
"require-dev": {
"phpstan/phpstan": "2.1.17",
"phpstan/phpstan-phpunit": "^2.0.0",
"phpstan/phpstan-strict-rules": "^2.0.0",
"phpunit/phpunit": "^10.5.24"
"phpunit/phpunit": "^12.2.1"
},
"replace": {
"symfony/polyfill-ctype": "*",
@ -77,12 +77,11 @@
},
"config": {
"platform": {
"php": "8.1.0"
"php": "8.3.0"
},
"sort-packages": true
},
"scripts": {
"make-devtools": "@php -dphar.readonly=0 tests/plugins/DevTools/src/ConsoleScript.php --make ./ --relative tests/plugins/DevTools --out plugins/DevTools.phar",
"make-server": [
"@composer install --no-dev --classmap-authoritative --ignore-platform-reqs",
"@php -dphar.readonly=0 build/server-phar.php"

731
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -4,17 +4,13 @@ includes:
- tests/phpstan/configs/impossible-generics.neon
- tests/phpstan/configs/php-bugs.neon
- tests/phpstan/configs/phpstan-bugs.neon
- tests/phpstan/configs/property-hook-sadness.neon
- tests/phpstan/configs/reflection-class-sadness.neon
- tests/phpstan/configs/spl-fixed-array-sucks.neon
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
- vendor/phpstan/phpstan-strict-rules/rules.neon
rules:
- pocketmine\phpstan\rules\DeprecatedLegacyEnumAccessRule
- pocketmine\phpstan\rules\DisallowDynamicNewRule
- pocketmine\phpstan\rules\DisallowEnumComparisonRule
- pocketmine\phpstan\rules\DisallowForeachByReferenceRule
- pocketmine\phpstan\rules\ExplodeLimitRule
- pocketmine\phpstan\rules\UnsafeForeachRule

View File

@ -123,13 +123,6 @@ class MemoryManager{
return $this->globalMemoryLimit;
}
/**
* @deprecated
*/
public function canUseChunkCache() : bool{
return !$this->lowMemory;
}
/**
* Returns the allowed chunk radius based on the current memory usage.
*/
@ -236,13 +229,4 @@ class MemoryManager{
}
}
}
/**
* Static memory dumper accessible from any thread.
* @deprecated
* @see MemoryDump
*/
public static function dumpMemory(mixed $startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger) : void{
MemoryDump::dumpMemory($startingObject, $outputFolder, $maxNesting, $maxStringSize, $logger);
}
}

View File

@ -55,7 +55,7 @@ namespace pocketmine {
require_once __DIR__ . '/VersionInfo.php';
const MIN_PHP_VERSION = "8.1.0";
const MIN_PHP_VERSION = "8.3.0";
/**
* @param string $message

View File

@ -80,6 +80,7 @@ use pocketmine\player\PlayerDataLoadException;
use pocketmine\player\PlayerDataProvider;
use pocketmine\player\PlayerDataSaveException;
use pocketmine\player\PlayerInfo;
use pocketmine\plugin\FolderPluginLoader;
use pocketmine\plugin\PharPluginLoader;
use pocketmine\plugin\PluginEnableOrder;
use pocketmine\plugin\PluginGraylist;
@ -346,6 +347,10 @@ class Server{
return $this->maxPlayers;
}
public function setMaxPlayers(int $maxPlayers) : void{
$this->maxPlayers = $maxPlayers;
}
/**
* Returns whether the server requires that players be authenticated to Xbox Live. If true, connecting players who
* are not logged into Xbox Live will be disconnected.
@ -1029,6 +1034,7 @@ class Server{
$this->pluginManager = new PluginManager($this, $this->configGroup->getPropertyBool(Yml::PLUGINS_LEGACY_DATA_DIR, true) ? null : Path::join($this->dataPath, "plugin_data"), $pluginGraylist);
$this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader));
$this->pluginManager->registerInterface(new ScriptPluginLoader());
$this->pluginManager->registerInterface(new FolderPluginLoader($this->autoloader));
$providerManager = new WorldProviderManager();
if(

View File

@ -31,7 +31,7 @@ use function str_repeat;
final class VersionInfo{
public const NAME = "PocketMine-MP";
public const BASE_VERSION = "5.33.2";
public const BASE_VERSION = "5.31.1";
public const IS_DEVELOPMENT_BUILD = true;
public const BUILD_CHANNEL = "stable";

View File

@ -50,10 +50,6 @@ abstract class BaseBanner extends Transparent implements Colored{
parent::readStateFromWorld();
$tile = $this->position->getWorld()->getTile($this->position);
if($tile instanceof TileBanner){
if($tile->getType() === TileBanner::TYPE_OMINOUS){
//illager banner is implemented as a separate block, as it doesn't support base color or custom patterns
return $this->getOminousVersion();
}
$this->color = $tile->getBaseColor();
$this->setPatterns($tile->getPatterns());
}
@ -61,13 +57,6 @@ abstract class BaseBanner extends Transparent implements Colored{
return $this;
}
/**
* TODO: make this abstract in PM6 (BC break)
*/
protected function getOminousVersion() : Block{
return VanillaBlocks::AIR();
}
public function writeStateToWorld() : void{
parent::writeStateToWorld();
$tile = $this->position->getWorld()->getTile($this->position);

View File

@ -1,90 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\tile\Banner as TileBanner;
use pocketmine\block\utils\DyeColor;
use pocketmine\block\utils\SupportType;
use pocketmine\item\Item;
use pocketmine\item\VanillaItems;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\world\BlockTransaction;
use function assert;
abstract class BaseOminousBanner extends Transparent{
public function writeStateToWorld() : void{
parent::writeStateToWorld();
$tile = $this->position->getWorld()->getTile($this->position);
assert($tile instanceof TileBanner);
$tile->setBaseColor(DyeColor::WHITE);
$tile->setPatterns([]);
$tile->setType(TileBanner::TYPE_OMINOUS);
}
public function isSolid() : bool{
return false;
}
public function getMaxStackSize() : int{
return 16;
}
public function getFuelTime() : int{
return 300;
}
protected function recalculateCollisionBoxes() : array{
return [];
}
public function getSupportType(int $facing) : SupportType{
return SupportType::NONE;
}
private function canBeSupportedBy(Block $block) : bool{
return $block->isSolid();
}
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if(!$this->canBeSupportedBy($blockReplace->getSide($this->getSupportingFace()))){
return false;
}
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
}
abstract protected function getSupportingFace() : int;
public function onNearbyBlockChange() : void{
if(!$this->canBeSupportedBy($this->getSide($this->getSupportingFace()))){
$this->position->getWorld()->useBreakOn($this->position);
}
}
public function asItem() : Item{
return VanillaItems::OMINOUS_BANNER();
}
}

View File

@ -787,43 +787,8 @@ final class BlockTypeIds{
public const RESIN_CLUMP = 10757;
public const CHISELED_RESIN_BRICKS = 10758;
public const RESPAWN_ANCHOR = 10759;
public const OMINOUS_BANNER = 10760;
public const OMINOUS_WALL_BANNER = 10761;
public const ACACIA_CEILING_CENTER_HANGING_SIGN = 10762;
public const ACACIA_CEILING_EDGES_HANGING_SIGN = 10763;
public const ACACIA_WALL_HANGING_SIGN = 10764;
public const BIRCH_CEILING_CENTER_HANGING_SIGN = 10765;
public const BIRCH_CEILING_EDGES_HANGING_SIGN = 10766;
public const BIRCH_WALL_HANGING_SIGN = 10767;
public const CHERRY_CEILING_CENTER_HANGING_SIGN = 10768;
public const CHERRY_CEILING_EDGES_HANGING_SIGN = 10769;
public const CHERRY_WALL_HANGING_SIGN = 10770;
public const CRIMSON_CEILING_CENTER_HANGING_SIGN = 10771;
public const CRIMSON_CEILING_EDGES_HANGING_SIGN = 10772;
public const CRIMSON_WALL_HANGING_SIGN = 10773;
public const DARK_OAK_CEILING_CENTER_HANGING_SIGN = 10774;
public const DARK_OAK_CEILING_EDGES_HANGING_SIGN = 10775;
public const DARK_OAK_WALL_HANGING_SIGN = 10776;
public const JUNGLE_CEILING_CENTER_HANGING_SIGN = 10777;
public const JUNGLE_CEILING_EDGES_HANGING_SIGN = 10778;
public const JUNGLE_WALL_HANGING_SIGN = 10779;
public const MANGROVE_CEILING_CENTER_HANGING_SIGN = 10780;
public const MANGROVE_CEILING_EDGES_HANGING_SIGN = 10781;
public const MANGROVE_WALL_HANGING_SIGN = 10782;
public const OAK_CEILING_CENTER_HANGING_SIGN = 10783;
public const OAK_CEILING_EDGES_HANGING_SIGN = 10784;
public const OAK_WALL_HANGING_SIGN = 10785;
public const PALE_OAK_CEILING_CENTER_HANGING_SIGN = 10786;
public const PALE_OAK_CEILING_EDGES_HANGING_SIGN = 10787;
public const PALE_OAK_WALL_HANGING_SIGN = 10788;
public const SPRUCE_CEILING_CENTER_HANGING_SIGN = 10789;
public const SPRUCE_CEILING_EDGES_HANGING_SIGN = 10790;
public const SPRUCE_WALL_HANGING_SIGN = 10791;
public const WARPED_CEILING_CENTER_HANGING_SIGN = 10792;
public const WARPED_CEILING_EDGES_HANGING_SIGN = 10793;
public const WARPED_WALL_HANGING_SIGN = 10794;
public const FIRST_UNUSED_BLOCK_ID = 10795;
public const FIRST_UNUSED_BLOCK_ID = 10760;
private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID;

View File

@ -31,5 +31,4 @@ final class BlockTypeTags{
public const SAND = self::PREFIX . "sand";
public const POTTABLE_PLANTS = self::PREFIX . "pottable";
public const FIRE = self::PREFIX . "fire";
public const HANGING_SIGN = self::PREFIX . "hanging_sign";
}

View File

@ -1,61 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\utils\SignLikeRotation;
use pocketmine\block\utils\SignLikeRotationTrait;
use pocketmine\block\utils\StaticSupportTrait;
use pocketmine\item\Item;
use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\world\BlockTransaction;
final class CeilingCenterHangingSign extends BaseSign implements SignLikeRotation{
use SignLikeRotationTrait;
use StaticSupportTrait;
protected function getSupportingFace() : int{
return Facing::UP;
}
//TODO: duplicated code :(
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($face !== Facing::DOWN){
return false;
}
if($player !== null){
$this->rotation = self::getRotationFromYaw($player->getLocation()->getYaw());
}
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
}
private function canBeSupportedAt(Block $block) : bool{
$supportBlock = $block->getSide(Facing::UP);
return
$supportBlock->getSupportType(Facing::DOWN)->hasCenterSupport() ||
$supportBlock->hasTypeTag(BlockTypeTags::HANGING_SIGN);
}
}

View File

@ -1,68 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\utils\HorizontalFacing;
use pocketmine\block\utils\HorizontalFacingTrait;
use pocketmine\block\utils\SupportType;
use pocketmine\item\Item;
use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\world\BlockTransaction;
final class CeilingEdgesHangingSign extends BaseSign implements HorizontalFacing{
use HorizontalFacingTrait;
protected function getSupportingFace() : int{
return Facing::UP;
}
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($face !== Facing::DOWN){
return false;
}
if($player !== null){
$this->facing = Facing::opposite($player->getHorizontalFacing());
}
if(!$this->canBeSupportedAt($blockReplace)){
return false;
}
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
}
public function onNearbyBlockChange() : void{
if(!$this->canBeSupportedAt($this)){
$this->position->getWorld()->useBreakOn($this->position);
}
}
private function canBeSupportedAt(Block $block) : bool{
$supportBlock = $block->getSide(Facing::UP);
return
$supportBlock->getSupportType(Facing::DOWN) === SupportType::FULL ||
(($supportBlock instanceof WallHangingSign || $supportBlock instanceof CeilingEdgesHangingSign) && Facing::axis($supportBlock->getFacing()) === Facing::axis($this->facing));
}
}

View File

@ -114,18 +114,6 @@ class ChiseledBookshelf extends Opaque implements HorizontalFacing{
return $this->slots;
}
/**
* @param ChiseledBookshelfSlot[] $slots
* @return $this
*/
public function setSlots(array $slots) : self{
$this->slots = [];
foreach($slots as $slot){
$this->setSlot($slot, true);
}
return $this;
}
/**
* Returns the last slot interacted by a player or null if no slot has been interacted with yet.
*/

View File

@ -34,10 +34,6 @@ use pocketmine\world\BlockTransaction;
final class FloorBanner extends BaseBanner implements SignLikeRotation{
use SignLikeRotationTrait;
protected function getOminousVersion() : Block{
return VanillaBlocks::OMINOUS_BANNER()->setRotation($this->rotation);
}
protected function getSupportingFace() : int{
return Facing::DOWN;
}

View File

@ -25,7 +25,6 @@ namespace pocketmine\block;
use pocketmine\block\tile\Furnace as TileFurnace;
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
use pocketmine\block\utils\HorizontalFacing;
use pocketmine\block\utils\Lightable;
use pocketmine\block\utils\LightableTrait;
use pocketmine\crafting\FurnaceType;
@ -35,7 +34,7 @@ use pocketmine\math\Vector3;
use pocketmine\player\Player;
use function mt_rand;
class Furnace extends Opaque implements Lightable, HorizontalFacing{
class Furnace extends Opaque implements Lightable{
use FacesOppositePlacingPlayerTrait;
use LightableTrait;

View File

@ -24,8 +24,8 @@ declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\utils\BlockEventHelper;
use pocketmine\block\utils\MultiAnyFacing;
use pocketmine\block\utils\MultiAnySupportTrait;
use pocketmine\block\utils\MultiFacing;
use pocketmine\block\utils\SupportType;
use pocketmine\item\Fertilizer;
use pocketmine\item\Item;
@ -36,7 +36,7 @@ use pocketmine\world\World;
use function count;
use function shuffle;
class GlowLichen extends Transparent implements MultiAnyFacing{
class GlowLichen extends Transparent implements MultiFacing{
use MultiAnySupportTrait;
public function getLightLevel() : int{

View File

@ -1,53 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\utils\SignLikeRotation;
use pocketmine\block\utils\SignLikeRotationTrait;
use pocketmine\item\Item;
use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\world\BlockTransaction;
final class OminousFloorBanner extends BaseOminousBanner implements SignLikeRotation{
use SignLikeRotationTrait;
//TODO: duplicated code :(
protected function getSupportingFace() : int{
return Facing::DOWN;
}
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($face !== Facing::UP){
return false;
}
if($player !== null){
$this->rotation = self::getRotationFromYaw($player->getLocation()->getYaw());
}
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
}
}

View File

@ -1,49 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\utils\HorizontalFacing;
use pocketmine\block\utils\HorizontalFacingTrait;
use pocketmine\item\Item;
use pocketmine\math\Axis;
use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\world\BlockTransaction;
final class OminousWallBanner extends BaseOminousBanner implements HorizontalFacing{
use HorizontalFacingTrait;
protected function getSupportingFace() : int{
return Facing::opposite($this->facing);
}
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if(Facing::axis($face) === Axis::Y){
return false;
}
$this->facing = $face;
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
}
}

View File

@ -23,12 +23,11 @@ declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\utils\Lightable;
use pocketmine\block\utils\PoweredByRedstone;
use pocketmine\block\utils\PoweredByRedstoneTrait;
use pocketmine\data\runtime\RuntimeDataDescriber;
class RedstoneLamp extends Opaque implements PoweredByRedstone, Lightable{
class RedstoneLamp extends Opaque implements PoweredByRedstone{
use PoweredByRedstoneTrait;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
@ -38,14 +37,4 @@ class RedstoneLamp extends Opaque implements PoweredByRedstone, Lightable{
public function getLightLevel() : int{
return $this->powered ? 15 : 0;
}
public function isLit() : bool{
return $this->powered;
}
/** @return $this */
public function setLit(bool $lit = true) : self{
$this->powered = $lit;
return $this;
}
}

View File

@ -23,11 +23,11 @@ declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\utils\MultiAnyFacing;
use pocketmine\block\utils\MultiAnySupportTrait;
use pocketmine\block\utils\MultiFacing;
use pocketmine\block\utils\SupportType;
final class ResinClump extends Transparent implements MultiAnyFacing{
final class ResinClump extends Transparent implements MultiFacing{
use MultiAnySupportTrait;
public function isSolid() : bool{

View File

@ -59,17 +59,10 @@ class SweetBerryBush extends Flowable implements Ageable{
return 0;
}
/**
* @deprecated
*/
protected function canBeSupportedBy(Block $block) : bool{
return $block->getTypeId() !== BlockTypeIds::FARMLAND && //bedrock-specific thing (bug?)
($block->hasTypeTag(BlockTypeTags::DIRT) || $block->hasTypeTag(BlockTypeTags::MUD));
}
private function canBeSupportedAt(Block $block) : bool{
$supportBlock = $block->getSide(Facing::DOWN);
return $this->canBeSupportedBy($supportBlock);
return $supportBlock->getTypeId() !== BlockTypeIds::FARMLAND && //bedrock-specific thing (bug?)
($supportBlock->hasTypeTag(BlockTypeTags::DIRT) || $supportBlock->hasTypeTag(BlockTypeTags::MUD));
}
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{

View File

@ -45,7 +45,6 @@ use pocketmine\block\tile\EnchantTable as TileEnchantingTable;
use pocketmine\block\tile\EnderChest as TileEnderChest;
use pocketmine\block\tile\FlowerPot as TileFlowerPot;
use pocketmine\block\tile\GlowingItemFrame as TileGlowingItemFrame;
use pocketmine\block\tile\HangingSign as TileHangingSign;
use pocketmine\block\tile\Hopper as TileHopper;
use pocketmine\block\tile\ItemFrame as TileItemFrame;
use pocketmine\block\tile\Jukebox as TileJukebox;
@ -81,8 +80,6 @@ use function strtolower;
* @generate-registry-docblock
*
* @method static WoodenButton ACACIA_BUTTON()
* @method static CeilingCenterHangingSign ACACIA_CEILING_CENTER_HANGING_SIGN()
* @method static CeilingEdgesHangingSign ACACIA_CEILING_EDGES_HANGING_SIGN()
* @method static WoodenDoor ACACIA_DOOR()
* @method static WoodenFence ACACIA_FENCE()
* @method static FenceGate ACACIA_FENCE_GATE()
@ -95,7 +92,6 @@ use function strtolower;
* @method static WoodenSlab ACACIA_SLAB()
* @method static WoodenStairs ACACIA_STAIRS()
* @method static WoodenTrapdoor ACACIA_TRAPDOOR()
* @method static WallHangingSign ACACIA_WALL_HANGING_SIGN()
* @method static WallSign ACACIA_WALL_SIGN()
* @method static Wood ACACIA_WOOD()
* @method static ActivatorRail ACTIVATOR_RAIL()
@ -126,8 +122,6 @@ use function strtolower;
* @method static BigDripleafHead BIG_DRIPLEAF_HEAD()
* @method static BigDripleafStem BIG_DRIPLEAF_STEM()
* @method static WoodenButton BIRCH_BUTTON()
* @method static CeilingCenterHangingSign BIRCH_CEILING_CENTER_HANGING_SIGN()
* @method static CeilingEdgesHangingSign BIRCH_CEILING_EDGES_HANGING_SIGN()
* @method static WoodenDoor BIRCH_DOOR()
* @method static WoodenFence BIRCH_FENCE()
* @method static FenceGate BIRCH_FENCE_GATE()
@ -140,7 +134,6 @@ use function strtolower;
* @method static WoodenSlab BIRCH_SLAB()
* @method static WoodenStairs BIRCH_STAIRS()
* @method static WoodenTrapdoor BIRCH_TRAPDOOR()
* @method static WallHangingSign BIRCH_WALL_HANGING_SIGN()
* @method static WallSign BIRCH_WALL_SIGN()
* @method static Wood BIRCH_WOOD()
* @method static Opaque BLACKSTONE()
@ -177,8 +170,6 @@ use function strtolower;
* @method static Chain CHAIN()
* @method static ChemicalHeat CHEMICAL_HEAT()
* @method static WoodenButton CHERRY_BUTTON()
* @method static CeilingCenterHangingSign CHERRY_CEILING_CENTER_HANGING_SIGN()
* @method static CeilingEdgesHangingSign CHERRY_CEILING_EDGES_HANGING_SIGN()
* @method static WoodenDoor CHERRY_DOOR()
* @method static WoodenFence CHERRY_FENCE()
* @method static FenceGate CHERRY_FENCE_GATE()
@ -190,7 +181,6 @@ use function strtolower;
* @method static WoodenSlab CHERRY_SLAB()
* @method static WoodenStairs CHERRY_STAIRS()
* @method static WoodenTrapdoor CHERRY_TRAPDOOR()
* @method static WallHangingSign CHERRY_WALL_HANGING_SIGN()
* @method static WallSign CHERRY_WALL_SIGN()
* @method static Wood CHERRY_WOOD()
* @method static Chest CHEST()
@ -241,8 +231,6 @@ use function strtolower;
* @method static Opaque CRACKED_STONE_BRICKS()
* @method static CraftingTable CRAFTING_TABLE()
* @method static WoodenButton CRIMSON_BUTTON()
* @method static CeilingCenterHangingSign CRIMSON_CEILING_CENTER_HANGING_SIGN()
* @method static CeilingEdgesHangingSign CRIMSON_CEILING_EDGES_HANGING_SIGN()
* @method static WoodenDoor CRIMSON_DOOR()
* @method static WoodenFence CRIMSON_FENCE()
* @method static FenceGate CRIMSON_FENCE_GATE()
@ -255,7 +243,6 @@ use function strtolower;
* @method static WoodenStairs CRIMSON_STAIRS()
* @method static Wood CRIMSON_STEM()
* @method static WoodenTrapdoor CRIMSON_TRAPDOOR()
* @method static WallHangingSign CRIMSON_WALL_HANGING_SIGN()
* @method static WallSign CRIMSON_WALL_SIGN()
* @method static Opaque CRYING_OBSIDIAN()
* @method static Copper CUT_COPPER()
@ -267,8 +254,6 @@ use function strtolower;
* @method static Slab CUT_SANDSTONE_SLAB()
* @method static Flower DANDELION()
* @method static WoodenButton DARK_OAK_BUTTON()
* @method static CeilingCenterHangingSign DARK_OAK_CEILING_CENTER_HANGING_SIGN()
* @method static CeilingEdgesHangingSign DARK_OAK_CEILING_EDGES_HANGING_SIGN()
* @method static WoodenDoor DARK_OAK_DOOR()
* @method static WoodenFence DARK_OAK_FENCE()
* @method static FenceGate DARK_OAK_FENCE_GATE()
@ -281,7 +266,6 @@ use function strtolower;
* @method static WoodenSlab DARK_OAK_SLAB()
* @method static WoodenStairs DARK_OAK_STAIRS()
* @method static WoodenTrapdoor DARK_OAK_TRAPDOOR()
* @method static WallHangingSign DARK_OAK_WALL_HANGING_SIGN()
* @method static WallSign DARK_OAK_WALL_SIGN()
* @method static Wood DARK_OAK_WOOD()
* @method static Opaque DARK_PRISMARINE()
@ -504,8 +488,6 @@ use function strtolower;
* @method static ItemFrame ITEM_FRAME()
* @method static Jukebox JUKEBOX()
* @method static WoodenButton JUNGLE_BUTTON()
* @method static CeilingCenterHangingSign JUNGLE_CEILING_CENTER_HANGING_SIGN()
* @method static CeilingEdgesHangingSign JUNGLE_CEILING_EDGES_HANGING_SIGN()
* @method static WoodenDoor JUNGLE_DOOR()
* @method static WoodenFence JUNGLE_FENCE()
* @method static FenceGate JUNGLE_FENCE_GATE()
@ -518,7 +500,6 @@ use function strtolower;
* @method static WoodenSlab JUNGLE_SLAB()
* @method static WoodenStairs JUNGLE_STAIRS()
* @method static WoodenTrapdoor JUNGLE_TRAPDOOR()
* @method static WallHangingSign JUNGLE_WALL_HANGING_SIGN()
* @method static WallSign JUNGLE_WALL_SIGN()
* @method static Wood JUNGLE_WOOD()
* @method static ChemistryTable LAB_TABLE()
@ -541,8 +522,6 @@ use function strtolower;
* @method static Loom LOOM()
* @method static Magma MAGMA()
* @method static WoodenButton MANGROVE_BUTTON()
* @method static CeilingCenterHangingSign MANGROVE_CEILING_CENTER_HANGING_SIGN()
* @method static CeilingEdgesHangingSign MANGROVE_CEILING_EDGES_HANGING_SIGN()
* @method static WoodenDoor MANGROVE_DOOR()
* @method static WoodenFence MANGROVE_FENCE()
* @method static FenceGate MANGROVE_FENCE_GATE()
@ -555,7 +534,6 @@ use function strtolower;
* @method static WoodenSlab MANGROVE_SLAB()
* @method static WoodenStairs MANGROVE_STAIRS()
* @method static WoodenTrapdoor MANGROVE_TRAPDOOR()
* @method static WallHangingSign MANGROVE_WALL_HANGING_SIGN()
* @method static WallSign MANGROVE_WALL_SIGN()
* @method static Wood MANGROVE_WOOD()
* @method static ChemistryTable MATERIAL_REDUCER()
@ -594,8 +572,6 @@ use function strtolower;
* @method static Opaque NETHER_WART_BLOCK()
* @method static Note NOTE_BLOCK()
* @method static WoodenButton OAK_BUTTON()
* @method static CeilingCenterHangingSign OAK_CEILING_CENTER_HANGING_SIGN()
* @method static CeilingEdgesHangingSign OAK_CEILING_EDGES_HANGING_SIGN()
* @method static WoodenDoor OAK_DOOR()
* @method static WoodenFence OAK_FENCE()
* @method static FenceGate OAK_FENCE_GATE()
@ -608,19 +584,14 @@ use function strtolower;
* @method static WoodenSlab OAK_SLAB()
* @method static WoodenStairs OAK_STAIRS()
* @method static WoodenTrapdoor OAK_TRAPDOOR()
* @method static WallHangingSign OAK_WALL_HANGING_SIGN()
* @method static WallSign OAK_WALL_SIGN()
* @method static Wood OAK_WOOD()
* @method static Opaque OBSIDIAN()
* @method static OminousFloorBanner OMINOUS_BANNER()
* @method static OminousWallBanner OMINOUS_WALL_BANNER()
* @method static Flower ORANGE_TULIP()
* @method static Flower OXEYE_DAISY()
* @method static PackedIce PACKED_ICE()
* @method static Opaque PACKED_MUD()
* @method static WoodenButton PALE_OAK_BUTTON()
* @method static CeilingCenterHangingSign PALE_OAK_CEILING_CENTER_HANGING_SIGN()
* @method static CeilingEdgesHangingSign PALE_OAK_CEILING_EDGES_HANGING_SIGN()
* @method static WoodenDoor PALE_OAK_DOOR()
* @method static WoodenFence PALE_OAK_FENCE()
* @method static FenceGate PALE_OAK_FENCE_GATE()
@ -632,7 +603,6 @@ use function strtolower;
* @method static WoodenSlab PALE_OAK_SLAB()
* @method static WoodenStairs PALE_OAK_STAIRS()
* @method static WoodenTrapdoor PALE_OAK_TRAPDOOR()
* @method static WallHangingSign PALE_OAK_WALL_HANGING_SIGN()
* @method static WallSign PALE_OAK_WALL_SIGN()
* @method static Wood PALE_OAK_WOOD()
* @method static DoublePlant PEONY()
@ -763,8 +733,6 @@ use function strtolower;
* @method static Sponge SPONGE()
* @method static SporeBlossom SPORE_BLOSSOM()
* @method static WoodenButton SPRUCE_BUTTON()
* @method static CeilingCenterHangingSign SPRUCE_CEILING_CENTER_HANGING_SIGN()
* @method static CeilingEdgesHangingSign SPRUCE_CEILING_EDGES_HANGING_SIGN()
* @method static WoodenDoor SPRUCE_DOOR()
* @method static WoodenFence SPRUCE_FENCE()
* @method static FenceGate SPRUCE_FENCE_GATE()
@ -777,7 +745,6 @@ use function strtolower;
* @method static WoodenSlab SPRUCE_SLAB()
* @method static WoodenStairs SPRUCE_STAIRS()
* @method static WoodenTrapdoor SPRUCE_TRAPDOOR()
* @method static WallHangingSign SPRUCE_WALL_HANGING_SIGN()
* @method static WallSign SPRUCE_WALL_SIGN()
* @method static Wood SPRUCE_WOOD()
* @method static StainedHardenedClay STAINED_CLAY()
@ -821,8 +788,6 @@ use function strtolower;
* @method static WallBanner WALL_BANNER()
* @method static WallCoralFan WALL_CORAL_FAN()
* @method static WoodenButton WARPED_BUTTON()
* @method static CeilingCenterHangingSign WARPED_CEILING_CENTER_HANGING_SIGN()
* @method static CeilingEdgesHangingSign WARPED_CEILING_EDGES_HANGING_SIGN()
* @method static WoodenDoor WARPED_DOOR()
* @method static WoodenFence WARPED_FENCE()
* @method static FenceGate WARPED_FENCE_GATE()
@ -835,14 +800,13 @@ use function strtolower;
* @method static WoodenStairs WARPED_STAIRS()
* @method static Wood WARPED_STEM()
* @method static WoodenTrapdoor WARPED_TRAPDOOR()
* @method static WallHangingSign WARPED_WALL_HANGING_SIGN()
* @method static WallSign WARPED_WALL_SIGN()
* @method static Opaque WARPED_WART_BLOCK()
* @method static Water WATER()
* @method static WaterCauldron WATER_CAULDRON()
* @method static NetherVines WEEPING_VINES()
* @method static WeightedPressurePlateHeavy WEIGHTED_PRESSURE_PLATE_HEAVY()
* @method static WeightedPressurePlateLight WEIGHTED_PRESSURE_PLATE_LIGHT()
* @method static WeightedPressurePlate WEIGHTED_PRESSURE_PLATE_HEAVY()
* @method static WeightedPressurePlate WEIGHTED_PRESSURE_PLATE_LIGHT()
* @method static Wheat WHEAT()
* @method static Flower WHITE_TULIP()
* @method static WitherRose WITHER_ROSE()
@ -909,8 +873,6 @@ final class VanillaBlocks{
$bannerBreakInfo = new Info(BreakInfo::axe(1.0));
self::register("banner", fn(BID $id) => new FloorBanner($id, "Banner", $bannerBreakInfo), TileBanner::class);
self::register("wall_banner", fn(BID $id) => new WallBanner($id, "Wall Banner", $bannerBreakInfo), TileBanner::class);
self::register("ominous_banner", fn(BID $id) => new OminousFloorBanner($id, "Ominous Banner", $bannerBreakInfo), TileBanner::class);
self::register("ominous_wall_banner", fn(BID $id) => new OminousWallBanner($id, "Ominous Wall Banner", $bannerBreakInfo), TileBanner::class);
self::register("barrel", fn(BID $id) => new Barrel($id, "Barrel", new Info(BreakInfo::axe(2.5))), TileBarrel::class);
self::register("barrier", fn(BID $id) => new Transparent($id, "Barrier", new Info(BreakInfo::indestructible())));
self::register("beacon", fn(BID $id) => new Beacon($id, "Beacon", new Info(new BreakInfo(3.0))), TileBeacon::class);
@ -1241,14 +1203,14 @@ final class VanillaBlocks{
self::register("lily_pad", fn(BID $id) => new WaterLily($id, "Lily Pad", new Info(BreakInfo::instant())));
$weightedPressurePlateBreakInfo = new Info(BreakInfo::pickaxe(0.5));
self::register("weighted_pressure_plate_heavy", fn(BID $id) => new WeightedPressurePlateHeavy(
self::register("weighted_pressure_plate_heavy", fn(BID $id) => new WeightedPressurePlate(
$id,
"Weighted Pressure Plate Heavy",
$weightedPressurePlateBreakInfo,
deactivationDelayTicks: 10,
signalStrengthFactor: 0.1
));
self::register("weighted_pressure_plate_light", fn(BID $id) => new WeightedPressurePlateLight(
self::register("weighted_pressure_plate_light", fn(BID $id) => new WeightedPressurePlate(
$id,
"Weighted Pressure Plate Light",
$weightedPressurePlateBreakInfo,
@ -1391,7 +1353,6 @@ final class VanillaBlocks{
private static function registerWoodenBlocks() : void{
$planksBreakInfo = new Info(BreakInfo::axe(2.0, null, 15.0));
$signBreakInfo = new Info(BreakInfo::axe(1.0));
$hangingSignBreakInfo = new Info(BreakInfo::axe(1.0), [Tags::HANGING_SIGN]);
$logBreakInfo = new Info(BreakInfo::axe(2.0));
$woodenDoorBreakInfo = new Info(BreakInfo::axe(3.0, null, 15.0));
$woodenButtonBreakInfo = new Info(BreakInfo::axe(0.5));
@ -1431,23 +1392,6 @@ final class VanillaBlocks{
};
self::register($idName("sign"), fn(BID $id) => new FloorSign($id, $name . " Sign", $signBreakInfo, $woodType, $signAsItem), TileSign::class);
self::register($idName("wall_sign"), fn(BID $id) => new WallSign($id, $name . " Wall Sign", $signBreakInfo, $woodType, $signAsItem), TileSign::class);
$hangingSignAsItem = match($woodType){
WoodType::OAK => VanillaItems::OAK_HANGING_SIGN(...),
WoodType::SPRUCE => VanillaItems::SPRUCE_HANGING_SIGN(...),
WoodType::BIRCH => VanillaItems::BIRCH_HANGING_SIGN(...),
WoodType::JUNGLE => VanillaItems::JUNGLE_HANGING_SIGN(...),
WoodType::ACACIA => VanillaItems::ACACIA_HANGING_SIGN(...),
WoodType::DARK_OAK => VanillaItems::DARK_OAK_HANGING_SIGN(...),
WoodType::MANGROVE => VanillaItems::MANGROVE_HANGING_SIGN(...),
WoodType::CRIMSON => VanillaItems::CRIMSON_HANGING_SIGN(...),
WoodType::WARPED => VanillaItems::WARPED_HANGING_SIGN(...),
WoodType::CHERRY => VanillaItems::CHERRY_HANGING_SIGN(...),
WoodType::PALE_OAK => VanillaItems::PALE_OAK_HANGING_SIGN(...),
};
self::register($idName("ceiling_center_hanging_sign"), fn(BID $id) => new CeilingCenterHangingSign($id, $name . " Center Hanging Sign", $hangingSignBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
self::register($idName("ceiling_edges_hanging_sign"), fn(BID $id) => new CeilingEdgesHangingSign($id, $name . " Edges Hanging Sign", $hangingSignBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
self::register($idName("wall_hanging_sign"), fn(BID $id) => new WallHangingSign($id, $name . " Wall Hanging Sign", $hangingSignBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
}
}

View File

@ -35,10 +35,6 @@ use pocketmine\world\BlockTransaction;
final class WallBanner extends BaseBanner implements HorizontalFacing{
use HorizontalFacingTrait;
protected function getOminousVersion() : Block{
return VanillaBlocks::OMINOUS_WALL_BANNER()->setFacing($this->facing);
}
protected function getSupportingFace() : int{
return Facing::opposite($this->facing);
}

View File

@ -1,81 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\utils\HorizontalFacing;
use pocketmine\block\utils\HorizontalFacingTrait;
use pocketmine\block\utils\SupportType;
use pocketmine\item\Item;
use pocketmine\math\Axis;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\world\BlockTransaction;
final class WallHangingSign extends BaseSign implements HorizontalFacing{
use HorizontalFacingTrait;
protected function getSupportingFace() : int{
return Facing::rotateY($this->facing, clockwise: true);
}
public function onNearbyBlockChange() : void{
//NOOP - disable default self-destruct behaviour
}
protected function recalculateCollisionBoxes() : array{
//only the cross bar is collidable
return [AxisAlignedBB::one()->trim(Facing::DOWN, 7 / 8)->squash(Facing::axis($this->facing), 3 / 4)];
}
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($player === null){
return false;
}
$attachFace = Facing::axis($face) === Axis::Y ? Facing::rotateY($player->getHorizontalFacing(), clockwise: true) : $face;
if($this->canBeSupportedAt($blockReplace->getSide($attachFace), $attachFace)){
$direction = $attachFace;
}elseif($this->canBeSupportedAt($blockReplace->getSide($opposite = Facing::opposite($attachFace)), $opposite)){
$direction = $opposite;
}else{
return false;
}
$this->facing = Facing::rotateY(Facing::opposite($direction), clockwise: true);
//the front should always face the player if possible
if($this->facing === $player->getHorizontalFacing()){
$this->facing = Facing::opposite($this->facing);
}
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
}
private function canBeSupportedAt(Block $block, int $face) : bool{
return
($block instanceof WallHangingSign && Facing::axis(Facing::rotateY($block->getFacing(), clockwise: true)) === Facing::axis($face)) ||
$block->getSupportType(Facing::opposite($face)) === SupportType::FULL;
}
}

View File

@ -1,31 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block;
/**
* @deprecated
*/
class WeightedPressurePlateHeavy extends WeightedPressurePlate{
}

View File

@ -1,31 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block;
/**
* @deprecated
*/
class WeightedPressurePlateLight extends WeightedPressurePlate{
}

View File

@ -41,10 +41,6 @@ class Banner extends Spawnable{
public const TAG_PATTERNS = "Patterns";
public const TAG_PATTERN_COLOR = "Color";
public const TAG_PATTERN_NAME = "Pattern";
public const TAG_TYPE = "Type";
public const TYPE_NORMAL = 0;
public const TYPE_OMINOUS = 1;
private DyeColor $baseColor = DyeColor::BLACK;
@ -54,8 +50,6 @@ class Banner extends Spawnable{
*/
private array $patterns = [];
private int $type = self::TYPE_NORMAL;
public function readSaveData(CompoundTag $nbt) : void{
$colorIdMap = DyeColorIdMap::getInstance();
if(
@ -81,8 +75,6 @@ class Banner extends Spawnable{
$this->patterns[] = new BannerPatternLayer($patternType, $patternColor);
}
}
$this->type = $nbt->getInt(self::TAG_TYPE, self::TYPE_NORMAL);
}
protected function writeSaveData(CompoundTag $nbt) : void{
@ -97,7 +89,6 @@ class Banner extends Spawnable{
);
}
$nbt->setTag(self::TAG_PATTERNS, $patterns);
$nbt->setInt(self::TAG_TYPE, $this->type);
}
protected function addAdditionalSpawnData(CompoundTag $nbt) : void{
@ -112,7 +103,6 @@ class Banner extends Spawnable{
);
}
$nbt->setTag(self::TAG_PATTERNS, $patterns);
$nbt->setInt(self::TAG_TYPE, $this->type);
}
/**
@ -146,10 +136,6 @@ class Banner extends Spawnable{
$this->patterns = $patterns;
}
public function getType() : int{ return $this->type; }
public function setType(int $type) : void{ $this->type = $type; }
public function getDefaultName() : string{
return "Banner";
}

View File

@ -1,31 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block\tile;
/**
* @deprecated
*/
final class HangingSign extends Sign{
}

View File

@ -37,7 +37,6 @@ use function array_slice;
use function explode;
use function implode;
use function mb_scrub;
use function rtrim;
use function sprintf;
/**
@ -118,7 +117,7 @@ class Sign extends Spawnable{
protected function writeSaveData(CompoundTag $nbt) : void{
$nbt->setTag(self::TAG_FRONT_TEXT, CompoundTag::create()
->setString(self::TAG_TEXT_BLOB, rtrim(implode("\n", $this->text->getLines()), "\n"))
->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text->getLines()))
->setInt(self::TAG_TEXT_COLOR, Binary::signInt($this->text->getBaseColor()->toARGB()))
->setByte(self::TAG_GLOWING_TEXT, $this->text->isGlowing() ? 1 : 0)
->setByte(self::TAG_PERSIST_FORMATTING, 1)
@ -163,7 +162,7 @@ class Sign extends Spawnable{
protected function addAdditionalSpawnData(CompoundTag $nbt) : void{
$nbt->setTag(self::TAG_FRONT_TEXT, CompoundTag::create()
->setString(self::TAG_TEXT_BLOB, rtrim(implode("\n", $this->text->getLines()), "\n"))
->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text->getLines()))
->setInt(self::TAG_TEXT_COLOR, Binary::signInt($this->text->getBaseColor()->toARGB()))
->setByte(self::TAG_GLOWING_TEXT, $this->text->isGlowing() ? 1 : 0)
->setByte(self::TAG_PERSIST_FORMATTING, 1) //TODO: not sure what this is used for

View File

@ -35,20 +35,6 @@ abstract class Spawnable extends Tile{
/** @phpstan-var CacheableNbt<CompoundTag>|null */
private ?CacheableNbt $spawnCompoundCache = null;
/**
* @deprecated
*/
public function isDirty() : bool{
return $this->spawnCompoundCache === null;
}
/**
* @deprecated
*/
public function setDirty(bool $dirty = true) : void{
$this->clearSpawnCompoundCache();
}
public function clearSpawnCompoundCache() : void{
$this->spawnCompoundCache = null;
}

View File

@ -79,7 +79,6 @@ final class TileFactory{
$this->register(SporeBlossom::class, ["SporeBlossom", "minecraft:spore_blossom"]);
$this->register(MobHead::class, ["Skull", "minecraft:skull"]);
$this->register(GlowingItemFrame::class, ["GlowItemFrame"]);
$this->register(HangingSign::class, ["HangingSign", "minecraft:hanging_sign"]);
//TODO: ChalkboardBlock
//TODO: ChemistryTable

View File

@ -27,10 +27,7 @@ interface Ageable{
public function getAge() : int;
public function getMaxAge() : int;
/**
* Must be in range 0 - getMaxAge()
* @return $this
*/
public function setAge(int $age) : self;

View File

@ -38,8 +38,6 @@ trait AgeableTrait{
public function getAge() : int{ return $this->age; }
public function getMaxAge() : int{ return self::MAX_AGE; }
/**
* @return $this
*/

View File

@ -23,54 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static BannerPatternType BORDER()
* @method static BannerPatternType BRICKS()
* @method static BannerPatternType CIRCLE()
* @method static BannerPatternType CREEPER()
* @method static BannerPatternType CROSS()
* @method static BannerPatternType CURLY_BORDER()
* @method static BannerPatternType DIAGONAL_LEFT()
* @method static BannerPatternType DIAGONAL_RIGHT()
* @method static BannerPatternType DIAGONAL_UP_LEFT()
* @method static BannerPatternType DIAGONAL_UP_RIGHT()
* @method static BannerPatternType FLOWER()
* @method static BannerPatternType GRADIENT()
* @method static BannerPatternType GRADIENT_UP()
* @method static BannerPatternType HALF_HORIZONTAL()
* @method static BannerPatternType HALF_HORIZONTAL_BOTTOM()
* @method static BannerPatternType HALF_VERTICAL()
* @method static BannerPatternType HALF_VERTICAL_RIGHT()
* @method static BannerPatternType MOJANG()
* @method static BannerPatternType RHOMBUS()
* @method static BannerPatternType SKULL()
* @method static BannerPatternType SMALL_STRIPES()
* @method static BannerPatternType SQUARE_BOTTOM_LEFT()
* @method static BannerPatternType SQUARE_BOTTOM_RIGHT()
* @method static BannerPatternType SQUARE_TOP_LEFT()
* @method static BannerPatternType SQUARE_TOP_RIGHT()
* @method static BannerPatternType STRAIGHT_CROSS()
* @method static BannerPatternType STRIPE_BOTTOM()
* @method static BannerPatternType STRIPE_CENTER()
* @method static BannerPatternType STRIPE_DOWNLEFT()
* @method static BannerPatternType STRIPE_DOWNRIGHT()
* @method static BannerPatternType STRIPE_LEFT()
* @method static BannerPatternType STRIPE_MIDDLE()
* @method static BannerPatternType STRIPE_RIGHT()
* @method static BannerPatternType STRIPE_TOP()
* @method static BannerPatternType TRIANGLES_BOTTOM()
* @method static BannerPatternType TRIANGLES_TOP()
* @method static BannerPatternType TRIANGLE_BOTTOM()
* @method static BannerPatternType TRIANGLE_TOP()
*/
enum BannerPatternType{
use LegacyEnumShimTrait;
case BORDER;
case BRICKS;
case CIRCLE;

View File

@ -23,20 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static BellAttachmentType CEILING()
* @method static BellAttachmentType FLOOR()
* @method static BellAttachmentType ONE_WALL()
* @method static BellAttachmentType TWO_WALLS()
*/
enum BellAttachmentType{
use LegacyEnumShimTrait;
case CEILING;
case FLOOR;
case ONE_WALL;

View File

@ -24,19 +24,8 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\block\inventory\BrewingStandInventory;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static BrewingStandSlot EAST()
* @method static BrewingStandSlot NORTHWEST()
* @method static BrewingStandSlot SOUTHWEST()
*/
enum BrewingStandSlot{
use LegacyEnumShimTrait;
case EAST;
case NORTHWEST;
case SOUTHWEST;

View File

@ -23,20 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static CopperOxidation EXPOSED()
* @method static CopperOxidation NONE()
* @method static CopperOxidation OXIDIZED()
* @method static CopperOxidation WEATHERED()
*/
enum CopperOxidation : int{
use LegacyEnumShimTrait;
case NONE = 0;
case EXPOSED = 1;
case WEATHERED = 2;

View File

@ -23,21 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static CoralType BRAIN()
* @method static CoralType BUBBLE()
* @method static CoralType FIRE()
* @method static CoralType HORN()
* @method static CoralType TUBE()
*/
enum CoralType{
use LegacyEnumShimTrait;
case TUBE;
case BRAIN;
case BUBBLE;

View File

@ -23,19 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static DirtType COARSE()
* @method static DirtType NORMAL()
* @method static DirtType ROOTED()
*/
enum DirtType{
use LegacyEnumShimTrait;
case NORMAL;
case COARSE;
case ROOTED;

View File

@ -23,20 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static DripleafState FULL_TILT()
* @method static DripleafState PARTIAL_TILT()
* @method static DripleafState STABLE()
* @method static DripleafState UNSTABLE()
*/
enum DripleafState{
use LegacyEnumShimTrait;
case STABLE;
case UNSTABLE;
case PARTIAL_TILT;

View File

@ -24,35 +24,12 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\color\Color;
use pocketmine\utils\LegacyEnumShimTrait;
use function spl_object_id;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static DyeColor BLACK()
* @method static DyeColor BLUE()
* @method static DyeColor BROWN()
* @method static DyeColor CYAN()
* @method static DyeColor GRAY()
* @method static DyeColor GREEN()
* @method static DyeColor LIGHT_BLUE()
* @method static DyeColor LIGHT_GRAY()
* @method static DyeColor LIME()
* @method static DyeColor MAGENTA()
* @method static DyeColor ORANGE()
* @method static DyeColor PINK()
* @method static DyeColor PURPLE()
* @method static DyeColor RED()
* @method static DyeColor WHITE()
* @method static DyeColor YELLOW()
*
* @phpstan-type TMetadata array{0: string, 1: Color}
*/
enum DyeColor{
use LegacyEnumShimTrait;
case WHITE;
case ORANGE;
case MAGENTA;

View File

@ -23,19 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static FroglightType OCHRE()
* @method static FroglightType PEARLESCENT()
* @method static FroglightType VERDANT()
*/
enum FroglightType{
use LegacyEnumShimTrait;
case OCHRE;
case PEARLESCENT;
case VERDANT;

View File

@ -23,26 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static LeavesType ACACIA()
* @method static LeavesType AZALEA()
* @method static LeavesType BIRCH()
* @method static LeavesType CHERRY()
* @method static LeavesType DARK_OAK()
* @method static LeavesType FLOWERING_AZALEA()
* @method static LeavesType JUNGLE()
* @method static LeavesType MANGROVE()
* @method static LeavesType OAK()
* @method static LeavesType SPRUCE()
*/
enum LeavesType{
use LegacyEnumShimTrait;
case OAK;
case SPRUCE;
case BIRCH;

View File

@ -24,24 +24,8 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\math\Facing;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static LeverFacing DOWN_AXIS_X()
* @method static LeverFacing DOWN_AXIS_Z()
* @method static LeverFacing EAST()
* @method static LeverFacing NORTH()
* @method static LeverFacing SOUTH()
* @method static LeverFacing UP_AXIS_X()
* @method static LeverFacing UP_AXIS_Z()
* @method static LeverFacing WEST()
*/
enum LeverFacing{
use LegacyEnumShimTrait;
case UP_AXIS_X;
case UP_AXIS_Z;
case DOWN_AXIS_X;

View File

@ -23,23 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static MobHeadType CREEPER()
* @method static MobHeadType DRAGON()
* @method static MobHeadType PIGLIN()
* @method static MobHeadType PLAYER()
* @method static MobHeadType SKELETON()
* @method static MobHeadType WITHER_SKELETON()
* @method static MobHeadType ZOMBIE()
*/
enum MobHeadType{
use LegacyEnumShimTrait;
case SKELETON;
case WITHER_SKELETON;
case ZOMBIE;

View File

@ -25,7 +25,7 @@ namespace pocketmine\block\utils;
use pocketmine\math\Facing;
interface MultiAnyFacing{
interface MultiFacing{
/**
* @return int[]

View File

@ -23,27 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static MushroomBlockType ALL_CAP()
* @method static MushroomBlockType CAP_EAST()
* @method static MushroomBlockType CAP_MIDDLE()
* @method static MushroomBlockType CAP_NORTH()
* @method static MushroomBlockType CAP_NORTHEAST()
* @method static MushroomBlockType CAP_NORTHWEST()
* @method static MushroomBlockType CAP_SOUTH()
* @method static MushroomBlockType CAP_SOUTHEAST()
* @method static MushroomBlockType CAP_SOUTHWEST()
* @method static MushroomBlockType CAP_WEST()
* @method static MushroomBlockType PORES()
*/
enum MushroomBlockType{
use LegacyEnumShimTrait;
case PORES;
case CAP_NORTHWEST;
case CAP_NORTH;

View File

@ -26,34 +26,12 @@ namespace pocketmine\block\utils;
use pocketmine\lang\KnownTranslationFactory;
use pocketmine\lang\Translatable;
use pocketmine\network\mcpe\protocol\types\LevelSoundEvent;
use pocketmine\utils\LegacyEnumShimTrait;
use function spl_object_id;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static RecordType DISK_11()
* @method static RecordType DISK_13()
* @method static RecordType DISK_5()
* @method static RecordType DISK_BLOCKS()
* @method static RecordType DISK_CAT()
* @method static RecordType DISK_CHIRP()
* @method static RecordType DISK_FAR()
* @method static RecordType DISK_MALL()
* @method static RecordType DISK_MELLOHI()
* @method static RecordType DISK_OTHERSIDE()
* @method static RecordType DISK_PIGSTEP()
* @method static RecordType DISK_STAL()
* @method static RecordType DISK_STRAD()
* @method static RecordType DISK_WAIT()
* @method static RecordType DISK_WARD()
*
* @phpstan-type TMetadata array{0: string, 1: LevelSoundEvent::*, 2: Translatable}
*/
enum RecordType{
use LegacyEnumShimTrait;
case DISK_13;
case DISK_5;
case DISK_CAT;

View File

@ -23,23 +23,9 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
use pocketmine\world\generator\object\TreeType;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static SaplingType ACACIA()
* @method static SaplingType BIRCH()
* @method static SaplingType DARK_OAK()
* @method static SaplingType JUNGLE()
* @method static SaplingType OAK()
* @method static SaplingType SPRUCE()
*/
enum SaplingType{
use LegacyEnumShimTrait;
case OAK;
case SPRUCE;
case BIRCH;

View File

@ -23,19 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static SlabType BOTTOM()
* @method static SlabType DOUBLE()
* @method static SlabType TOP()
*/
enum SlabType{
use LegacyEnumShimTrait;
case BOTTOM;
case TOP;
case DOUBLE;

View File

@ -23,21 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static StairShape INNER_LEFT()
* @method static StairShape INNER_RIGHT()
* @method static StairShape OUTER_LEFT()
* @method static StairShape OUTER_RIGHT()
* @method static StairShape STRAIGHT()
*/
enum StairShape{
use LegacyEnumShimTrait;
case STRAIGHT;
case INNER_LEFT;
case INNER_RIGHT;

View File

@ -23,20 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static SupportType CENTER()
* @method static SupportType EDGE()
* @method static SupportType FULL()
* @method static SupportType NONE()
*/
enum SupportType{
use LegacyEnumShimTrait;
case FULL;
case CENTER;
case EDGE;

View File

@ -23,18 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static WallConnectionType SHORT()
* @method static WallConnectionType TALL()
*/
enum WallConnectionType{
use LegacyEnumShimTrait;
case SHORT;
case TALL;
}

View File

@ -23,26 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\utils\LegacyEnumShimTrait;
/**
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static WoodType ACACIA()
* @method static WoodType BIRCH()
* @method static WoodType CHERRY()
* @method static WoodType CRIMSON()
* @method static WoodType DARK_OAK()
* @method static WoodType JUNGLE()
* @method static WoodType MANGROVE()
* @method static WoodType OAK()
* @method static WoodType SPRUCE()
* @method static WoodType WARPED()
*/
enum WoodType{
use LegacyEnumShimTrait;
case OAK;
case SPRUCE;
case BIRCH;

View File

@ -38,19 +38,17 @@ final class ClosureCommand extends Command{
* @phpstan-param Execute $execute
*/
public function __construct(
string $name,
\Closure $execute,
array $permissions,
Translatable|string $description = "",
Translatable|string|null $usageMessage = null,
array $aliases = []
){
Utils::validateCallableSignature(
fn(CommandSender $sender, Command $command, string $commandLabel, array $args) : mixed => 1,
$execute,
);
$this->execute = $execute;
parent::__construct($name, $description, $usageMessage, $aliases);
parent::__construct($description, $usageMessage);
$this->setPermissions($permissions);
}

View File

@ -33,52 +33,20 @@ use pocketmine\permission\PermissionManager;
use pocketmine\Server;
use pocketmine\utils\BroadcastLoggerForwarder;
use pocketmine\utils\TextFormat;
use function array_values;
use function explode;
use function implode;
use function str_replace;
use const PHP_INT_MAX;
abstract class Command{
private string $name;
private string $nextLabel;
private string $label;
/**
* @var string[]
* @phpstan-var list<string>
*/
private array $aliases = [];
/**
* @var string[]
* @phpstan-var list<string>
*/
private array $activeAliases = [];
private ?CommandMap $commandMap = null;
protected Translatable|string $description = "";
protected Translatable|string $usageMessage;
/** @var string[] */
private array $permission = [];
private ?string $permissionMessage = null;
private Translatable|string|null $permissionMessage = null;
/**
* @param string[] $aliases
* @phpstan-param list<string> $aliases
*/
public function __construct(string $name, Translatable|string $description = "", Translatable|string|null $usageMessage = null, array $aliases = []){
$this->name = $name;
$this->setLabel($name);
$this->setDescription($description);
$this->usageMessage = $usageMessage ?? ("/" . $name);
$this->setAliases($aliases);
}
public function __construct(
private Translatable|string $description = "",
private Translatable|string|null $usageMessage = null
){}
/**
* @param string[] $args
@ -89,10 +57,6 @@ abstract class Command{
*/
abstract public function execute(CommandSender $sender, string $commandLabel, array $args);
public function getName() : string{
return $this->name;
}
/**
* @return string[]
*/
@ -117,15 +81,21 @@ abstract class Command{
$this->setPermissions($permission === null ? [] : explode(";", $permission, limit: PHP_INT_MAX));
}
public function testPermission(CommandSender $target, ?string $permission = null) : bool{
/**
* @param string $context usually the command name, but may include extra args if useful (e.g. for subcommands)
* @param CommandSender $target the target to check the permission for
* @param string|null $permission the permission to check, if null, will check if the target has any of the command's permissions
*/
public function testPermission(string $context, CommandSender $target, ?string $permission = null) : bool{
if($this->testPermissionSilent($target, $permission)){
return true;
}
if($this->permissionMessage === null){
$target->sendMessage(KnownTranslationFactory::pocketmine_command_error_permission($this->name)->prefix(TextFormat::RED));
}elseif($this->permissionMessage !== ""){
$target->sendMessage(str_replace("<permission>", $permission ?? implode(";", $this->permission), $this->permissionMessage));
$message = $this->permissionMessage ?? KnownTranslationFactory::pocketmine_command_error_permission($context);
if($message instanceof Translatable){
$target->sendMessage($message->prefix(TextFormat::RED));
}elseif($message !== ""){
$target->sendMessage(str_replace("<permission>", $permission ?? implode(";", $this->permission), $message));
}
return false;
@ -142,63 +112,7 @@ abstract class Command{
return false;
}
public function getLabel() : string{
return $this->label;
}
public function setLabel(string $name) : bool{
$this->nextLabel = $name;
if(!$this->isRegistered()){
$this->label = $name;
return true;
}
return false;
}
/**
* Registers the command into a Command map
*/
public function register(CommandMap $commandMap) : bool{
if($this->allowChangesFrom($commandMap)){
$this->commandMap = $commandMap;
return true;
}
return false;
}
public function unregister(CommandMap $commandMap) : bool{
if($this->allowChangesFrom($commandMap)){
$this->commandMap = null;
$this->activeAliases = $this->aliases;
$this->label = $this->nextLabel;
return true;
}
return false;
}
private function allowChangesFrom(CommandMap $commandMap) : bool{
return $this->commandMap === null || $this->commandMap === $commandMap;
}
public function isRegistered() : bool{
return $this->commandMap !== null;
}
/**
* @return string[]
* @phpstan-return list<string>
*/
public function getAliases() : array{
return $this->activeAliases;
}
public function getPermissionMessage() : ?string{
public function getPermissionMessage() : Translatable|string|null{
return $this->permissionMessage;
}
@ -206,31 +120,19 @@ abstract class Command{
return $this->description;
}
public function getUsage() : Translatable|string{
public function getUsage() : Translatable|string|null{
return $this->usageMessage;
}
/**
* @param string[] $aliases
* @phpstan-param list<string> $aliases
*/
public function setAliases(array $aliases) : void{
$aliases = array_values($aliases); //because plugins can and will pass crap
$this->aliases = $aliases;
if(!$this->isRegistered()){
$this->activeAliases = $aliases;
}
}
public function setDescription(Translatable|string $description) : void{
$this->description = $description;
}
public function setPermissionMessage(string $permissionMessage) : void{
public function setPermissionMessage(Translatable|string $permissionMessage) : void{
$this->permissionMessage = $permissionMessage;
}
public function setUsage(Translatable|string $usage) : void{
public function setUsage(Translatable|string|null $usage) : void{
$this->usageMessage = $usage;
}
@ -251,8 +153,4 @@ abstract class Command{
}
}
}
public function __toString() : string{
return $this->name;
}
}

View File

@ -24,13 +24,12 @@ declare(strict_types=1);
namespace pocketmine\command;
interface CommandMap{
/**
* @param Command[] $commands
* @param string[] $otherAliases
*
* @phpstan-param list<string> $otherAliases
*/
public function registerAll(string $fallbackPrefix, array $commands) : void;
public function register(string $fallbackPrefix, Command $command, ?string $label = null) : bool;
public function register(string $fallbackPrefix, Command $command, string $preferredAlias, array $otherAliases = []) : CommandMapEntry;
public function dispatch(CommandSender $sender, string $cmdLine) : bool;

View File

@ -21,18 +21,28 @@
declare(strict_types=1);
namespace pocketmine\utils;
namespace pocketmine\command;
use PHPUnit\Framework\TestCase;
use pocketmine\lang\Translatable;
class EnumTraitTest extends TestCase{
final class CommandMapEntry{
/**
* @doesNotPerformAssertions
* @param string[] $aliases
* @phpstan-param non-empty-list<string> $aliases
*/
public function testEnumLazyInit() : void{
foreach([TestEnum::ONE(), TestEnum::TWO(), TestEnum::THREE()] as $member){
//NOOP
}
public function __construct(
public readonly Command $command,
public readonly array $aliases
){}
public function getPreferredAlias() : string{
return $this->aliases[0];
}
public function getUsage() : Translatable|string{
//TODO: usage messages ought to use user-specified alias, not command preferred
//command-preferred is confusing if the user used a different alias
return $this->command->getUsage() ?? "/" . $this->getPreferredAlias();
}
}

View File

@ -50,10 +50,9 @@ class FormattedCommandAlias extends Command{
* @param string[] $formatStrings
*/
public function __construct(
string $alias,
private array $formatStrings
){
parent::__construct($alias, KnownTranslationFactory::pocketmine_command_userDefined_description());
parent::__construct(KnownTranslationFactory::pocketmine_command_userDefined_description());
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
@ -95,12 +94,14 @@ class FormattedCommandAlias extends Command{
throw new AssumptionFailedError("This should have been checked before construction");
}
if(($target = $commandMap->getCommand($commandLabel)) !== null){
$timings = Timings::getCommandDispatchTimings($target->getLabel());
if(($target = $commandMap->getEntry($commandLabel)) !== null){
//TODO: using labels for command dispatch is problematic - what if the label changes?
//maybe this should use command class instead?
$timings = Timings::getCommandDispatchTimings($target->getPreferredAlias());
$timings->startTiming();
try{
$target->execute($sender, $commandLabel, $commandArgs);
$target->command->execute($sender, $commandLabel, $commandArgs);
}catch(InvalidCommandSyntaxException $e){
$sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage())));
}finally{

View File

@ -24,17 +24,23 @@ declare(strict_types=1);
namespace pocketmine\command;
use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\Translatable;
use pocketmine\plugin\Plugin;
use pocketmine\plugin\PluginOwned;
final class PluginCommand extends Command implements PluginOwned{
public function __construct(
string $name,
private string $name,
private Plugin $owner,
private CommandExecutor $executor
private CommandExecutor $executor,
Translatable|string $description = "",
Translatable|string|null $usageMessage = null
){
parent::__construct($name);
$this->usageMessage = "";
parent::__construct($description, $usageMessage);
}
public function getName() : string{
return $this->name;
}
public function execute(CommandSender $sender, string $commandLabel, array $args){
@ -43,13 +49,11 @@ final class PluginCommand extends Command implements PluginOwned{
return false;
}
$success = $this->executor->onCommand($sender, $this, $commandLabel, $args);
if(!$success && $this->usageMessage !== ""){
if(!$this->executor->onCommand($sender, $this, $commandLabel, $args)){
throw new InvalidCommandSyntaxException();
}
return $success;
return true;
}
public function getOwningPlugin() : Plugin{

View File

@ -61,7 +61,6 @@ use pocketmine\command\defaults\TimeCommand;
use pocketmine\command\defaults\TimingsCommand;
use pocketmine\command\defaults\TitleCommand;
use pocketmine\command\defaults\TransferServerCommand;
use pocketmine\command\defaults\VanillaCommand;
use pocketmine\command\defaults\VersionCommand;
use pocketmine\command\defaults\WhitelistCommand;
use pocketmine\command\defaults\XpCommand;
@ -70,12 +69,15 @@ use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\lang\KnownTranslationFactory;
use pocketmine\Server;
use pocketmine\timings\Timings;
use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
use function array_filter;
use function array_shift;
use function array_values;
use function count;
use function implode;
use function spl_object_id;
use function str_contains;
use function strcasecmp;
use function strtolower;
@ -87,122 +89,138 @@ class SimpleCommandMap implements CommandMap{
* @var Command[]
* @phpstan-var array<string, Command>
*/
protected array $knownCommands = [];
protected array $aliasToCommandMap = [];
/**
* @var CommandMapEntry[]
* @phpstan-var array<int, CommandMapEntry>
*/
private array $uniqueCommands = [];
public function __construct(private Server $server){
$this->setDefaultCommands();
}
private function setDefaultCommands() : void{
$this->registerAll("pocketmine", [
new BanCommand(),
new BanIpCommand(),
new BanListCommand(),
new ClearCommand(),
new DefaultGamemodeCommand(),
new DeopCommand(),
new DifficultyCommand(),
new DumpMemoryCommand(),
new EffectCommand(),
new EnchantCommand(),
new GamemodeCommand(),
new GarbageCollectorCommand(),
new GiveCommand(),
new HelpCommand(),
new KickCommand(),
new KillCommand(),
new ListCommand(),
new MeCommand(),
new OpCommand(),
new PardonCommand(),
new PardonIpCommand(),
new ParticleCommand(),
new PluginsCommand(),
new SaveCommand(),
new SaveOffCommand(),
new SaveOnCommand(),
new SayCommand(),
new SeedCommand(),
new SetWorldSpawnCommand(),
new SpawnpointCommand(),
new StatusCommand(),
new StopCommand(),
new TeleportCommand(),
new TellCommand(),
new TimeCommand(),
new TimingsCommand(),
new TitleCommand(),
new TransferServerCommand(),
new VersionCommand(),
new WhitelistCommand(),
new XpCommand(),
]);
$pmPrefix = "pocketmine";
$this->register($pmPrefix, new BanCommand(), "ban");
$this->register($pmPrefix, new BanIpCommand(), "ban-ip");
$this->register($pmPrefix, new BanListCommand(), "banlist");
$this->register($pmPrefix, new ClearCommand(), "clear");
$this->register($pmPrefix, new DefaultGamemodeCommand(), "defaultgamemode");
$this->register($pmPrefix, new DeopCommand(), "deop");
$this->register($pmPrefix, new DifficultyCommand(), "difficulty");
$this->register($pmPrefix, new DumpMemoryCommand(), "dumpmemory");
$this->register($pmPrefix, new EffectCommand(), "effect");
$this->register($pmPrefix, new EnchantCommand(), "enchant");
$this->register($pmPrefix, new GamemodeCommand(), "gamemode");
$this->register($pmPrefix, new GarbageCollectorCommand(), "gc");
$this->register($pmPrefix, new GiveCommand(), "give");
$this->register($pmPrefix, new HelpCommand(), "help", ["?"]);
$this->register($pmPrefix, new KickCommand(), "kick");
$this->register($pmPrefix, new KillCommand(), "kill", ["suicide"]);
$this->register($pmPrefix, new ListCommand(), "list");
$this->register($pmPrefix, new MeCommand(), "me");
$this->register($pmPrefix, new OpCommand(), "op");
$this->register($pmPrefix, new PardonCommand(), "pardon", ["unban"]);
$this->register($pmPrefix, new PardonIpCommand(), "pardon-ip", ["unban-ip"]);
$this->register($pmPrefix, new ParticleCommand(), "particle");
$this->register($pmPrefix, new PluginsCommand(), "plugins", ["pl"]);
$this->register($pmPrefix, new SaveCommand(), "save-all");
$this->register($pmPrefix, new SaveOffCommand(), "save-off");
$this->register($pmPrefix, new SaveOnCommand(), "save-on");
$this->register($pmPrefix, new SayCommand(), "say");
$this->register($pmPrefix, new SeedCommand(), "seed");
$this->register($pmPrefix, new SetWorldSpawnCommand(), "setworldspawn");
$this->register($pmPrefix, new SpawnpointCommand(), "spawnpoint");
$this->register($pmPrefix, new StatusCommand(), "status");
$this->register($pmPrefix, new StopCommand(), "stop");
$this->register($pmPrefix, new TeleportCommand(), "tp", ["teleport"]);
$this->register($pmPrefix, new TellCommand(), "tell", ["w", "msg"]);
$this->register($pmPrefix, new TimeCommand(), "time");
$this->register($pmPrefix, new TimingsCommand(), "timings");
$this->register($pmPrefix, new TitleCommand(), "title");
$this->register($pmPrefix, new TransferServerCommand(), "transferserver");
$this->register($pmPrefix, new VersionCommand(), "version", ["ver", "about"]);
$this->register($pmPrefix, new WhitelistCommand(), "whitelist");
$this->register($pmPrefix, new XpCommand(), "xp");
}
public function registerAll(string $fallbackPrefix, array $commands) : void{
foreach($commands as $command){
$this->register($fallbackPrefix, $command);
}
}
public function register(string $fallbackPrefix, Command $command, ?string $label = null) : bool{
public function register(string $fallbackPrefix, Command $command, string $preferredAlias, array $otherAliases = []) : CommandMapEntry{
if(count($command->getPermissions()) === 0){
throw new \InvalidArgumentException("Commands must have a permission set");
}
if($label === null){
$label = $command->getLabel();
if(isset($this->uniqueCommands[spl_object_id($command)])){
throw new \InvalidArgumentException("This Command object has already been registered");
}
$label = trim($label);
$preferredAlias = trim($preferredAlias);
$fallbackPrefix = strtolower(trim($fallbackPrefix));
$registered = $this->registerAlias($command, false, $fallbackPrefix, $label);
$registeredAliases = [];
//primary labels take precedence over any existing registrations
$this->mapAlias($preferredAlias, $command, $registeredAliases);
$this->mapAlias($fallbackPrefix . ":" . $preferredAlias, $command, $registeredAliases);
$aliases = $command->getAliases();
foreach($aliases as $index => $alias){
if(!$this->registerAlias($command, true, $fallbackPrefix, $alias)){
unset($aliases[$index]);
foreach($otherAliases as $alias){
$this->mapAlias($fallbackPrefix . ":" . $alias, $command, $registeredAliases);
if(!isset($this->aliasToCommandMap[$alias])){
$this->mapAlias($alias, $command, $registeredAliases);
}
}
$command->setAliases(array_values($aliases));
if(!$registered){
$command->setLabel($fallbackPrefix . ":" . $label);
$entry = new CommandMapEntry($command, $registeredAliases);
$this->uniqueCommands[spl_object_id($command)] = $entry;
return $entry;
}
/**
* @param string[] &$registeredAliases
* @phpstan-param list<string> &$registeredAliases
* @phpstan-param-out non-empty-list<string> $registeredAliases
*/
private function mapAlias(string $alias, Command $command, array &$registeredAliases) : void{
$this->unregisterAlias($alias);
$this->aliasToCommandMap[$alias] = $command;
$registeredAliases[] = $alias;
}
public function registerAlias(string $existingAlias, string $newAlias) : void{
$existingCommand = $this->aliasToCommandMap[$existingAlias] ?? null;
if($existingCommand === null){
throw new \InvalidArgumentException("No command is currently using the alias \"$existingAlias\", cannot create an alias to it");
}
$registration = $this->uniqueCommands[spl_object_id($existingCommand)];
$newAliases = $registration->aliases;
$this->mapAlias($newAlias, $existingCommand, $newAliases);
$this->uniqueCommands[spl_object_id($existingCommand)] = new CommandMapEntry($existingCommand, $newAliases);
}
$command->register($this);
return $registered;
public function unregisterAlias(string $alias) : void{
$oldCommand = $this->aliasToCommandMap[$alias] ?? null;
if($oldCommand !== null){
unset($this->aliasToCommandMap[$alias]);
$oldCommandKey = spl_object_id($oldCommand);
$oldCommandEntry = $this->uniqueCommands[$oldCommandKey];
$filteredAliases = array_values(array_filter($oldCommandEntry->aliases, fn(string $oldAlias) => $oldAlias !== $alias));
if(count($filteredAliases) > 0){
$this->uniqueCommands[$oldCommandKey] = new CommandMapEntry($oldCommand, $filteredAliases);
}else{
unset($this->uniqueCommands[$oldCommandKey]);
}
}
}
public function unregister(Command $command) : bool{
foreach(Utils::promoteKeys($this->knownCommands) as $lbl => $cmd){
if($cmd === $command){
unset($this->knownCommands[$lbl]);
$entry = $this->uniqueCommands[spl_object_id($command)] ?? null;
if($entry !== null){
unset($this->uniqueCommands[spl_object_id($command)]);
foreach($entry->aliases as $alias){
unset($this->aliasToCommandMap[$alias]);
}
}
$command->unregister($this);
return true;
}
private function registerAlias(Command $command, bool $isAlias, string $fallbackPrefix, string $label) : bool{
$this->knownCommands[$fallbackPrefix . ":" . $label] = $command;
if(($command instanceof VanillaCommand || $isAlias) && isset($this->knownCommands[$label])){
return false;
}
if(isset($this->knownCommands[$label]) && $this->knownCommands[$label]->getLabel() === $label){
return false;
}
if(!$isAlias){
$command->setLabel($label);
}
$this->knownCommands[$label] = $command;
return true;
}
@ -210,13 +228,15 @@ class SimpleCommandMap implements CommandMap{
$args = CommandStringHelper::parseQuoteAware($commandLine);
$sentCommandLabel = array_shift($args);
if($sentCommandLabel !== null && ($target = $this->getCommand($sentCommandLabel)) !== null){
$timings = Timings::getCommandDispatchTimings($target->getLabel());
if($sentCommandLabel !== null && ($target = $this->getEntry($sentCommandLabel)) !== null){
//TODO: using labels for command dispatch is problematic - what if the label changes?
//maybe this should use command class instead?
$timings = Timings::getCommandDispatchTimings($target->getPreferredAlias());
$timings->startTiming();
try{
if($target->testPermission($sender)){
$target->execute($sender, $sentCommandLabel, $args);
if($target->command->testPermission($sentCommandLabel, $sender)){
$target->command->execute($sender, $sentCommandLabel, $args);
}
}catch(InvalidCommandSyntaxException $e){
$sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage())));
@ -231,23 +251,36 @@ class SimpleCommandMap implements CommandMap{
}
public function clearCommands() : void{
foreach($this->knownCommands as $command){
$command->unregister($this);
}
$this->knownCommands = [];
$this->aliasToCommandMap = [];
$this->uniqueCommands = [];
$this->setDefaultCommands();
}
public function getCommand(string $name) : ?Command{
return $this->knownCommands[$name] ?? null;
return $this->aliasToCommandMap[$name] ?? null;
}
/**
* @return Command[]
* @phpstan-return array<string, Command>
*/
public function getCommands() : array{
return $this->knownCommands;
public function getAliasToCommandMap() : array{
return $this->aliasToCommandMap;
}
/**
* @return CommandMapEntry[]
* @phpstan-return array<int, CommandMapEntry>
*/
public function getUniqueCommands() : array{
return $this->uniqueCommands;
}
public function getEntry(string $name) : ?CommandMapEntry{
$command = $this->getCommand($name);
return $command !== null ?
$this->uniqueCommands[spl_object_id($command)] ?? throw new AssumptionFailedError("This should never be unset") :
null;
}
public function registerServerAliases() : void{
@ -289,12 +322,13 @@ class SimpleCommandMap implements CommandMap{
//These registered commands have absolute priority
$lowerAlias = strtolower($alias);
$this->unregisterAlias($lowerAlias);
if(count($targets) > 0){
$this->knownCommands[$lowerAlias] = new FormattedCommandAlias($lowerAlias, $targets);
}else{
unset($this->knownCommands[$lowerAlias]);
$aliasInstance = new FormattedCommandAlias($targets);
$registeredAliases = [];
$this->mapAlias($lowerAlias, $aliasInstance, $registeredAliases);
$this->uniqueCommands[spl_object_id($aliasInstance)] = new CommandMapEntry($aliasInstance, $registeredAliases);
}
}
}
}

View File

@ -37,7 +37,6 @@ class BanCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"ban",
KnownTranslationFactory::pocketmine_command_ban_player_description(),
KnownTranslationFactory::commands_ban_usage()
);

View File

@ -38,7 +38,6 @@ class BanIpCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"ban-ip",
KnownTranslationFactory::pocketmine_command_ban_ip_description(),
KnownTranslationFactory::commands_banip_usage()
);

View File

@ -39,7 +39,6 @@ class BanListCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"banlist",
KnownTranslationFactory::pocketmine_command_banlist_description(),
KnownTranslationFactory::commands_banlist_usage()
);

View File

@ -41,7 +41,6 @@ class ClearCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"clear",
KnownTranslationFactory::pocketmine_command_clear_description(),
KnownTranslationFactory::pocketmine_command_clear_usage()
);
@ -53,7 +52,7 @@ class ClearCommand extends VanillaCommand{
throw new InvalidCommandSyntaxException();
}
$target = $this->fetchPermittedPlayerTarget($sender, $args[0] ?? null, DefaultPermissionNames::COMMAND_CLEAR_SELF, DefaultPermissionNames::COMMAND_CLEAR_OTHER);
$target = $this->fetchPermittedPlayerTarget($commandLabel, $sender, $args[0] ?? null, DefaultPermissionNames::COMMAND_CLEAR_SELF, DefaultPermissionNames::COMMAND_CLEAR_OTHER);
if($target === null){
return true;
}

View File

@ -35,7 +35,6 @@ class DefaultGamemodeCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"defaultgamemode",
KnownTranslationFactory::pocketmine_command_defaultgamemode_description(),
KnownTranslationFactory::commands_defaultgamemode_usage()
);

View File

@ -37,7 +37,6 @@ class DeopCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"deop",
KnownTranslationFactory::pocketmine_command_deop_description(),
KnownTranslationFactory::commands_deop_usage()
);

View File

@ -36,7 +36,6 @@ class DifficultyCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"difficulty",
KnownTranslationFactory::pocketmine_command_difficulty_description(),
KnownTranslationFactory::commands_difficulty_usage()
);

View File

@ -33,7 +33,6 @@ class DumpMemoryCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"dumpmemory",
KnownTranslationFactory::pocketmine_command_dumpmemory_description(),
"/dumpmemory [path]"
);

View File

@ -38,7 +38,6 @@ class EffectCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"effect",
KnownTranslationFactory::pocketmine_command_effect_description(),
KnownTranslationFactory::commands_effect_usage()
);
@ -53,7 +52,7 @@ class EffectCommand extends VanillaCommand{
throw new InvalidCommandSyntaxException();
}
$player = $this->fetchPermittedPlayerTarget($sender, $args[0], DefaultPermissionNames::COMMAND_EFFECT_SELF, DefaultPermissionNames::COMMAND_EFFECT_OTHER);
$player = $this->fetchPermittedPlayerTarget($commandLabel, $sender, $args[0], DefaultPermissionNames::COMMAND_EFFECT_SELF, DefaultPermissionNames::COMMAND_EFFECT_OTHER);
if($player === null){
return true;
}

View File

@ -36,7 +36,6 @@ class EnchantCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"enchant",
KnownTranslationFactory::pocketmine_command_enchant_description(),
KnownTranslationFactory::commands_enchant_usage()
);
@ -51,7 +50,7 @@ class EnchantCommand extends VanillaCommand{
throw new InvalidCommandSyntaxException();
}
$player = $this->fetchPermittedPlayerTarget($sender, $args[0], DefaultPermissionNames::COMMAND_ENCHANT_SELF, DefaultPermissionNames::COMMAND_ENCHANT_OTHER);
$player = $this->fetchPermittedPlayerTarget($commandLabel, $sender, $args[0], DefaultPermissionNames::COMMAND_ENCHANT_SELF, DefaultPermissionNames::COMMAND_ENCHANT_OTHER);
if($player === null){
return true;
}

View File

@ -35,7 +35,6 @@ class GamemodeCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"gamemode",
KnownTranslationFactory::pocketmine_command_gamemode_description(),
KnownTranslationFactory::commands_gamemode_usage()
);
@ -56,7 +55,7 @@ class GamemodeCommand extends VanillaCommand{
return true;
}
$target = $this->fetchPermittedPlayerTarget($sender, $args[1] ?? null, DefaultPermissionNames::COMMAND_GAMEMODE_SELF, DefaultPermissionNames::COMMAND_GAMEMODE_OTHER);
$target = $this->fetchPermittedPlayerTarget($commandLabel, $sender, $args[1] ?? null, DefaultPermissionNames::COMMAND_GAMEMODE_SELF, DefaultPermissionNames::COMMAND_GAMEMODE_OTHER);
if($target === null){
return true;
}

View File

@ -36,7 +36,6 @@ class GarbageCollectorCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"gc",
KnownTranslationFactory::pocketmine_command_gc_description()
);
$this->setPermission(DefaultPermissionNames::COMMAND_GC);

View File

@ -43,7 +43,6 @@ class GiveCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"give",
KnownTranslationFactory::pocketmine_command_give_description(),
KnownTranslationFactory::pocketmine_command_give_usage()
);
@ -58,7 +57,7 @@ class GiveCommand extends VanillaCommand{
throw new InvalidCommandSyntaxException();
}
$player = $this->fetchPermittedPlayerTarget($sender, $args[0], DefaultPermissionNames::COMMAND_GIVE_SELF, DefaultPermissionNames::COMMAND_GIVE_OTHER);
$player = $this->fetchPermittedPlayerTarget($commandLabel, $sender, $args[0], DefaultPermissionNames::COMMAND_GIVE_SELF, DefaultPermissionNames::COMMAND_GIVE_OTHER);
if($player === null){
return true;
}

View File

@ -47,10 +47,8 @@ class HelpCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"help",
KnownTranslationFactory::pocketmine_command_help_description(),
KnownTranslationFactory::commands_help_usage(),
["?"]
KnownTranslationFactory::commands_help_usage()
);
$this->setPermission(DefaultPermissionNames::COMMAND_HELP);
}
@ -72,11 +70,13 @@ class HelpCommand extends VanillaCommand{
$pageHeight = $sender->getScreenLineHeight();
//TODO: maybe inject this in the constructor instead of assuming the server's command map?
$commandMap = $sender->getServer()->getCommandMap();
if($commandName === ""){
$commands = [];
foreach($sender->getServer()->getCommandMap()->getCommands() as $command){
if($command->testPermissionSilent($sender)){
$commands[$command->getLabel()] = $command;
foreach($commandMap->getUniqueCommands() as $commandEntry){
if($commandEntry->command->testPermissionSilent($sender)){
$commands[$commandEntry->getPreferredAlias()] = $commandEntry;
}
}
ksort($commands, SORT_NATURAL | SORT_FLAG_CASE);
@ -88,31 +88,31 @@ class HelpCommand extends VanillaCommand{
$sender->sendMessage(KnownTranslationFactory::commands_help_header((string) $pageNumber, (string) count($commands)));
$lang = $sender->getLanguage();
if(isset($commands[$pageNumber - 1])){
foreach($commands[$pageNumber - 1] as $command){
$description = $command->getDescription();
foreach($commands[$pageNumber - 1] as $commandEntry){
$description = $commandEntry->command->getDescription();
$descriptionString = $description instanceof Translatable ? $lang->translate($description) : $description;
$sender->sendMessage(TextFormat::DARK_GREEN . "/" . $command->getLabel() . ": " . TextFormat::RESET . $descriptionString);
$sender->sendMessage(TextFormat::DARK_GREEN . "/" . $commandEntry->getPreferredAlias() . ": " . TextFormat::RESET . $descriptionString);
}
}
return true;
}else{
if(($cmd = $sender->getServer()->getCommandMap()->getCommand(strtolower($commandName))) instanceof Command){
if($cmd->testPermissionSilent($sender)){
if(($commandEntry = $commandMap->getEntry(strtolower($commandName))) !== null){
if($commandEntry->command->testPermissionSilent($sender)){
$lang = $sender->getLanguage();
$description = $cmd->getDescription();
$description = $commandEntry->command->getDescription();
$descriptionString = $description instanceof Translatable ? $lang->translate($description) : $description;
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_header($cmd->getLabel())
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_header($commandEntry->getPreferredAlias())
->format(TextFormat::YELLOW . "--------- " . TextFormat::RESET, TextFormat::YELLOW . " ---------"));
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_description(TextFormat::RESET . $descriptionString)
->prefix(TextFormat::GOLD));
$usage = $cmd->getUsage();
$usage = $commandEntry->getUsage();
$usageString = $usage instanceof Translatable ? $lang->translate($usage) : $usage;
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_usage(TextFormat::RESET . implode("\n" . TextFormat::RESET, explode("\n", $usageString, limit: PHP_INT_MAX)))
->prefix(TextFormat::GOLD));
$aliases = $cmd->getAliases();
$aliases = $commandEntry->aliases;
sort($aliases, SORT_NATURAL);
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_aliases(TextFormat::RESET . implode(", ", $aliases))
->prefix(TextFormat::GOLD));

View File

@ -39,7 +39,6 @@ class KickCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"kick",
KnownTranslationFactory::pocketmine_command_kick_description(),
KnownTranslationFactory::commands_kick_usage()
);

View File

@ -35,10 +35,8 @@ class KillCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"kill",
KnownTranslationFactory::pocketmine_command_kill_description(),
KnownTranslationFactory::pocketmine_command_kill_usage(),
["suicide"]
KnownTranslationFactory::pocketmine_command_kill_usage()
);
$this->setPermissions([DefaultPermissionNames::COMMAND_KILL_SELF, DefaultPermissionNames::COMMAND_KILL_OTHER]);
}
@ -48,7 +46,7 @@ class KillCommand extends VanillaCommand{
throw new InvalidCommandSyntaxException();
}
$player = $this->fetchPermittedPlayerTarget($sender, $args[0] ?? null, DefaultPermissionNames::COMMAND_KILL_SELF, DefaultPermissionNames::COMMAND_KILL_OTHER);
$player = $this->fetchPermittedPlayerTarget($commandLabel, $sender, $args[0] ?? null, DefaultPermissionNames::COMMAND_KILL_SELF, DefaultPermissionNames::COMMAND_KILL_OTHER);
if($player === null){
return true;
}

View File

@ -38,7 +38,6 @@ class ListCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"list",
KnownTranslationFactory::pocketmine_command_list_description()
);
$this->setPermission(DefaultPermissionNames::COMMAND_LIST);

View File

@ -36,7 +36,6 @@ class MeCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"me",
KnownTranslationFactory::pocketmine_command_me_description(),
KnownTranslationFactory::commands_me_usage()
);

View File

@ -37,7 +37,6 @@ class OpCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"op",
KnownTranslationFactory::pocketmine_command_op_description(),
KnownTranslationFactory::commands_op_usage()
);

View File

@ -34,10 +34,8 @@ class PardonCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"pardon",
KnownTranslationFactory::pocketmine_command_unban_player_description(),
KnownTranslationFactory::commands_unban_usage(),
["unban"]
KnownTranslationFactory::commands_unban_usage()
);
$this->setPermission(DefaultPermissionNames::COMMAND_UNBAN_PLAYER);
}

View File

@ -35,10 +35,8 @@ class PardonIpCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"pardon-ip",
KnownTranslationFactory::pocketmine_command_unban_ip_description(),
KnownTranslationFactory::commands_unbanip_usage(),
["unban-ip"]
KnownTranslationFactory::commands_unbanip_usage()
);
$this->setPermission(DefaultPermissionNames::COMMAND_UNBAN_IP);
}

View File

@ -76,7 +76,6 @@ class ParticleCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"particle",
KnownTranslationFactory::pocketmine_command_particle_description(),
KnownTranslationFactory::pocketmine_command_particle_usage()
);

View File

@ -38,10 +38,8 @@ class PluginsCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"plugins",
KnownTranslationFactory::pocketmine_command_plugins_description(),
null,
["pl"]
null
);
$this->setPermission(DefaultPermissionNames::COMMAND_PLUGINS);
}

View File

@ -34,7 +34,6 @@ class SaveCommand extends VanillaCommand{
public function __construct(){
parent::__construct(
"save-all",
KnownTranslationFactory::pocketmine_command_save_description()
);
$this->setPermission(DefaultPermissionNames::COMMAND_SAVE_PERFORM);

Some files were not shown because too many files have changed in this diff Show More