mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-09 23:39:43 +00:00
Merge branch 'next-minor'
This commit is contained in:
commit
34ed2980e5
@ -1565,7 +1565,7 @@ MATHJAX_FORMAT = HTML-CSS
|
|||||||
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
|
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
|
||||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
MATHJAX_RELPATH = https://cdn.mathjax.org/mathjax/latest
|
||||||
|
|
||||||
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
|
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
|
||||||
# extension names that should be enabled during MathJax rendering. For example
|
# extension names that should be enabled during MathJax rendering. For example
|
||||||
|
@ -127,171 +127,175 @@ namespace pocketmine {
|
|||||||
return $messages;
|
return $messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($messages = check_platform_dependencies())){
|
function server(){
|
||||||
echo PHP_EOL;
|
if(!empty($messages = check_platform_dependencies())){
|
||||||
$binary = version_compare(PHP_VERSION, "5.4") >= 0 ? PHP_BINARY : "unknown";
|
echo PHP_EOL;
|
||||||
critical_error("Selected PHP binary ($binary) does not satisfy some requirements.");
|
$binary = version_compare(PHP_VERSION, "5.4") >= 0 ? PHP_BINARY : "unknown";
|
||||||
foreach($messages as $m){
|
critical_error("Selected PHP binary ($binary) does not satisfy some requirements.");
|
||||||
echo " - $m" . PHP_EOL;
|
foreach($messages as $m){
|
||||||
}
|
echo " - $m" . PHP_EOL;
|
||||||
critical_error("Please recompile PHP with the needed configuration, or refer to the installation instructions at http://pmmp.rtfd.io/en/rtfd/installation.html.");
|
|
||||||
echo PHP_EOL;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
unset($messages);
|
|
||||||
|
|
||||||
error_reporting(-1);
|
|
||||||
|
|
||||||
if(\Phar::running(true) !== ""){
|
|
||||||
define('pocketmine\PATH', \Phar::running(true) . "/");
|
|
||||||
}else{
|
|
||||||
define('pocketmine\PATH', dirname(__FILE__, 3) . DIRECTORY_SEPARATOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
$opts = getopt("", ["bootstrap:"]);
|
|
||||||
if(isset($opts["bootstrap"])){
|
|
||||||
$bootstrap = realpath($opts["bootstrap"]) ?: $opts["bootstrap"];
|
|
||||||
}else{
|
|
||||||
$bootstrap = \pocketmine\PATH . 'vendor/autoload.php';
|
|
||||||
}
|
|
||||||
define('pocketmine\COMPOSER_AUTOLOADER_PATH', $bootstrap);
|
|
||||||
|
|
||||||
if(\pocketmine\COMPOSER_AUTOLOADER_PATH !== false and is_file(\pocketmine\COMPOSER_AUTOLOADER_PATH)){
|
|
||||||
require_once(\pocketmine\COMPOSER_AUTOLOADER_PATH);
|
|
||||||
if(extension_loaded('parallel')){
|
|
||||||
\parallel\bootstrap(\pocketmine\COMPOSER_AUTOLOADER_PATH);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
critical_error("Composer autoloader not found at " . $bootstrap);
|
|
||||||
critical_error("Please install/update Composer dependencies or use provided builds.");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
\ErrorUtils::setErrorExceptionHandler();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We now use the Composer autoloader, but this autoloader is still for loading plugins.
|
|
||||||
*/
|
|
||||||
$autoloader = new \BaseClassLoader();
|
|
||||||
$autoloader->register(false);
|
|
||||||
|
|
||||||
set_time_limit(0); //Who set it to 30 seconds?!?!
|
|
||||||
|
|
||||||
ini_set("allow_url_fopen", '1');
|
|
||||||
ini_set("display_errors", '1');
|
|
||||||
ini_set("display_startup_errors", '1');
|
|
||||||
ini_set("default_charset", "utf-8");
|
|
||||||
|
|
||||||
ini_set("memory_limit", '-1');
|
|
||||||
|
|
||||||
define('pocketmine\RESOURCE_PATH', \pocketmine\PATH . 'resources' . DIRECTORY_SEPARATOR);
|
|
||||||
|
|
||||||
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]);
|
|
||||||
|
|
||||||
define('pocketmine\DATA', isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR);
|
|
||||||
define('pocketmine\PLUGIN_PATH', isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR);
|
|
||||||
|
|
||||||
if(!file_exists(\pocketmine\DATA)){
|
|
||||||
mkdir(\pocketmine\DATA, 0777, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
define('pocketmine\LOCK_FILE_PATH', \pocketmine\DATA . 'server.lock');
|
|
||||||
define('pocketmine\LOCK_FILE', fopen(\pocketmine\LOCK_FILE_PATH, "a+b"));
|
|
||||||
if(!flock(\pocketmine\LOCK_FILE, 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
|
|
||||||
//other server wrote its PID and released exclusive lock before we get our lock
|
|
||||||
flock(\pocketmine\LOCK_FILE, LOCK_SH);
|
|
||||||
$pid = stream_get_contents(\pocketmine\LOCK_FILE);
|
|
||||||
critical_error("Another " . \pocketmine\NAME . " instance (PID $pid) is already using this folder (" . realpath(\pocketmine\DATA) . ").");
|
|
||||||
critical_error("Please stop the other server first before running a new one.");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
ftruncate(\pocketmine\LOCK_FILE, 0);
|
|
||||||
fwrite(\pocketmine\LOCK_FILE, (string) getmypid());
|
|
||||||
fflush(\pocketmine\LOCK_FILE);
|
|
||||||
flock(\pocketmine\LOCK_FILE, LOCK_SH); //prevent acquiring an exclusive lock from another process, but allow reading
|
|
||||||
|
|
||||||
//Logger has a dependency on timezone
|
|
||||||
Timezone::init();
|
|
||||||
|
|
||||||
if(isset($opts["enable-ansi"])){
|
|
||||||
Terminal::init(true);
|
|
||||||
}elseif(isset($opts["disable-ansi"])){
|
|
||||||
Terminal::init(false);
|
|
||||||
}else{
|
|
||||||
Terminal::init();
|
|
||||||
}
|
|
||||||
|
|
||||||
$logger = new MainLogger(\pocketmine\DATA . "server.log");
|
|
||||||
\GlobalLogger::set($logger);
|
|
||||||
|
|
||||||
if(extension_loaded("xdebug")){
|
|
||||||
$logger->warning(PHP_EOL . PHP_EOL . PHP_EOL . "\tYou are running " . \pocketmine\NAME . " with xdebug enabled. This has a major impact on performance." . PHP_EOL . PHP_EOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(\Phar::running(true) === ""){
|
|
||||||
$logger->warning("Non-packaged " . \pocketmine\NAME . " installation detected. Consider using a phar in production for better performance.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
|
|
||||||
define('pocketmine\VERSION', $version->getFullVersion(true));
|
|
||||||
|
|
||||||
$gitHash = str_repeat("00", 20);
|
|
||||||
|
|
||||||
if(\Phar::running(true) === ""){
|
|
||||||
if(Process::execute("git rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){
|
|
||||||
$gitHash = trim($out);
|
|
||||||
if(Process::execute("git diff --quiet") === 1 or Process::execute("git diff --cached --quiet") === 1){ //Locally-modified
|
|
||||||
$gitHash .= "-dirty";
|
|
||||||
}
|
}
|
||||||
|
critical_error("Please recompile PHP with the needed configuration, or refer to the installation instructions at http://pmmp.rtfd.io/en/rtfd/installation.html.");
|
||||||
|
echo PHP_EOL;
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
}else{
|
unset($messages);
|
||||||
$phar = new \Phar(\Phar::running(false));
|
|
||||||
$meta = $phar->getMetadata();
|
error_reporting(-1);
|
||||||
if(isset($meta["git"])){
|
|
||||||
$gitHash = $meta["git"];
|
if(\Phar::running(true) !== ""){
|
||||||
|
define('pocketmine\PATH', \Phar::running(true) . "/");
|
||||||
|
}else{
|
||||||
|
define('pocketmine\PATH', dirname(__FILE__, 3) . DIRECTORY_SEPARATOR);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
define('pocketmine\GIT_COMMIT', $gitHash);
|
$opts = getopt("", ["bootstrap:"]);
|
||||||
|
if(isset($opts["bootstrap"])){
|
||||||
|
$bootstrap = realpath($opts["bootstrap"]) ?: $opts["bootstrap"];
|
||||||
|
}else{
|
||||||
|
$bootstrap = \pocketmine\PATH . 'vendor/autoload.php';
|
||||||
|
}
|
||||||
|
define('pocketmine\COMPOSER_AUTOLOADER_PATH', $bootstrap);
|
||||||
|
|
||||||
|
if(\pocketmine\COMPOSER_AUTOLOADER_PATH !== false and is_file(\pocketmine\COMPOSER_AUTOLOADER_PATH)){
|
||||||
|
require_once(\pocketmine\COMPOSER_AUTOLOADER_PATH);
|
||||||
|
if(extension_loaded('parallel')){
|
||||||
|
\parallel\bootstrap(\pocketmine\COMPOSER_AUTOLOADER_PATH);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
critical_error("Composer autoloader not found at " . $bootstrap);
|
||||||
|
critical_error("Please install/update Composer dependencies or use provided builds.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
@define("INT32_MASK", is_int(0xffffffff) ? 0xffffffff : -1);
|
\ErrorUtils::setErrorExceptionHandler();
|
||||||
@ini_set("opcache.mmap_base", bin2hex(random_bytes(8))); //Fix OPCache address errors
|
|
||||||
|
|
||||||
$exitCode = 0;
|
/*
|
||||||
do{
|
* We now use the Composer autoloader, but this autoloader is still for loading plugins.
|
||||||
if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){
|
*/
|
||||||
$installer = new SetupWizard();
|
$autoloader = new \BaseClassLoader();
|
||||||
if(!$installer->run()){
|
$autoloader->register(false);
|
||||||
$exitCode = -1;
|
|
||||||
break;
|
set_time_limit(0); //Who set it to 30 seconds?!?!
|
||||||
|
|
||||||
|
ini_set("allow_url_fopen", '1');
|
||||||
|
ini_set("display_errors", '1');
|
||||||
|
ini_set("display_startup_errors", '1');
|
||||||
|
ini_set("default_charset", "utf-8");
|
||||||
|
|
||||||
|
ini_set("memory_limit", '-1');
|
||||||
|
|
||||||
|
define('pocketmine\RESOURCE_PATH', \pocketmine\PATH . 'resources' . DIRECTORY_SEPARATOR);
|
||||||
|
|
||||||
|
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]);
|
||||||
|
|
||||||
|
define('pocketmine\DATA', isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR);
|
||||||
|
define('pocketmine\PLUGIN_PATH', isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR);
|
||||||
|
|
||||||
|
if(!file_exists(\pocketmine\DATA)){
|
||||||
|
mkdir(\pocketmine\DATA, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
define('pocketmine\LOCK_FILE_PATH', \pocketmine\DATA . 'server.lock');
|
||||||
|
define('pocketmine\LOCK_FILE', fopen(\pocketmine\LOCK_FILE_PATH, "a+b"));
|
||||||
|
if(!flock(\pocketmine\LOCK_FILE, 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
|
||||||
|
//other server wrote its PID and released exclusive lock before we get our lock
|
||||||
|
flock(\pocketmine\LOCK_FILE, LOCK_SH);
|
||||||
|
$pid = stream_get_contents(\pocketmine\LOCK_FILE);
|
||||||
|
critical_error("Another " . \pocketmine\NAME . " instance (PID $pid) is already using this folder (" . realpath(\pocketmine\DATA) . ").");
|
||||||
|
critical_error("Please stop the other server first before running a new one.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
ftruncate(\pocketmine\LOCK_FILE, 0);
|
||||||
|
fwrite(\pocketmine\LOCK_FILE, (string) getmypid());
|
||||||
|
fflush(\pocketmine\LOCK_FILE);
|
||||||
|
flock(\pocketmine\LOCK_FILE, LOCK_SH); //prevent acquiring an exclusive lock from another process, but allow reading
|
||||||
|
|
||||||
|
//Logger has a dependency on timezone
|
||||||
|
Timezone::init();
|
||||||
|
|
||||||
|
if(isset($opts["enable-ansi"])){
|
||||||
|
Terminal::init(true);
|
||||||
|
}elseif(isset($opts["disable-ansi"])){
|
||||||
|
Terminal::init(false);
|
||||||
|
}else{
|
||||||
|
Terminal::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
$logger = new MainLogger(\pocketmine\DATA . "server.log");
|
||||||
|
\GlobalLogger::set($logger);
|
||||||
|
|
||||||
|
if(extension_loaded("xdebug")){
|
||||||
|
$logger->warning(PHP_EOL . PHP_EOL . PHP_EOL . "\tYou are running " . \pocketmine\NAME . " with xdebug enabled. This has a major impact on performance." . PHP_EOL . PHP_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(\Phar::running(true) === ""){
|
||||||
|
$logger->warning("Non-packaged " . \pocketmine\NAME . " installation detected. Consider using a phar in production for better performance.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
|
||||||
|
define('pocketmine\VERSION', $version->getFullVersion(true));
|
||||||
|
|
||||||
|
$gitHash = str_repeat("00", 20);
|
||||||
|
|
||||||
|
if(\Phar::running(true) === ""){
|
||||||
|
if(Process::execute("git rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){
|
||||||
|
$gitHash = trim($out);
|
||||||
|
if(Process::execute("git diff --quiet") === 1 or Process::execute("git diff --cached --quiet") === 1){ //Locally-modified
|
||||||
|
$gitHash .= "-dirty";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$phar = new \Phar(\Phar::running(false));
|
||||||
|
$meta = $phar->getMetadata();
|
||||||
|
if(isset($meta["git"])){
|
||||||
|
$gitHash = $meta["git"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: move this to a Server field
|
define('pocketmine\GIT_COMMIT', $gitHash);
|
||||||
define('pocketmine\START_TIME', microtime(true));
|
|
||||||
ThreadManager::init();
|
|
||||||
new Server($autoloader, $logger, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
|
||||||
|
|
||||||
$logger->info("Stopping other threads");
|
|
||||||
|
|
||||||
$killer = new ServerKiller(8);
|
@define("INT32_MASK", is_int(0xffffffff) ? 0xffffffff : -1);
|
||||||
$killer->start(PTHREADS_INHERIT_NONE);
|
@ini_set("opcache.mmap_base", bin2hex(random_bytes(8))); //Fix OPCache address errors
|
||||||
usleep(10000); //Fixes ServerKiller not being able to start on single-core machines
|
|
||||||
|
|
||||||
if(ThreadManager::getInstance()->stopAll() > 0){
|
$exitCode = 0;
|
||||||
if(\pocketmine\DEBUG > 1){
|
do{
|
||||||
echo "Some threads could not be stopped, performing a force-kill" . PHP_EOL . PHP_EOL;
|
if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){
|
||||||
|
$installer = new SetupWizard();
|
||||||
|
if(!$installer->run()){
|
||||||
|
$exitCode = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Process::kill(getmypid());
|
|
||||||
}
|
|
||||||
}while(false);
|
|
||||||
|
|
||||||
$logger->shutdown();
|
//TODO: move this to a Server field
|
||||||
$logger->join();
|
define('pocketmine\START_TIME', microtime(true));
|
||||||
|
ThreadManager::init();
|
||||||
|
new Server($autoloader, $logger, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||||
|
|
||||||
echo Terminal::$FORMAT_RESET . PHP_EOL;
|
$logger->info("Stopping other threads");
|
||||||
|
|
||||||
exit($exitCode);
|
$killer = new ServerKiller(8);
|
||||||
|
$killer->start(PTHREADS_INHERIT_NONE);
|
||||||
|
usleep(10000); //Fixes ServerKiller not being able to start on single-core machines
|
||||||
|
|
||||||
|
if(ThreadManager::getInstance()->stopAll() > 0){
|
||||||
|
if(\pocketmine\DEBUG > 1){
|
||||||
|
echo "Some threads could not be stopped, performing a force-kill" . PHP_EOL . PHP_EOL;
|
||||||
|
}
|
||||||
|
Process::kill(getmypid());
|
||||||
|
}
|
||||||
|
}while(false);
|
||||||
|
|
||||||
|
$logger->shutdown();
|
||||||
|
$logger->join();
|
||||||
|
|
||||||
|
echo Terminal::$FORMAT_RESET . PHP_EOL;
|
||||||
|
|
||||||
|
exit($exitCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
\pocketmine\server();
|
||||||
}
|
}
|
||||||
|
@ -33,12 +33,12 @@ use function unserialize;
|
|||||||
*
|
*
|
||||||
* An AsyncTask does not have its own thread. It is queued into an AsyncPool and executed if there is an async worker
|
* An AsyncTask does not have its own thread. It is queued into an AsyncPool and executed if there is an async worker
|
||||||
* with no AsyncTask running. Therefore, an AsyncTask SHOULD NOT execute for more than a few seconds. For tasks that
|
* with no AsyncTask running. Therefore, an AsyncTask SHOULD NOT execute for more than a few seconds. For tasks that
|
||||||
* run for a long time or infinitely, start another {@link \pocketmine\thread\Thread} instead.
|
* run for a long time or infinitely, start another thread instead.
|
||||||
*
|
*
|
||||||
* WARNING: Any non-Threaded objects WILL BE SERIALIZED when assigned to members of AsyncTasks or other Threaded object.
|
* WARNING: Any non-Threaded objects WILL BE SERIALIZED when assigned to members of AsyncTasks or other Threaded object.
|
||||||
* If later accessed from said Threaded object, you will be operating on a COPY OF THE OBJECT, NOT THE ORIGINAL OBJECT.
|
* If later accessed from said Threaded object, you will be operating on a COPY OF THE OBJECT, NOT THE ORIGINAL OBJECT.
|
||||||
* If you want to store non-serializable objects to access when the task completes, store them using
|
* If you want to store non-serializable objects to access when the task completes, store them using
|
||||||
* {@link AsyncTask#storeLocal}.
|
* {@link AsyncTask::storeLocal}.
|
||||||
*
|
*
|
||||||
* WARNING: As of pthreads v3.1.6, arrays are converted to Volatile objects when assigned as members of Threaded objects.
|
* WARNING: As of pthreads v3.1.6, arrays are converted to Volatile objects when assigned as members of Threaded objects.
|
||||||
* Keep this in mind when using arrays stored as members of your AsyncTask.
|
* Keep this in mind when using arrays stored as members of your AsyncTask.
|
||||||
@ -152,8 +152,8 @@ abstract class AsyncTask extends \Threaded{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this method from {@link AsyncTask#onRun} (AsyncTask execution thread) to schedule a call to
|
* Call this method from {@link AsyncTask::onRun} (AsyncTask execution thread) to schedule a call to
|
||||||
* {@link AsyncTask#onProgressUpdate} from the main thread with the given progress parameter.
|
* {@link AsyncTask::onProgressUpdate} from the main thread with the given progress parameter.
|
||||||
*
|
*
|
||||||
* @param mixed $progress A value that can be safely serialize()'ed.
|
* @param mixed $progress A value that can be safely serialize()'ed.
|
||||||
*/
|
*/
|
||||||
@ -172,9 +172,9 @@ abstract class AsyncTask extends \Threaded{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from the main thread after {@link AsyncTask#publishProgress} is called.
|
* Called from the main thread after {@link AsyncTask::publishProgress} is called.
|
||||||
* All {@link AsyncTask#publishProgress} calls should result in {@link AsyncTask#onProgressUpdate} calls before
|
* All {@link AsyncTask::publishProgress} calls should result in {@link AsyncTask::onProgressUpdate} calls before
|
||||||
* {@link AsyncTask#onCompletion} is called.
|
* {@link AsyncTask::onCompletion} is called.
|
||||||
*
|
*
|
||||||
* @param mixed $progress The parameter passed to {@link AsyncTask#publishProgress}. It is serialize()'ed
|
* @param mixed $progress The parameter passed to {@link AsyncTask#publishProgress}. It is serialize()'ed
|
||||||
* and then unserialize()'ed, as if it has been cloned.
|
* and then unserialize()'ed, as if it has been cloned.
|
||||||
@ -205,14 +205,6 @@ abstract class AsyncTask extends \Threaded{
|
|||||||
* Objects stored in this storage can be retrieved using fetchLocal() on the same thread that this method was called
|
* Objects stored in this storage can be retrieved using fetchLocal() on the same thread that this method was called
|
||||||
* from.
|
* from.
|
||||||
*
|
*
|
||||||
* WARNING: Use this method carefully. It might take a long time before an AsyncTask is completed. The thread this
|
|
||||||
* is called on will keep a strong reference to variables stored using method. This may result in a light memory
|
|
||||||
* leak. Usually this does not cause memory failure, but be aware that the object may be no longer usable when the
|
|
||||||
* AsyncTask completes. Since a strong reference is retained, the objects still exist, but the implementation is
|
|
||||||
* responsible for checking whether these objects are still usable.
|
|
||||||
* (E.g. a {@link \pocketmine\World} object is no longer usable because it is unloaded while the AsyncTask is
|
|
||||||
* executing, or even a plugin might be unloaded).
|
|
||||||
*
|
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @param mixed $complexData the data to store
|
* @param mixed $complexData the data to store
|
||||||
*/
|
*/
|
||||||
|
@ -31,9 +31,7 @@ use function unserialize;
|
|||||||
/**
|
/**
|
||||||
* Executes a consecutive list of cURL operations.
|
* Executes a consecutive list of cURL operations.
|
||||||
*
|
*
|
||||||
* The result of this AsyncTask is an array of arrays (returned from {@link Utils::simpleCurl}) or InternetException objects.
|
* The result of this AsyncTask is an array of arrays (returned from {@link Internet::simpleCurl}) or InternetException objects.
|
||||||
*
|
|
||||||
* @package pocketmine\scheduler
|
|
||||||
*/
|
*/
|
||||||
class BulkCurlTask extends AsyncTask{
|
class BulkCurlTask extends AsyncTask{
|
||||||
private $operations;
|
private $operations;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user