mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-07 12:18:46 +00:00
Merge branch 'next-minor' into next-major
This commit is contained in:
commit
4d79aced07
2
.github/workflows/draft-release.yml
vendored
2
.github/workflows/draft-release.yml
vendored
@ -69,7 +69,7 @@ jobs:
|
|||||||
${{ github.workspace }}/build_info.json
|
${{ github.workspace }}/build_info.json
|
||||||
|
|
||||||
- name: Create draft release
|
- name: Create draft release
|
||||||
uses: ncipollo/release-action@v1.11.2
|
uses: ncipollo/release-action@v1.12.0
|
||||||
with:
|
with:
|
||||||
artifacts: ${{ github.workspace }}/PocketMine-MP.phar,${{ github.workspace }}/start.*,${{ github.workspace }}/build_info.json
|
artifacts: ${{ github.workspace }}/PocketMine-MP.phar,${{ github.workspace }}/start.*,${{ github.workspace }}/build_info.json
|
||||||
commit: ${{ github.sha }}
|
commit: ${{ github.sha }}
|
||||||
|
2
.github/workflows/support.yml
vendored
2
.github/workflows/support.yml
vendored
@ -8,7 +8,7 @@ jobs:
|
|||||||
support:
|
support:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: dessant/support-requests@v2
|
- uses: dessant/support-requests@v3
|
||||||
with:
|
with:
|
||||||
github-token: ${{ github.token }}
|
github-token: ${{ github.token }}
|
||||||
support-label: "Support request"
|
support-label: "Support request"
|
||||||
|
5
.idea/codeStyles/Project.xml
generated
5
.idea/codeStyles/Project.xml
generated
@ -62,6 +62,11 @@
|
|||||||
<option name="USE_TAB_CHARACTER" value="true" />
|
<option name="USE_TAB_CHARACTER" value="true" />
|
||||||
</indentOptions>
|
</indentOptions>
|
||||||
</codeStyleSettings>
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="Shell Script">
|
||||||
|
<indentOptions>
|
||||||
|
<option name="USE_TAB_CHARACTER" value="true" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
<codeStyleSettings language="neon">
|
<codeStyleSettings language="neon">
|
||||||
<indentOptions>
|
<indentOptions>
|
||||||
<option name="USE_TAB_CHARACTER" value="true" />
|
<option name="USE_TAB_CHARACTER" value="true" />
|
||||||
|
@ -66,6 +66,9 @@ BODY,
|
|||||||
],
|
],
|
||||||
'indentation_type' => true,
|
'indentation_type' => true,
|
||||||
'logical_operators' => true,
|
'logical_operators' => true,
|
||||||
|
'native_constant_invocation' => [
|
||||||
|
'scope' => 'namespaced'
|
||||||
|
],
|
||||||
'native_function_invocation' => [
|
'native_function_invocation' => [
|
||||||
'scope' => 'namespaced',
|
'scope' => 'namespaced',
|
||||||
'include' => ['@all'],
|
'include' => ['@all'],
|
||||||
@ -92,6 +95,12 @@ BODY,
|
|||||||
],
|
],
|
||||||
'sort_algorithm' => 'alpha'
|
'sort_algorithm' => 'alpha'
|
||||||
],
|
],
|
||||||
|
'phpdoc_align' => [
|
||||||
|
'align' => 'vertical',
|
||||||
|
'tags' => [
|
||||||
|
'param',
|
||||||
|
]
|
||||||
|
],
|
||||||
'phpdoc_line_span' => [
|
'phpdoc_line_span' => [
|
||||||
'property' => 'single',
|
'property' => 'single',
|
||||||
'method' => null,
|
'method' => null,
|
||||||
|
@ -48,6 +48,8 @@ use function sort;
|
|||||||
use function strrpos;
|
use function strrpos;
|
||||||
use function strtoupper;
|
use function strtoupper;
|
||||||
use function substr;
|
use function substr;
|
||||||
|
use const SORT_STRING;
|
||||||
|
use const STDERR;
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ use function file_get_contents;
|
|||||||
use function fopen;
|
use function fopen;
|
||||||
use function fwrite;
|
use function fwrite;
|
||||||
use function strtoupper;
|
use function strtoupper;
|
||||||
|
use const SORT_STRING;
|
||||||
|
use const STDERR;
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ use function sprintf;
|
|||||||
use function str_replace;
|
use function str_replace;
|
||||||
use function substr;
|
use function substr;
|
||||||
use const SORT_STRING;
|
use const SORT_STRING;
|
||||||
|
use const STDERR;
|
||||||
|
|
||||||
if(count($argv) !== 2){
|
if(count($argv) !== 2){
|
||||||
fwrite(STDERR, "Provide a path to process\n");
|
fwrite(STDERR, "Provide a path to process\n");
|
||||||
|
@ -48,6 +48,7 @@ use function lcfirst;
|
|||||||
use function log;
|
use function log;
|
||||||
use function ob_get_clean;
|
use function ob_get_clean;
|
||||||
use function ob_start;
|
use function ob_start;
|
||||||
|
use const SORT_STRING;
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ use function rtrim;
|
|||||||
use function sprintf;
|
use function sprintf;
|
||||||
use function str_replace;
|
use function str_replace;
|
||||||
use function unlink;
|
use function unlink;
|
||||||
|
use const DIRECTORY_SEPARATOR;
|
||||||
use const PHP_EOL;
|
use const PHP_EOL;
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
38
composer.lock
generated
38
composer.lock
generated
@ -198,16 +198,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "netresearch/jsonmapper",
|
"name": "netresearch/jsonmapper",
|
||||||
"version": "v4.0.0",
|
"version": "v4.1.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/cweiske/jsonmapper.git",
|
"url": "https://github.com/cweiske/jsonmapper.git",
|
||||||
"reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d"
|
"reference": "cfa81ea1d35294d64adb9c68aa4cb9e92400e53f"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d",
|
"url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/cfa81ea1d35294d64adb9c68aa4cb9e92400e53f",
|
||||||
"reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d",
|
"reference": "cfa81ea1d35294d64adb9c68aa4cb9e92400e53f",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -243,9 +243,9 @@
|
|||||||
"support": {
|
"support": {
|
||||||
"email": "cweiske@cweiske.de",
|
"email": "cweiske@cweiske.de",
|
||||||
"issues": "https://github.com/cweiske/jsonmapper/issues",
|
"issues": "https://github.com/cweiske/jsonmapper/issues",
|
||||||
"source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0"
|
"source": "https://github.com/cweiske/jsonmapper/tree/v4.1.0"
|
||||||
},
|
},
|
||||||
"time": "2020-12-01T19:48:11+00:00"
|
"time": "2022-12-08T20:46:14+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pocketmine/bedrock-block-upgrade-schema",
|
"name": "pocketmine/bedrock-block-upgrade-schema",
|
||||||
@ -1824,21 +1824,21 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpstan-phpunit",
|
"name": "phpstan/phpstan-phpunit",
|
||||||
"version": "1.2.2",
|
"version": "1.3.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpstan/phpstan-phpunit.git",
|
"url": "https://github.com/phpstan/phpstan-phpunit.git",
|
||||||
"reference": "dea1f87344c6964c607d9076dee42d891f3923f0"
|
"reference": "4c06b7e3f2c40081334d86975350dda814bd064a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/dea1f87344c6964c607d9076dee42d891f3923f0",
|
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/4c06b7e3f2c40081334d86975350dda814bd064a",
|
||||||
"reference": "dea1f87344c6964c607d9076dee42d891f3923f0",
|
"reference": "4c06b7e3f2c40081334d86975350dda814bd064a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2 || ^8.0",
|
"php": "^7.2 || ^8.0",
|
||||||
"phpstan/phpstan": "^1.8.11"
|
"phpstan/phpstan": "^1.9.0"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"phpunit/phpunit": "<7.0"
|
"phpunit/phpunit": "<7.0"
|
||||||
@ -1870,9 +1870,9 @@
|
|||||||
"description": "PHPUnit extensions and rules for PHPStan",
|
"description": "PHPUnit extensions and rules for PHPStan",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/phpstan/phpstan-phpunit/issues",
|
"issues": "https://github.com/phpstan/phpstan-phpunit/issues",
|
||||||
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.2.2"
|
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.0"
|
||||||
},
|
},
|
||||||
"time": "2022-10-28T10:23:07+00:00"
|
"time": "2022-12-07T15:46:24+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpstan-strict-rules",
|
"name": "phpstan/phpstan-strict-rules",
|
||||||
@ -2242,16 +2242,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit",
|
"name": "phpunit/phpunit",
|
||||||
"version": "9.5.26",
|
"version": "9.5.27",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||||
"reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2"
|
"reference": "a2bc7ffdca99f92d959b3f2270529334030bba38"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/851867efcbb6a1b992ec515c71cdcf20d895e9d2",
|
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2bc7ffdca99f92d959b3f2270529334030bba38",
|
||||||
"reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2",
|
"reference": "a2bc7ffdca99f92d959b3f2270529334030bba38",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2324,7 +2324,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.26"
|
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.27"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -2340,7 +2340,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-10-28T06:00:21+00:00"
|
"time": "2022-12-09T07:31:23+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/cli-parser",
|
"name": "sebastian/cli-parser",
|
||||||
|
@ -39,11 +39,14 @@ namespace pocketmine {
|
|||||||
use function extension_loaded;
|
use function extension_loaded;
|
||||||
use function function_exists;
|
use function function_exists;
|
||||||
use function getcwd;
|
use function getcwd;
|
||||||
|
use function is_dir;
|
||||||
|
use function mkdir;
|
||||||
use function phpversion;
|
use function phpversion;
|
||||||
use function preg_match;
|
use function preg_match;
|
||||||
use function preg_quote;
|
use function preg_quote;
|
||||||
use function realpath;
|
use function realpath;
|
||||||
use function version_compare;
|
use function version_compare;
|
||||||
|
use const DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
require_once __DIR__ . '/VersionInfo.php';
|
require_once __DIR__ . '/VersionInfo.php';
|
||||||
|
|
||||||
@ -273,25 +276,33 @@ JIT_WARNING
|
|||||||
$pluginPath = getopt_string("plugins") ?? $cwd . DIRECTORY_SEPARATOR . "plugins";
|
$pluginPath = getopt_string("plugins") ?? $cwd . DIRECTORY_SEPARATOR . "plugins";
|
||||||
Filesystem::addCleanedPath($pluginPath, Filesystem::CLEAN_PATH_PLUGINS_PREFIX);
|
Filesystem::addCleanedPath($pluginPath, Filesystem::CLEAN_PATH_PLUGINS_PREFIX);
|
||||||
|
|
||||||
if(!@mkdir($dataPath, 0777, true) && (!is_dir($dataPath) || !is_writable($dataPath))){
|
if(!@mkdir($dataPath, 0777, true) && !is_dir($dataPath)){
|
||||||
critical_error("Unable to create/access data directory at $dataPath. Check that the target location is accessible by the current user.");
|
critical_error("Unable to create/access data directory at $dataPath. Check that the target location is accessible by the current user.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
//this has to be done after we're sure the data path exists
|
//this has to be done after we're sure the data path exists
|
||||||
$dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR;
|
$dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR;
|
||||||
if(!@mkdir($pluginPath, 0777, true) && (!is_dir($pluginPath) || !is_writable($pluginPath))){
|
|
||||||
critical_error("Unable to create plugin directory at $pluginPath. Check that the target location is accessible by the current user.");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
$pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR;
|
|
||||||
|
|
||||||
$lockFilePath = Path::join($dataPath, 'server.lock');
|
$lockFilePath = Path::join($dataPath, 'server.lock');
|
||||||
if(($pid = Filesystem::createLockFile($lockFilePath)) !== null){
|
try{
|
||||||
|
$pid = Filesystem::createLockFile($lockFilePath);
|
||||||
|
}catch(\InvalidArgumentException $e){
|
||||||
|
critical_error($e->getMessage());
|
||||||
|
critical_error("Please ensure that there is enough space on the disk and that the current user has read/write permissions to the selected data directory $dataPath.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if($pid !== null){
|
||||||
critical_error("Another " . VersionInfo::NAME . " instance (PID $pid) is already using this folder (" . realpath($dataPath) . ").");
|
critical_error("Another " . VersionInfo::NAME . " instance (PID $pid) is already using this folder (" . realpath($dataPath) . ").");
|
||||||
critical_error("Please stop the other server first before running a new one.");
|
critical_error("Please stop the other server first before running a new one.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!@mkdir($pluginPath, 0777, true) && !is_dir($pluginPath)){
|
||||||
|
critical_error("Unable to create plugin directory at $pluginPath. Check that the target location is accessible by the current user.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
$pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
//Logger has a dependency on timezone
|
//Logger has a dependency on timezone
|
||||||
Timezone::init();
|
Timezone::init();
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ class ShapelessRecipe implements CraftingRecipe{
|
|||||||
/**
|
/**
|
||||||
* @param RecipeIngredient[] $ingredients No more than 9 total. This applies to sum of item stack counts, not count of array.
|
* @param RecipeIngredient[] $ingredients No more than 9 total. This applies to sum of item stack counts, not count of array.
|
||||||
* @param Item[] $results List of result items created by this recipe.
|
* @param Item[] $results List of result items created by this recipe.
|
||||||
|
*
|
||||||
* TODO: we'll want to make the type parameter mandatory in PM5
|
* TODO: we'll want to make the type parameter mandatory in PM5
|
||||||
*/
|
*/
|
||||||
public function __construct(array $ingredients, array $results, ?ShapelessRecipeType $type = null){
|
public function __construct(array $ingredients, array $results, ?ShapelessRecipeType $type = null){
|
||||||
|
@ -34,6 +34,7 @@ use function gettype;
|
|||||||
use function is_array;
|
use function is_array;
|
||||||
use function is_string;
|
use function is_string;
|
||||||
use function json_decode;
|
use function json_decode;
|
||||||
|
use const JSON_THROW_ON_ERROR;
|
||||||
use const pocketmine\BEDROCK_DATA_PATH;
|
use const pocketmine\BEDROCK_DATA_PATH;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,6 +31,7 @@ use function array_flip;
|
|||||||
use function file_get_contents;
|
use function file_get_contents;
|
||||||
use function is_array;
|
use function is_array;
|
||||||
use function json_decode;
|
use function json_decode;
|
||||||
|
use const JSON_THROW_ON_ERROR;
|
||||||
use const pocketmine\BEDROCK_DATA_PATH;
|
use const pocketmine\BEDROCK_DATA_PATH;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,6 +37,7 @@ use pocketmine\nbt\tag\StringTag;
|
|||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use function assert;
|
use function assert;
|
||||||
use function ksort;
|
use function ksort;
|
||||||
|
use const SORT_NUMERIC;
|
||||||
|
|
||||||
final class ItemDataUpgrader{
|
final class ItemDataUpgrader{
|
||||||
private const TAG_LEGACY_ID = "id"; //TAG_Short (or TAG_String for Java itemstacks)
|
private const TAG_LEGACY_ID = "id"; //TAG_Short (or TAG_String for Java itemstacks)
|
||||||
|
@ -31,6 +31,8 @@ use function gettype;
|
|||||||
use function is_object;
|
use function is_object;
|
||||||
use function json_decode;
|
use function json_decode;
|
||||||
use function ksort;
|
use function ksort;
|
||||||
|
use const JSON_THROW_ON_ERROR;
|
||||||
|
use const SORT_NUMERIC;
|
||||||
|
|
||||||
final class ItemIdMetaUpgradeSchemaUtils{
|
final class ItemIdMetaUpgradeSchemaUtils{
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ use function is_array;
|
|||||||
use function is_string;
|
use function is_string;
|
||||||
use function json_decode;
|
use function json_decode;
|
||||||
use function mb_strtolower;
|
use function mb_strtolower;
|
||||||
|
use const JSON_THROW_ON_ERROR;
|
||||||
use const pocketmine\BEDROCK_ITEM_UPGRADE_SCHEMA_PATH;
|
use const pocketmine\BEDROCK_ITEM_UPGRADE_SCHEMA_PATH;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -439,7 +439,9 @@ abstract class Living extends Entity{
|
|||||||
*/
|
*/
|
||||||
protected function applyPostDamageEffects(EntityDamageEvent $source) : void{
|
protected function applyPostDamageEffects(EntityDamageEvent $source) : void{
|
||||||
$this->setAbsorption(max(0, $this->getAbsorption() + $source->getModifier(EntityDamageEvent::MODIFIER_ABSORPTION)));
|
$this->setAbsorption(max(0, $this->getAbsorption() + $source->getModifier(EntityDamageEvent::MODIFIER_ABSORPTION)));
|
||||||
|
if($source->canBeReducedByArmor()){
|
||||||
$this->damageArmor($source->getBaseDamage());
|
$this->damageArmor($source->getBaseDamage());
|
||||||
|
}
|
||||||
|
|
||||||
if($source instanceof EntityDamageByEntityEvent && ($attacker = $source->getDamager()) !== null){
|
if($source instanceof EntityDamageByEntityEvent && ($attacker = $source->getDamager()) !== null){
|
||||||
$damage = 0;
|
$damage = 0;
|
||||||
|
73
src/event/world/WorldParticleEvent.php
Normal file
73
src/event/world/WorldParticleEvent.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?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\event\world;
|
||||||
|
|
||||||
|
use pocketmine\event\Cancellable;
|
||||||
|
use pocketmine\event\CancellableTrait;
|
||||||
|
use pocketmine\math\Vector3;
|
||||||
|
use pocketmine\player\Player;
|
||||||
|
use pocketmine\world\particle\Particle;
|
||||||
|
use pocketmine\world\World;
|
||||||
|
|
||||||
|
class WorldParticleEvent extends WorldEvent implements Cancellable{
|
||||||
|
use CancellableTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Player[] $recipients
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
World $world,
|
||||||
|
private Particle $particle,
|
||||||
|
private Vector3 $position,
|
||||||
|
private array $recipients
|
||||||
|
){
|
||||||
|
parent::__construct($world);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParticle() : Particle{
|
||||||
|
return $this->particle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setParticle(Particle $particle) : void{
|
||||||
|
$this->particle = $particle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPosition() : Vector3{
|
||||||
|
return $this->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Player[]
|
||||||
|
*/
|
||||||
|
public function getRecipients() : array{
|
||||||
|
return $this->recipients;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Player[] $recipients
|
||||||
|
*/
|
||||||
|
public function setRecipients(array $recipients) : void{
|
||||||
|
$this->recipients = $recipients;
|
||||||
|
}
|
||||||
|
}
|
77
src/event/world/WorldSoundEvent.php
Normal file
77
src/event/world/WorldSoundEvent.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?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\event\world;
|
||||||
|
|
||||||
|
use pocketmine\event\Cancellable;
|
||||||
|
use pocketmine\event\CancellableTrait;
|
||||||
|
use pocketmine\math\Vector3;
|
||||||
|
use pocketmine\player\Player;
|
||||||
|
use pocketmine\world\sound\Sound;
|
||||||
|
use pocketmine\world\World;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a sound is played in a world
|
||||||
|
* @see World::addSound()
|
||||||
|
*/
|
||||||
|
class WorldSoundEvent extends WorldEvent implements Cancellable{
|
||||||
|
use CancellableTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Player[] $recipients
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
World $world,
|
||||||
|
private Sound $sound,
|
||||||
|
private Vector3 $position,
|
||||||
|
private array $recipients
|
||||||
|
){
|
||||||
|
parent::__construct($world);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSound() : Sound{
|
||||||
|
return $this->sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSound(Sound $sound) : void{
|
||||||
|
$this->sound = $sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPosition() : Vector3{
|
||||||
|
return $this->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Player[]
|
||||||
|
*/
|
||||||
|
public function getRecipients() : array{
|
||||||
|
return $this->recipients;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Player[] $recipients
|
||||||
|
*/
|
||||||
|
public function setRecipients(array $recipients) : void{
|
||||||
|
$this->recipients = $recipients;
|
||||||
|
}
|
||||||
|
}
|
@ -568,6 +568,16 @@ class Item implements \JsonSerializable{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a player uses the item to interact with entity, for example by using a name tag.
|
||||||
|
*
|
||||||
|
* @param Vector3 $clickVector The exact position of the click (absolute coordinates)
|
||||||
|
* @return bool whether some action took place
|
||||||
|
*/
|
||||||
|
public function onInteractEntity(Player $player, Entity $entity, Vector3 $clickVector) : bool{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of ticks a player must wait before activating this item again.
|
* Returns the number of ticks a player must wait before activating this item again.
|
||||||
*/
|
*/
|
||||||
|
@ -36,6 +36,7 @@ use function get_debug_type;
|
|||||||
use function is_array;
|
use function is_array;
|
||||||
use function is_int;
|
use function is_int;
|
||||||
use function json_decode;
|
use function json_decode;
|
||||||
|
use const JSON_THROW_ON_ERROR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles translation of network block runtime IDs into blockstate data, and vice versa
|
* Handles translation of network block runtime IDs into blockstate data, and vice versa
|
||||||
|
@ -34,6 +34,7 @@ use function openssl_digest;
|
|||||||
use function openssl_error_string;
|
use function openssl_error_string;
|
||||||
use function openssl_pkey_derive;
|
use function openssl_pkey_derive;
|
||||||
use function str_pad;
|
use function str_pad;
|
||||||
|
use const STR_PAD_LEFT;
|
||||||
|
|
||||||
final class EncryptionUtils{
|
final class EncryptionUtils{
|
||||||
|
|
||||||
|
@ -306,6 +306,8 @@ class InGamePacketHandler extends PacketHandler{
|
|||||||
public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{
|
public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{
|
||||||
$result = true;
|
$result = true;
|
||||||
|
|
||||||
|
$this->inventoryManager->addPredictedSlotChanges($packet->trData->getActions());
|
||||||
|
|
||||||
if($packet->trData instanceof NormalTransactionData){
|
if($packet->trData instanceof NormalTransactionData){
|
||||||
$result = $this->handleNormalTransaction($packet->trData);
|
$result = $this->handleNormalTransaction($packet->trData);
|
||||||
}elseif($packet->trData instanceof MismatchTransactionData){
|
}elseif($packet->trData instanceof MismatchTransactionData){
|
||||||
@ -355,7 +357,6 @@ class InGamePacketHandler extends PacketHandler{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->inventoryManager->addPredictedSlotChanges($data->getActions());
|
|
||||||
|
|
||||||
if($isCraftingPart){
|
if($isCraftingPart){
|
||||||
if($this->craftingTransaction === null){
|
if($this->craftingTransaction === null){
|
||||||
|
@ -52,6 +52,7 @@ use function mt_rand;
|
|||||||
use function random_bytes;
|
use function random_bytes;
|
||||||
use function rtrim;
|
use function rtrim;
|
||||||
use function substr;
|
use function substr;
|
||||||
|
use const PHP_INT_MAX;
|
||||||
|
|
||||||
class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{
|
class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{
|
||||||
/**
|
/**
|
||||||
|
@ -40,6 +40,7 @@ use function strlen;
|
|||||||
use function time;
|
use function time;
|
||||||
use function trim;
|
use function trim;
|
||||||
use const AF_INET;
|
use const AF_INET;
|
||||||
|
use const AF_INET6;
|
||||||
use const IPPROTO_IPV6;
|
use const IPPROTO_IPV6;
|
||||||
use const IPV6_V6ONLY;
|
use const IPV6_V6ONLY;
|
||||||
use const PHP_INT_MAX;
|
use const PHP_INT_MAX;
|
||||||
|
@ -73,6 +73,12 @@ use function sprintf;
|
|||||||
use function strlen;
|
use function strlen;
|
||||||
use function trim;
|
use function trim;
|
||||||
use const AF_INET;
|
use const AF_INET;
|
||||||
|
use const PREG_BACKTRACK_LIMIT_ERROR;
|
||||||
|
use const PREG_BAD_UTF8_ERROR;
|
||||||
|
use const PREG_BAD_UTF8_OFFSET_ERROR;
|
||||||
|
use const PREG_INTERNAL_ERROR;
|
||||||
|
use const PREG_JIT_STACKLIMIT_ERROR;
|
||||||
|
use const PREG_RECURSION_LIMIT_ERROR;
|
||||||
use const SO_RCVTIMEO;
|
use const SO_RCVTIMEO;
|
||||||
use const SOCK_DGRAM;
|
use const SOCK_DGRAM;
|
||||||
use const SOCKET_ETIMEDOUT;
|
use const SOCKET_ETIMEDOUT;
|
||||||
|
@ -1836,7 +1836,17 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
|||||||
|
|
||||||
$ev->call();
|
$ev->call();
|
||||||
|
|
||||||
|
$item = $this->inventory->getItemInHand();
|
||||||
|
$oldItem = clone $item;
|
||||||
if(!$ev->isCancelled()){
|
if(!$ev->isCancelled()){
|
||||||
|
if($item->onInteractEntity($this, $entity, $clickPos)){
|
||||||
|
if($this->hasFiniteResources() && !$item->equalsExact($oldItem) && $oldItem->equalsExact($this->inventory->getItemInHand())){
|
||||||
|
if($item instanceof Durable && $item->isBroken()){
|
||||||
|
$this->broadcastSound(new ItemBreakSound());
|
||||||
|
}
|
||||||
|
$this->inventory->setItemInHand($item);
|
||||||
|
}
|
||||||
|
}
|
||||||
return $entity->onInteract($this, $clickPos);
|
return $entity->onInteract($this, $clickPos);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -45,6 +45,7 @@ use function stream_copy_to_stream;
|
|||||||
use function strpos;
|
use function strpos;
|
||||||
use function strtolower;
|
use function strtolower;
|
||||||
use function trim;
|
use function trim;
|
||||||
|
use const DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
abstract class PluginBase implements Plugin, CommandExecutor{
|
abstract class PluginBase implements Plugin, CommandExecutor{
|
||||||
private bool $isEnabled = false;
|
private bool $isEnabled = false;
|
||||||
|
@ -29,6 +29,7 @@ use pocketmine\lang\Translatable;
|
|||||||
use pocketmine\permission\PermissibleBase;
|
use pocketmine\permission\PermissibleBase;
|
||||||
use pocketmine\permission\PermissibleDelegateTrait;
|
use pocketmine\permission\PermissibleDelegateTrait;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
|
use const PHP_INT_MAX;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forwards any messages it receives via sendMessage() to the given logger. Used for forwarding chat messages and
|
* Forwards any messages it receives via sendMessage() to the given logger. Used for forwarding chat messages and
|
||||||
|
@ -55,6 +55,7 @@ use const CASE_LOWER;
|
|||||||
use const JSON_BIGINT_AS_STRING;
|
use const JSON_BIGINT_AS_STRING;
|
||||||
use const JSON_PRETTY_PRINT;
|
use const JSON_PRETTY_PRINT;
|
||||||
use const JSON_THROW_ON_ERROR;
|
use const JSON_THROW_ON_ERROR;
|
||||||
|
use const YAML_UTF8_ENCODING;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config Class for simple config manipulation of multiple formats.
|
* Config Class for simple config manipulation of multiple formats.
|
||||||
|
@ -182,9 +182,10 @@ final class Filesystem{
|
|||||||
* @throws \InvalidArgumentException if the lock file path is invalid (e.g. parent directory doesn't exist, permission denied)
|
* @throws \InvalidArgumentException if the lock file path is invalid (e.g. parent directory doesn't exist, permission denied)
|
||||||
*/
|
*/
|
||||||
public static function createLockFile(string $lockFilePath) : ?int{
|
public static function createLockFile(string $lockFilePath) : ?int{
|
||||||
$resource = fopen($lockFilePath, "a+b");
|
try{
|
||||||
if($resource === false){
|
$resource = ErrorToExceptionHandler::trapAndRemoveFalse(fn() => fopen($lockFilePath, "a+b"));
|
||||||
throw new \InvalidArgumentException("Invalid lock file path or read/write permissions denied");
|
}catch(\ErrorException $e){
|
||||||
|
throw new \InvalidArgumentException("Failed to open lock file: " . $e->getMessage(), 0, $e);
|
||||||
}
|
}
|
||||||
if(!flock($resource, LOCK_EX | LOCK_NB)){
|
if(!flock($resource, LOCK_EX | LOCK_NB)){
|
||||||
//wait for a shared lock to avoid race conditions if two servers started at the same time - this makes sure the
|
//wait for a shared lock to avoid race conditions if two servers started at the same time - this makes sure the
|
||||||
|
@ -51,7 +51,9 @@ use pocketmine\event\world\ChunkLoadEvent;
|
|||||||
use pocketmine\event\world\ChunkPopulateEvent;
|
use pocketmine\event\world\ChunkPopulateEvent;
|
||||||
use pocketmine\event\world\ChunkUnloadEvent;
|
use pocketmine\event\world\ChunkUnloadEvent;
|
||||||
use pocketmine\event\world\SpawnChangeEvent;
|
use pocketmine\event\world\SpawnChangeEvent;
|
||||||
|
use pocketmine\event\world\WorldParticleEvent;
|
||||||
use pocketmine\event\world\WorldSaveEvent;
|
use pocketmine\event\world\WorldSaveEvent;
|
||||||
|
use pocketmine\event\world\WorldSoundEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\item\ItemUseResult;
|
use pocketmine\item\ItemUseResult;
|
||||||
use pocketmine\item\LegacyStringToItemParser;
|
use pocketmine\item\LegacyStringToItemParser;
|
||||||
@ -669,9 +671,19 @@ class World implements ChunkManager{
|
|||||||
* @param Player[]|null $players
|
* @param Player[]|null $players
|
||||||
*/
|
*/
|
||||||
public function addSound(Vector3 $pos, Sound $sound, ?array $players = null) : void{
|
public function addSound(Vector3 $pos, Sound $sound, ?array $players = null) : void{
|
||||||
$pk = $sound->encode($pos);
|
$players ??= $this->getViewersForPosition($pos);
|
||||||
|
$ev = new WorldSoundEvent($this, $sound, $pos, $players);
|
||||||
|
|
||||||
|
$ev->call();
|
||||||
|
|
||||||
|
if($ev->isCancelled()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pk = $ev->getSound()->encode($pos);
|
||||||
|
$players = $ev->getRecipients();
|
||||||
if(count($pk) > 0){
|
if(count($pk) > 0){
|
||||||
if($players === null){
|
if($players === $this->getViewersForPosition($pos)){
|
||||||
foreach($pk as $e){
|
foreach($pk as $e){
|
||||||
$this->broadcastPacketToViewers($pos, $e);
|
$this->broadcastPacketToViewers($pos, $e);
|
||||||
}
|
}
|
||||||
@ -685,14 +697,24 @@ class World implements ChunkManager{
|
|||||||
* @param Player[]|null $players
|
* @param Player[]|null $players
|
||||||
*/
|
*/
|
||||||
public function addParticle(Vector3 $pos, Particle $particle, ?array $players = null) : void{
|
public function addParticle(Vector3 $pos, Particle $particle, ?array $players = null) : void{
|
||||||
$pk = $particle->encode($pos);
|
$players ??= $this->getViewersForPosition($pos);
|
||||||
|
$ev = new WorldParticleEvent($this, $particle, $pos, $players);
|
||||||
|
|
||||||
|
$ev->call();
|
||||||
|
|
||||||
|
if($ev->isCancelled()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pk = $ev->getParticle()->encode($pos);
|
||||||
|
$players = $ev->getRecipients();
|
||||||
if(count($pk) > 0){
|
if(count($pk) > 0){
|
||||||
if($players === null){
|
if($players === $this->getViewersForPosition($pos)){
|
||||||
foreach($pk as $e){
|
foreach($pk as $e){
|
||||||
$this->broadcastPacketToViewers($pos, $e);
|
$this->broadcastPacketToViewers($pos, $e);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
$this->server->broadcastPackets($this->filterViewersForPosition($pos, $players), $pk);
|
$this->server->broadcastPackets($this->filterViewersForPosition($pos, $ev->getRecipients()), $pk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ use function file_get_contents;
|
|||||||
use function is_array;
|
use function is_array;
|
||||||
use function json_decode;
|
use function json_decode;
|
||||||
use function print_r;
|
use function print_r;
|
||||||
|
use const SORT_STRING;
|
||||||
|
|
||||||
class BlockTest extends TestCase{
|
class BlockTest extends TestCase{
|
||||||
|
|
||||||
|
@ -43,6 +43,10 @@ use function rename;
|
|||||||
use function round;
|
use function round;
|
||||||
use function scandir;
|
use function scandir;
|
||||||
use function unlink;
|
use function unlink;
|
||||||
|
use const PATHINFO_EXTENSION;
|
||||||
|
use const PHP_BINARY;
|
||||||
|
use const SCANDIR_SORT_NONE;
|
||||||
|
use const SORT_NUMERIC;
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@ use function realpath;
|
|||||||
use function trim;
|
use function trim;
|
||||||
use function zlib_decode;
|
use function zlib_decode;
|
||||||
use const FILE_IGNORE_NEW_LINES;
|
use const FILE_IGNORE_NEW_LINES;
|
||||||
|
use const JSON_PRETTY_PRINT;
|
||||||
|
use const JSON_UNESCAPED_SLASHES;
|
||||||
use const PHP_EOL;
|
use const PHP_EOL;
|
||||||
use const STDERR;
|
use const STDERR;
|
||||||
|
|
||||||
|
@ -40,6 +40,9 @@ use function fwrite;
|
|||||||
use function get_class;
|
use function get_class;
|
||||||
use function json_encode;
|
use function json_encode;
|
||||||
use function ksort;
|
use function ksort;
|
||||||
|
use const JSON_PRETTY_PRINT;
|
||||||
|
use const SORT_STRING;
|
||||||
|
use const STDERR;
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@ use function file_put_contents;
|
|||||||
use function fwrite;
|
use function fwrite;
|
||||||
use function json_encode;
|
use function json_encode;
|
||||||
use function ksort;
|
use function ksort;
|
||||||
|
use const JSON_PRETTY_PRINT;
|
||||||
|
use const SORT_STRING;
|
||||||
use const STDERR;
|
use const STDERR;
|
||||||
|
|
||||||
require_once dirname(__DIR__) . '/vendor/autoload.php';
|
require_once dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
@ -40,6 +40,11 @@ use function json_decode;
|
|||||||
use function json_encode;
|
use function json_encode;
|
||||||
use function ksort;
|
use function ksort;
|
||||||
use function scandir;
|
use function scandir;
|
||||||
|
use const JSON_FORCE_OBJECT;
|
||||||
|
use const JSON_PRETTY_PRINT;
|
||||||
|
use const JSON_THROW_ON_ERROR;
|
||||||
|
use const SCANDIR_SORT_ASCENDING;
|
||||||
|
use const SORT_STRING;
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
@ -49,9 +49,13 @@ use function socket_strerror;
|
|||||||
use function strlen;
|
use function strlen;
|
||||||
use function time;
|
use function time;
|
||||||
use function trim;
|
use function trim;
|
||||||
|
use const AF_INET;
|
||||||
use const MSG_DONTROUTE;
|
use const MSG_DONTROUTE;
|
||||||
use const PHP_BINARY;
|
use const PHP_BINARY;
|
||||||
use const PHP_INT_MAX;
|
use const PHP_INT_MAX;
|
||||||
|
use const SOCK_DGRAM;
|
||||||
|
use const SOL_UDP;
|
||||||
|
use const STDIN;
|
||||||
|
|
||||||
require_once 'vendor/autoload.php';
|
require_once 'vendor/autoload.php';
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user