mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-11 03:58:06 +00:00
Compare commits
1 Commits
3.7.3
...
Alpha_1.2.
Author | SHA1 | Date | |
---|---|---|---|
af17ce6c58 |
@ -1,10 +0,0 @@
|
||||
# http://editorconfig.org/
|
||||
root = yes
|
||||
|
||||
[*]
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
indent_style = space
|
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -5,8 +5,6 @@
|
||||
*.txt text eol=lf
|
||||
*.properties text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.cmd text eol=crlf
|
||||
*.ps1 text eol=crlf
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
|
19
.github/ISSUE_TEMPLATE/api-change-request.md
vendored
19
.github/ISSUE_TEMPLATE/api-change-request.md
vendored
@ -1,19 +0,0 @@
|
||||
---
|
||||
name: API change request
|
||||
about: Suggest a change, addition or removal to the plugin API
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--- tell us what you want -->
|
||||
## Description
|
||||
|
||||
|
||||
<!--- explain why you want this and why it's a good idea -->
|
||||
## Justification
|
||||
|
||||
|
||||
<!--- (optional) describe alternative methods you've explored to achieve your goal -->
|
||||
## Alternative methods
|
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,36 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Unexpected non-crash behaviour (except missing gameplay features)
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Issue description
|
||||
|
||||
- Expected result: What were you expecting to happen?
|
||||
- Actual result: What actually happened?
|
||||
|
||||
### Steps to reproduce the issue
|
||||
1. ...
|
||||
2. ...
|
||||
|
||||
### OS and versions
|
||||
<!-- try the `version` command | LATEST IS NOT A VALID VERSION -->
|
||||
* PocketMine-MP:
|
||||
* PHP:
|
||||
* Server OS:
|
||||
* Game version: PE/Win10 (delete as appropriate)
|
||||
|
||||
### Plugins
|
||||
<!--- use the `plugins` command and paste the output below -->
|
||||
|
||||
- If you remove all plugins, does the issue still occur?
|
||||
- If the issue is **not** reproducible without plugins:
|
||||
- Have you asked for help on our forums before creating an issue?
|
||||
- Can you provide sample, *minimal* reproducing code for the issue? If so, paste it in the bottom section
|
||||
|
||||
### Crashdump, backtrace or other files
|
||||
<!--- Submit crashdumps at https://crash.pmmp.io and paste a link -->
|
||||
<!--- Use gist or anything else to add other files and add links here -->
|
15
.github/ISSUE_TEMPLATE/crash.md
vendored
15
.github/ISSUE_TEMPLATE/crash.md
vendored
@ -1,15 +0,0 @@
|
||||
---
|
||||
name: Crash
|
||||
about: Report a crash in PocketMine-MP (not plugins)
|
||||
title: Server crashed
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--- submit crashdump files to https://crash.pmmp.io -->
|
||||
<!--- or, copy the data between ===BEGIN CRASH DUMP=== and ===END CRASH DUMP and paste it on a site like https://pastebin.com -->
|
||||
Link to crashdump:
|
||||
|
||||
<!--- write additional information about the crash to help us find the problem -->
|
||||
### Additional comments (optional)
|
14
.github/ISSUE_TEMPLATE/help---support.md
vendored
14
.github/ISSUE_TEMPLATE/help---support.md
vendored
@ -1,14 +0,0 @@
|
||||
---
|
||||
name: Help & support
|
||||
about: We don't accept support requests here. Try the links on the README.
|
||||
title: ''
|
||||
labels: Support request
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
We don't accept support requests on the issue tracker. Please try the following links instead:
|
||||
|
||||
Documentation: http://pmmp.rtfd.io
|
||||
Forums: https://forums.pmmp.io
|
||||
Discord: https://discord.gg/bge7dYQ
|
@ -1,12 +0,0 @@
|
||||
---
|
||||
name: Security/DoS vulnerability
|
||||
about: 'Bug or exploit that can be used to attack servers (hint: don''t report it
|
||||
on a public issue tracker)'
|
||||
title: ''
|
||||
labels: 'Auto: Spam'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please DO NOT report security vulnerabilities here.
|
||||
Instead, send an email to team@pmmp.io or contact a developer directly, IN PRIVATE.
|
40
.github/PULL_REQUEST_TEMPLATE.md
vendored
40
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,40 +0,0 @@
|
||||
## Introduction
|
||||
<!-- Explain existing problems or why this pull request is necessary -->
|
||||
|
||||
### Relevant issues
|
||||
<!-- List relevant issues here -->
|
||||
<!--
|
||||
|
||||
* Fixes #1
|
||||
* Fixes #2
|
||||
|
||||
-->
|
||||
|
||||
## Changes
|
||||
### API changes
|
||||
<!-- Any additions to the API that should be documented in release notes? -->
|
||||
|
||||
### Behavioural changes
|
||||
<!-- Any change in how the server behaves, or its performance? -->
|
||||
|
||||
## Backwards compatibility
|
||||
<!-- Any possible backwards incompatible changes? How are they solved, or how can they be solved? -->
|
||||
|
||||
## Follow-up
|
||||
<!-- Suggest any actions to be done before/after merging this pull request -->
|
||||
<!--
|
||||
|
||||
Requires translations:
|
||||
|
||||
| Name | Value in eng.ini |
|
||||
| :--: | :---: |
|
||||
| `foo.bar` | `Foo bar` |
|
||||
|
||||
-->
|
||||
|
||||
## Tests
|
||||
<!--
|
||||
Details should be provided of tests done. Simply saying "tested" or equivalent is not acceptable.
|
||||
|
||||
Attach scripts or actions to test this pull request, as well as the result
|
||||
-->
|
16
.github/support.yml
vendored
16
.github/support.yml
vendored
@ -1,16 +0,0 @@
|
||||
# Configuration for support-requests - https://github.com/dessant/support-requests
|
||||
|
||||
# Label used to mark issues as support requests
|
||||
supportLabel: "Support request"
|
||||
# Comment to post on issues marked as support requests. Add a link
|
||||
# to a support page, or set to `false` to disable
|
||||
supportComment: >
|
||||
Thanks, but this issue tracker not intended for support requests. Please read the guidelines on [submitting an issue](https://github.com/pmmp/PocketMine-MP/blob/master/CONTRIBUTING.md#creating-an-issue).
|
||||
|
||||
|
||||
[Docs](https://pmmp.rtfd.io) | [Discord](https://discord.gg/bge7dYQ) | [Forums](https://forums.pmmp.io)
|
||||
|
||||
# Whether to close issues marked as support requests
|
||||
close: true
|
||||
# Whether to lock issues marked as support requests
|
||||
lock: false
|
187
.gitignore
vendored
187
.gitignore
vendored
@ -1,22 +1,136 @@
|
||||
players/*
|
||||
worlds/*
|
||||
plugin_data/*
|
||||
plugins/*
|
||||
bin*/*
|
||||
timings/*
|
||||
crashdumps/*
|
||||
logs/*
|
||||
*.log
|
||||
*.txt
|
||||
*.phar
|
||||
*.pmf
|
||||
server.properties
|
||||
/pocketmine.yml
|
||||
memory_dumps/*
|
||||
resource_packs/
|
||||
server.lock
|
||||
white-list.txt
|
||||
banned-ips.txt
|
||||
banned.txt
|
||||
ops.txt
|
||||
|
||||
# Common IDEs
|
||||
.idea/
|
||||
nbproject/*
|
||||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.vspscc
|
||||
.builds
|
||||
*.dotCover
|
||||
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment this
|
||||
#packages/
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish
|
||||
|
||||
# Others
|
||||
[Bb]in
|
||||
[Oo]bj
|
||||
sql
|
||||
TestResults
|
||||
*.Cache
|
||||
ClientBin
|
||||
stylecop.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
|
||||
|
||||
|
||||
############
|
||||
## Windows
|
||||
############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
@ -24,19 +138,38 @@ Thumbs.db
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[co]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
/nbproject/private/
|
||||
|
||||
# Sphinx-doc
|
||||
/docs/build/
|
||||
!/docs/requirements.txt
|
||||
|
||||
# Composer
|
||||
vendor/*
|
||||
|
||||
# Travis files
|
||||
test_data/*
|
||||
|
||||
# Doxygen
|
||||
Documentation/*
|
||||
|
12
.gitmodules
vendored
12
.gitmodules
vendored
@ -1,12 +0,0 @@
|
||||
[submodule "src/pocketmine/lang/locale"]
|
||||
path = src/pocketmine/lang/locale
|
||||
url = https://github.com/pmmp/PocketMine-Language.git
|
||||
[submodule "tests/preprocessor"]
|
||||
path = tests/preprocessor
|
||||
url = https://github.com/pmmp/preprocessor.git
|
||||
[submodule "tests/plugins/PocketMine-DevTools"]
|
||||
path = tests/plugins/PocketMine-DevTools
|
||||
url = https://github.com/pmmp/PocketMine-DevTools.git
|
||||
[submodule "src/pocketmine/resources/vanilla"]
|
||||
path = src/pocketmine/resources/vanilla
|
||||
url = https://github.com/pmmp/BedrockData.git
|
28
.travis.yml
28
.travis.yml
@ -1,25 +1,19 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 7.2
|
||||
- 7.3
|
||||
|
||||
- 5.4
|
||||
|
||||
before_script:
|
||||
# - pecl install channel://pecl.php.net/pthreads-3.1.6
|
||||
- echo | pecl install channel://pecl.php.net/yaml-2.0.4
|
||||
- git clone https://github.com/pmmp/pthreads.git
|
||||
- cd pthreads
|
||||
- git checkout 6ca019c58b4fa09ee2ff490f2444e34bef0773d0
|
||||
- phpize
|
||||
- ./configure
|
||||
- make
|
||||
- make install
|
||||
- cd ..
|
||||
- echo "extension=pthreads.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
|
||||
- composer install
|
||||
- pecl install channel://pecl.php.net/pthreads-0.0.42
|
||||
- git clone --depth=100 --quiet --branch=tests git://github.com/shoghicp/PocketMine-MP.git $(pwd)/tests/
|
||||
|
||||
script:
|
||||
- ./tests/travis.sh -t4
|
||||
|
||||
- phpunit tests/
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
irc:
|
||||
channels:
|
||||
- "irc.freenode.org#mcpedevs"
|
||||
template:
|
||||
- "PocketMine-MP #%{build_number} %{commit}: %{message} (%{build_url})"
|
||||
|
126
CONTRIBUTING.md
126
CONTRIBUTING.md
@ -1,126 +0,0 @@
|
||||

|
||||
|
||||
# PocketMine-MP Contribution Guidelines
|
||||
|
||||
|
||||
## Creating an Issue
|
||||
- If you are reporting a bug:
|
||||
- **make sure that you are using the latest supported version** before opening an issue.
|
||||
- **test it on a clean test server, WITHOUT PLUGINS**, to see if the issue still occurs. If not then it may be a plugin issue. Please also indicate the result of such tests.
|
||||
- **[Search the issue tracker](https://github.com/pmmp/PocketMine-MP/issues?utf8=%E2%9C%93&q=is%3Aissue)** to check if anyone has already reported it, to avoid needlessly creating duplicate issues. Make sure you also check closed issues, as an issue you think is valid may already have been resolved.
|
||||
- **Do not report plugin issues here.** If your issue is related to a plugin, contact the plugin's original author instead.
|
||||
- **Support requests are not bugs.** Issues such as "How do I do this" are not bugs and will be closed. If you need help, please see [here](README.md#discussion) and do not misuse our issue tracker.
|
||||
- **No generic titles** such as "Question", "Help", "Crash Report" etc. A good issue report provides a quick summary in the title. If you just got a crash report but you don't understand it, please look for a line starting with `Message`. It summarizes the bug.
|
||||
- **Provide information in the issue body, not in the title.** No tags like `[BUG]` are allowed in the title, including `[SOLVED]` for solved issues.
|
||||
- **No generic issue reports.** For bugs, it is the issue author's responsibility to provide us an issue that is **trackable, debuggable, reproducible, reported professionally and is an actual bug**.
|
||||
<br>Valid issue reports must include instructions how to reproduce the issue or a crashdump/backtrace (unless the cause of the issue is obvious).
|
||||
<br>**If you do not provide us with a summary or instructions on how to reproduce the issue, it will be treated as spam and will therefore be closed.**
|
||||
<br>In simple words, if the issue cannot be properly confirmed to be valid or lacks required information, the issue will be closed until further information is provided.
|
||||
- To express appreciation, objection, confusion or other supported reactions on pull requests, issues or comments on them, use GitHub [reactions](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) rather than posting an individual comment with an emoji only. This helps keeping the issue/pull request conversation clean and readable.
|
||||
- If your issue is related to the PocketMine-MP website, forums, etc., please [talk to a human directly](README.md#discussion).
|
||||
|
||||
|
||||
|
||||
## Contributing
|
||||
To contribute to the repository, [fork it on GitHub](https://github.com/pmmp/PocketMine-MP/fork), create a branch on your fork, and make your changes on your fork. You can then make a [pull request](https://github.com/pmmp/PocketMine-MP/pull/new) to the project to compare your branch to ours and propose your changes to our repository. We use the Pull Request system to allow members of the team to review changes before they are merged.
|
||||
|
||||
### Licensing
|
||||
By proposing a pull request to the project, you agree to your code being distributed within PocketMine-MP under the [LGPL license](LICENSE).
|
||||
|
||||
### Contribution standards
|
||||
- **We enforce a very high standard for contributions**. This is because PocketMine-MP and its related projects are used very widely in production. While this might seem like we are being mean at times, **our priority is what is best for PocketMine-MP itself**.
|
||||
We try to ensure that our project's codebase is as clean as possible and ensure that only top-quality material makes it through to PocketMine-MP itself.
|
||||
- **If a contribution does not meet our standards, changes may be requested or the pull request may be closed.**
|
||||
|
||||
### Pull requests
|
||||
- **Create a new branch for each pull request.** Do not create a pull request with commits that exist in another pull request.
|
||||
- **Use descriptive commit titles.** You can see an example [here](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
||||
- **Do not include multiple unrelated changes in one commit.** An atomic style for commits is preferred - this means that changes included in a commit should be part of a single distinct change set. See [this link](https://www.freshconsulting.com/atomic-commits/) for more information on atomic commits. See the [documentation on `git add`](https://git-scm.com/docs/git-add) for information on how to isolate local changes for committing.
|
||||
- **Your pull request will be checked and discussed in due time.** Since the team is scattered all around the world, your PR may not receive any attention for some time.
|
||||
- **It is inadvisable to create large pull requests with lots of changes** unless this has been discussed with the team beforehand. Large pull requests are difficult to review, and such pull requests may end up being closed. The only exception is when all features in the pull request are related to each other, and share the same core changes.
|
||||
- **You may be asked to rebase your pull request** if the branch becomes outdated and/or if possibly conflicting changes are made to the target branch. To see how to do this, read [this page](https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request).
|
||||
- **Details should be provided of tests done.** Simply saying "Tested" or equivalent is not acceptable.
|
||||
|
||||
### Code contributions
|
||||
- **Avoid committing changes directly on GitHub. This includes use of the web editor, and also uploading files.** The web editor lacks most useful GIT features and **should only be used for very minor changes**. It is immediately clear if the web editor has been used, and if so the PR is more likely to be rejected. If you want to make serious contributions, **please learn how to use [GIT version control](https://git-scm.com/)**.
|
||||
- **Do not copy-paste code**. There are potential license issues implicit with copy-pasting, and copy-paste usually indicates a lack of understanding of the actual code. Copy-pasted code is obvious a mile off and **any PR like this is likely to be closed**. If you want to use somebody else's code from a Git repository, **use [GIT's cherry-pick feature](https://git-scm.com/docs/git-cherry-pick)** to cherry-pick the commit. **Cherry-picking is the politer way to copy somebody's changes** and retains all the original accreditation, so there is no need for copy-pasted commits with descriptions like `Some code, thanks @exampleperson`.
|
||||
- **Make sure you can explain your changes**. If you can't provide a good explanation of changes, your PR may be rejected.
|
||||
- **Code should use the same style as in PocketMine-MP.** See [below](#code-syntax) for an example.
|
||||
- **The code must be clear** and written in English, comments included.
|
||||
|
||||
|
||||
**Thanks for contributing to PocketMine-MP!**
|
||||
|
||||
|
||||
|
||||
### Code Syntax
|
||||
|
||||
It is mainly [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) with a few exceptions.
|
||||
|
||||
- Opening braces MUST go on the same line, and MUST NOT have spaces before.
|
||||
- `else if` MUST be written as `elseif`. _(It is in PSR-2, but using a SHOULD)_
|
||||
- Control structure keywords or opening braces MUST NOT have one space before or after them.
|
||||
- Code MUST use tabs for indenting.
|
||||
- Long arrays MAY be split across multiple lines, where each subsequent line is indented once.
|
||||
- Files MUST use only the `<?php` tag.
|
||||
- Files MUST NOT have an ending `?>` tag.
|
||||
- Code MUST use namespaces.
|
||||
- Strings SHOULD use the double quote `"` except when the single quote is required.
|
||||
- All code SHOULD have parameter and type declarations where possible.
|
||||
- Strict types SHOULD be enabled on new files where it is sensible to do so.
|
||||
- All constant declarations SHOULD be preceded by a visibility modifier.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\example;
|
||||
|
||||
class ExampleClass{
|
||||
|
||||
public const EXAMPLE_CLASS_CONSTANT = 1;
|
||||
|
||||
public $examplePublicVariable = "defaultValue";
|
||||
private $examplePrivateVariable;
|
||||
|
||||
/**
|
||||
* Creates an instance of ExampleClass
|
||||
*
|
||||
* @param string $firstArgument the first argument
|
||||
* @param string|null $secondArgument default null
|
||||
*/
|
||||
public function __construct(string $firstArgument, ?string &$secondArgument = null){
|
||||
if($firstArgument === "exampleValue"){ //Remember to use === instead of == when possible
|
||||
//do things
|
||||
}elseif($firstArgument === "otherValue"){
|
||||
$secondArgument = function(){
|
||||
$this->examplePrivateVariable = [
|
||||
0 => "value1",
|
||||
1 => "value2",
|
||||
2 => "value3",
|
||||
3 => "value4",
|
||||
4 => "value5",
|
||||
5 => "value6",
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public function doStuff(string $stuff) : string{
|
||||
return $stuff;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<!-- TODO: RFC and voting on the forums instead -->
|
||||
### RFC and Voting
|
||||
* These are big Pull Requests or contributions that change important behavior.
|
||||
* RFCs will be tagged with the *PR: RFC* label
|
||||
* A vote will be held once the RFC is ready. All users can vote commenting on the Pull Request
|
||||
* Comments MUST use "Yes" or "No" on the FIRST sentence to signify the vote, except when they don't want it to be counted.
|
||||
* If your comment is a voting comment, specify the reason of your vote or it won't be counted.
|
||||
* After voting has been closed, no further votes will be counted.
|
||||
* An RFC will be rejected if less than 50% + 1 (simple majority) has voted Yes.
|
||||
* If the RFC is approved, Team Members have the final word on its implementation or rejection.
|
||||
* RFCs with complex voting options will specify the vote percentage or other details.
|
39
PocketMine-MP.php
Normal file
39
PocketMine-MP.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/***REM_START***/
|
||||
require_once(dirname(__FILE__)."/src/config.php");
|
||||
require_once(FILE_PATH."/src/functions.php");
|
||||
require_once(FILE_PATH."/src/dependencies.php");
|
||||
/***REM_END***/
|
||||
|
||||
$server = new ServerAPI();
|
||||
$server->run();
|
||||
|
||||
|
||||
kill(getmypid()); //Fix for segfault
|
72
README.md
72
README.md
@ -1,53 +1,45 @@
|
||||
# [](https://pmmp.io)
|
||||

|
||||
|
||||
__A highly customisable, open source server software for Minecraft: Bedrock Edition written in PHP__
|
||||
# PocketMine-MP [](https://travis-ci.org/shoghicp/PocketMine-MP)
|
||||
|
||||
[](https://travis-ci.org/pmmp/PocketMine-MP)
|
||||
```
|
||||
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.
|
||||
|
||||
### Setup, help & support, FAQs
|
||||
Head over to the [documentation site](http://pmmp.readthedocs.org/).
|
||||
If you don't find what you're looking for there, [talk to a human](#discussion). Please do not use our issue tracker for support requests.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
### Discussion
|
||||
- [Forums](https://forums.pmmp.io/)
|
||||
- [Community Discord](https://discord.gg/bge7dYQ)
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
```
|
||||
|
||||
### Plugins
|
||||
There are a very wide range of already-written plugins available which you can use to customise your server. Check out [Poggit](https://poggit.pmmp.io), or just search GitHub.
|
||||
__PocketMine-MP is a Server for Minecraft Pocket Edition__. It has a Plugin API that enables a developer to extend it and add new features, or change default ones.
|
||||
|
||||
### For developers
|
||||
* [Latest API documentation](https://jenkins.pmmp.io/job/PocketMine-MP-doc/doxygen/) - Doxygen documentation generated from development
|
||||
* [DevTools](https://github.com/pmmp/PocketMine-DevTools/) - Development tools plugin for creating plugins
|
||||
* [ExamplePlugin](https://github.com/pmmp/ExamplePlugin/) - Example plugin demonstrating some basic API features
|
||||
The entire server is done in PHP, and has been tested, profiled and optimized to run smoothly.
|
||||
|
||||
### Can I contribute?
|
||||
Yes you can! Contributions are welcomed provided that they comply with our [Contributing Guidelines](CONTRIBUTING.md). Please ensure you read the relevant sections of the guidelines carefully before making a Pull Request or opening an Issue.
|
||||
### [Homepage](http://www.pocketmine.net/)
|
||||
|
||||
### Where can I get the latest .phar?
|
||||
- Latest release builds can be found in our [GitHub releases](https://github.com/pmmp/PocketMine-MP/releases).
|
||||
- Latest bleeding-edge development builds (and other builds in the build job channels) can be found on our [Jenkins server](https://jenkins.pmmp.io/).
|
||||
### [FAQ: Frequently Asked Questions](https://github.com/shoghicp/PocketMine-MP/wiki/Frequently-Asked-Questions)
|
||||
|
||||
**Note: Please avoid development builds unless there is no other alternative for what you need.** Development builds are subject to changes at any time without notice, and it is likely that your server or plugins might break without warning.
|
||||
### [Help Page](http://www.pocketmine.net/help.php)
|
||||
|
||||
### Donate
|
||||
Donations help support the development of the project and pay for our expenses.
|
||||
- Bitcoin Cash (BCH): `qz9p8dqkv0r7aahdatu5uewqfkvstrglv58f8yle07`
|
||||
- Bitcoin (BTC): `1PVAyDJ2g7kcjCxAC3C89oxpV2ZYcLad8T`
|
||||
- [Patreon](https://www.patreon.com/pocketminemp)
|
||||
### [Twitter @PocketMine](https://twitter.com/PocketMine)
|
||||
|
||||
## Licensing information
|
||||
## IRC #mcpedevs @ irc.freenode.net
|
||||
* [WebIRC](http://webchat.freenode.net?channels=mcpedevs&uio=d4)
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pmmp/PocketMine are not affiliated with Mojang. All brands and trademarks belong to their respective owners. PocketMine-MP is not a Mojang-approved software, nor is it associated with Mojang.
|
||||
## Third-party Libraries Used
|
||||
* __[PHP Sockets](http://php.net/manual/en/book.sockets.php)__
|
||||
* __[PHP SQLite3](http://php.net/manual/en/book.sqlite3.php)__
|
||||
* __[cURL](http://curl.haxx.se/)__: cURL is a command line tool for transferring data with URL syntax
|
||||
* __[GMP](http://gmplib.org/)__: Arithmetic without limitations
|
||||
* __[Zlib](http://www.zlib.net/)__: A Massively Spiffy Yet Delicately Unobtrusive Compression Library
|
||||
* __[PHP pthreads](https://github.com/krakjoe/pthreads)__ by _[krakjoe](https://github.com/krakjoe)_: Threading for PHP - Share Nothing, Do Everything.
|
||||
* __[PHP NBT](https://github.com/TheFrozenFire/PHP-NBT-Decoder-Encoder/blob/master/nbt.class.php)__ by _[TheFrozenFire](https://github.com/TheFrozenFire)_: Class for reading in NBT-format files (modified to handle Little-Endian files).
|
||||
* __[Spyc](https://github.com/mustangostang/spyc/blob/master/Spyc.php)__ by _[Vlad Andersen](https://github.com/mustangostang)_: A simple YAML loader/dumper class for PHP.
|
||||
* __[ANSICON](https://github.com/adoxa/ansicon)__ by _[Jason Hood](https://github.com/adoxa)_: Process ANSI escape sequences for Windows console programs.
|
||||
|
176
compile_php.sh
Normal file
176
compile_php.sh
Normal file
@ -0,0 +1,176 @@
|
||||
#!/bin/bash
|
||||
COMPILER_VERSION="0.10"
|
||||
|
||||
PHP_VERSION="5.4.13"
|
||||
ZEND_VM="GOTO"
|
||||
|
||||
ZLIB_VERSION="1.2.8"
|
||||
GMP_VERSION="5.1.1"
|
||||
PTHREADS_VERSION="0d5df071231478ff3b1982eb2b0d96cc24e39d9a"
|
||||
CURL_VERSION="curl-7_29_0"
|
||||
#READLINE_VERSION="6.2"
|
||||
|
||||
echo "[PocketMine] PHP installer and compiler for Linux & Mac - by @shoghicp v$COMPILER_VERSION"
|
||||
DIR=`pwd`
|
||||
date > "$DIR/install.log" 2>&1
|
||||
uname -a >> "$DIR/install.log" 2>&1
|
||||
echo "[INFO] Checking dependecies"
|
||||
type make >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"make\""; exit 1; }
|
||||
type autoconf >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"autoconf\""; exit 1; }
|
||||
type automake >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"automake\""; exit 1; }
|
||||
type libtool >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"libtool\""; exit 1; }
|
||||
type gcc >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"gcc\""; exit 1; }
|
||||
type m4 >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"m4\""; exit 1; }
|
||||
|
||||
rm -r -f install_data/ >> "$DIR/install.log" 2>&1
|
||||
rm -r -f php5/ >> "$DIR/install.log" 2>&1
|
||||
mkdir -m 0777 install_data >> "$DIR/install.log" 2>&1
|
||||
mkdir -m 0777 php5 >> "$DIR/install.log" 2>&1
|
||||
cd install_data
|
||||
set -e
|
||||
|
||||
#PHP 5
|
||||
echo -n "[PHP] downloading $PHP_VERSION..."
|
||||
wget http://php.net/get/php-$PHP_VERSION.tar.gz/from/this/mirror -q -O - | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv php-$PHP_VERSION php
|
||||
echo " done!"
|
||||
|
||||
#zlib
|
||||
echo -n "[zlib] downloading $ZLIB_VERSION..."
|
||||
wget http://zlib.net/zlib-$ZLIB_VERSION.tar.gz -q -O - | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv zlib-$ZLIB_VERSION zlib
|
||||
echo -n " checking..."
|
||||
cd zlib
|
||||
./configure --prefix="$DIR/install_data/php/ext/zlib" \
|
||||
--static >> "$DIR/install.log" 2>&1
|
||||
echo -n " compiling..."
|
||||
make >> "$DIR/install.log" 2>&1
|
||||
echo -n " installing..."
|
||||
make install >> "$DIR/install.log" 2>&1
|
||||
echo -n " cleaning..."
|
||||
cd ..
|
||||
rm -r -f ./zlib
|
||||
echo " done!"
|
||||
|
||||
#Readline
|
||||
#echo -n "[Readline] downloading $READLINE_VERSION..."
|
||||
#wget ftp://ftp.cwru.edu/pub/bash/readline-$READLINE_VERSION.tar.gz -q -O - | tar -xz >> "$DIR/install.log" 2>&1
|
||||
#mv readline-$READLINE_VERSION readline
|
||||
#echo -n " checking..."
|
||||
#cd readline
|
||||
#./configure --prefix="$DIR/install_data/php/ext/readline" \
|
||||
#--disable-shared >> "$DIR/install.log" 2>&1
|
||||
#echo -n " compiling..."
|
||||
#make >> "$DIR/install.log" 2>&1
|
||||
#echo -n " installing..."
|
||||
#make install >> "$DIR/install.log" 2>&1
|
||||
#echo -n " cleaning..."
|
||||
#cd ..
|
||||
#rm -r -f ./readine
|
||||
#echo " done!"
|
||||
|
||||
#--with-readline=$DIR/install_data/php/ext/readline
|
||||
|
||||
#GMP
|
||||
echo -n "[GMP] downloading $GMP_VERSION..."
|
||||
wget ftp://ftp.gmplib.org/pub/gmp-$GMP_VERSION/gmp-$GMP_VERSION.tar.bz2 -q -O - | tar -xj >> "$DIR/install.log" 2>&1
|
||||
mv gmp-$GMP_VERSION gmp
|
||||
echo -n " checking..."
|
||||
cd gmp
|
||||
./configure --prefix="$DIR/install_data/php/ext/gmp" \
|
||||
--disable-assembly \
|
||||
--disable-shared >> "$DIR/install.log" 2>&1
|
||||
echo -n " compiling..."
|
||||
make >> "$DIR/install.log" 2>&1
|
||||
echo -n " installing..."
|
||||
make install >> "$DIR/install.log" 2>&1
|
||||
echo -n " cleaning..."
|
||||
cd ..
|
||||
rm -r -f ./gmp
|
||||
echo " done!"
|
||||
|
||||
|
||||
echo -n "[cURL] downloading $CURL_VERSION..."
|
||||
wget https://github.com/bagder/curl/archive/$CURL_VERSION.tar.gz --no-check-certificate -q -O - | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv curl-$CURL_VERSION curl
|
||||
echo -n " checking..."
|
||||
cd curl
|
||||
./buildconf >> "$DIR/install.log" 2>&1
|
||||
./configure --prefix="$DIR/install_data/php/ext/curl" \
|
||||
--disable-shared >> "$DIR/install.log" 2>&1
|
||||
echo -n " compiling..."
|
||||
make >> "$DIR/install.log" 2>&1
|
||||
echo -n " installing..."
|
||||
make install >> "$DIR/install.log" 2>&1
|
||||
echo -n " cleaning..."
|
||||
cd ..
|
||||
rm -r -f ./curl
|
||||
echo " done!"
|
||||
|
||||
#pthreads
|
||||
echo -n "[PHP pthreads] downloading $PTHREADS_VERSION..."
|
||||
wget https://github.com/krakjoe/pthreads/archive/$PTHREADS_VERSION.tar.gz --no-check-certificate -q -O - | tar -zx >> "$DIR/install.log" 2>&1
|
||||
mv pthreads-$PTHREADS_VERSION "$DIR/install_data/php/ext/pthreads"
|
||||
echo " done!"
|
||||
|
||||
echo -n "[PHP]"
|
||||
set +e
|
||||
if which free >/dev/null; then
|
||||
MAX_MEMORY=$(free -m | awk '/^Mem:/{print $2}')
|
||||
else
|
||||
MAX_MEMORY=$(top -l 1 | grep PhysMem: | awk '{print $10}' | tr -d 'a-zA-Z')
|
||||
fi
|
||||
if [ $MAX_MEMORY -gt 2048 ]
|
||||
then
|
||||
echo -n " enabling optimizations..."
|
||||
OPTIMIZATION="--enable-inline-optimization "
|
||||
else
|
||||
OPTIMIZATION=""
|
||||
fi
|
||||
set -e
|
||||
echo -n " checking..."
|
||||
cd php
|
||||
rm -rf ./aclocal.m4 >> "$DIR/install.log" 2>&1
|
||||
rm -rf ./autom4te.cache/ >> "$DIR/install.log" 2>&1
|
||||
rm -f ./configure >> "$DIR/install.log" 2>&1
|
||||
./buildconf --force >> "$DIR/install.log" 2>&1
|
||||
./configure $OPTIMIZATION--prefix="$DIR/php5" \
|
||||
--exec-prefix="$DIR/php5" \
|
||||
--enable-embedded-mysqli \
|
||||
--enable-bcmath \
|
||||
--with-gmp="$DIR/install_data/php/ext/gmp" \
|
||||
--with-curl="$DIR/install_data/php/ext/curl" \
|
||||
--with-zlib="$DIR/install_data/php/ext/zlib" \
|
||||
--disable-libxml \
|
||||
--disable-xml \
|
||||
--disable-dom \
|
||||
--disable-simplexml \
|
||||
--disable-xmlreader \
|
||||
--disable-xmlwriter \
|
||||
--without-pear \
|
||||
--disable-cgi \
|
||||
--disable-session \
|
||||
--enable-ctype \
|
||||
--without-iconv \
|
||||
--without-pdo-sqlite \
|
||||
--enable-sockets \
|
||||
--enable-shared=no \
|
||||
--enable-static=yes \
|
||||
--enable-pcntl \
|
||||
--enable-pthreads \
|
||||
--enable-maintainer-zts \
|
||||
--enable-zend-signals \
|
||||
--with-zend-vm=$ZEND_VM \
|
||||
--enable-cli >> "$DIR/install.log" 2>&1
|
||||
echo -n " compiling..."
|
||||
make >> "$DIR/install.log" 2>&1
|
||||
echo -n " installing..."
|
||||
make install >> "$DIR/install.log" 2>&1
|
||||
echo " done!"
|
||||
cd "$DIR"
|
||||
echo -n "[INFO] Cleaning up..."
|
||||
rm -r -f install_data/ >> "$DIR/install.log" 2>&1
|
||||
date >> "$DIR/install.log" 2>&1
|
||||
echo " done!"
|
||||
echo "[PocketMine] You should start the server now using \"./start.sh\""
|
||||
echo "[PocketMine] If it doesn't works, please send the \"install.log\" file to the Bug Tracker"
|
@ -1,72 +0,0 @@
|
||||
{
|
||||
"name": "pocketmine/pocketmine-mp",
|
||||
"description": "A server software for Minecraft: Pocket Edition written in PHP",
|
||||
"type": "project",
|
||||
"homepage": "https://pmmp.io",
|
||||
"license": "LGPL-3.0",
|
||||
"require": {
|
||||
"php": ">=7.2.0",
|
||||
"php-64bit": "*",
|
||||
"ext-bcmath": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-ctype": "*",
|
||||
"ext-date": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pthreads": ">=3.1.7dev",
|
||||
"ext-reflection": "*",
|
||||
"ext-sockets": "*",
|
||||
"ext-spl": "*",
|
||||
"ext-yaml": ">=2.0.0",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": ">=1.2.11",
|
||||
"pocketmine/raklib": "^0.12.0",
|
||||
"pocketmine/spl": "^0.3.0",
|
||||
"pocketmine/binaryutils": "^0.1.0",
|
||||
"pocketmine/nbt": "^0.2.6",
|
||||
"pocketmine/math": "^0.2.0",
|
||||
"pocketmine/snooze": "^0.1.0",
|
||||
"daverandom/callback-validator": "dev-master",
|
||||
"adhocore/json-comment": "^0.0.7"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"": ["src"]
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"pocketmine\\": "tests/phpunit/"
|
||||
}
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/RakLib"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/SPL"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/BinaryUtils"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/NBT"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/Math"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/Snooze"
|
||||
}
|
||||
]
|
||||
}
|
341
composer.lock
generated
341
composer.lock
generated
@ -1,341 +0,0 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2f5313e4ebd7b62c785cf683b27464b4",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
"version": "v0.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/adhocore/php-json-comment.git",
|
||||
"reference": "135356c7e7336ef59924f1d921c770045f937a76"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/adhocore/php-json-comment/zipball/135356c7e7336ef59924f1d921c770045f937a76",
|
||||
"reference": "135356c7e7336ef59924f1d921c770045f937a76",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Ahc\\Json\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jitendra Adhikari",
|
||||
"email": "jiten.adhikary@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Lightweight JSON comment stripper library for PHP",
|
||||
"keywords": [
|
||||
"comment",
|
||||
"json",
|
||||
"strip-comment"
|
||||
],
|
||||
"time": "2018-08-01T12:27:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "daverandom/callback-validator",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DaveRandom/CallbackValidator.git",
|
||||
"reference": "d87a08cddbc6099816ed01e50ce25cdfc43b542f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/DaveRandom/CallbackValidator/zipball/d87a08cddbc6099816ed01e50ce25cdfc43b542f",
|
||||
"reference": "d87a08cddbc6099816ed01e50ce25cdfc43b542f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-reflection": "*",
|
||||
"php": ">=7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DaveRandom\\CallbackValidator\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Chris Wright",
|
||||
"email": "cw@daverandom.com"
|
||||
}
|
||||
],
|
||||
"description": "Tools for validating callback signatures",
|
||||
"time": "2017-04-03T15:22:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/binaryutils",
|
||||
"version": "0.1.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BinaryUtils.git",
|
||||
"reference": "33f511715d22418c03368b49b45a6c25d6b33806"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/33f511715d22418c03368b49b45a6c25d6b33806",
|
||||
"reference": "33f511715d22418c03368b49b45a6c25d6b33806",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"php-64bit": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"pocketmine\\utils\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"LGPL-3.0"
|
||||
],
|
||||
"description": "Classes and methods for conveniently handling binary data",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/BinaryUtils/tree/0.1.8",
|
||||
"issues": "https://github.com/pmmp/BinaryUtils/issues"
|
||||
},
|
||||
"time": "2019-01-16T17:31:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/math",
|
||||
"version": "0.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Math.git",
|
||||
"reference": "b755d3fb7025c4ddb7d9d6df0ba7e0b65125e51c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Math/zipball/b755d3fb7025c4ddb7d9d6df0ba7e0b65125e51c",
|
||||
"reference": "b755d3fb7025c4ddb7d9d6df0ba7e0b65125e51c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.0",
|
||||
"php-64bit": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"pocketmine\\math\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"LGPL-3.0"
|
||||
],
|
||||
"description": "PHP library containing math related code used in PocketMine-MP",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/Math/tree/0.2.2",
|
||||
"issues": "https://github.com/pmmp/Math/issues"
|
||||
},
|
||||
"time": "2019-01-04T15:42:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/nbt",
|
||||
"version": "0.2.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/NBT.git",
|
||||
"reference": "2f176c9f2fd9b31db8bc2ada2f38990157ec8f1a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/NBT/zipball/2f176c9f2fd9b31db8bc2ada2f38990157ec8f1a",
|
||||
"reference": "2f176c9f2fd9b31db8bc2ada2f38990157ec8f1a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-zlib": "*",
|
||||
"php": ">=7.2.0",
|
||||
"php-64bit": "*",
|
||||
"pocketmine/binaryutils": "^0.1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"pocketmine\\nbt\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"pocketmine\\nbt\\": "tests/phpunit/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"LGPL-3.0"
|
||||
],
|
||||
"description": "PHP library for working with Named Binary Tags",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/NBT/tree/0.2.7",
|
||||
"issues": "https://github.com/pmmp/NBT/issues"
|
||||
},
|
||||
"time": "2019-03-29T19:39:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/raklib",
|
||||
"version": "0.12.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/RakLib.git",
|
||||
"reference": "9df7dbcdafeb29403af6a7fa22c8785f758a1145"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/9df7dbcdafeb29403af6a7fa22c8785f758a1145",
|
||||
"reference": "9df7dbcdafeb29403af6a7fa22c8785f758a1145",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-bcmath": "*",
|
||||
"ext-pthreads": ">=3.1.7dev",
|
||||
"ext-sockets": "*",
|
||||
"php": ">=7.2.0",
|
||||
"php-64bit": "*",
|
||||
"php-ipv6": "*",
|
||||
"pocketmine/binaryutils": "^0.1.0",
|
||||
"pocketmine/snooze": "^0.1.0",
|
||||
"pocketmine/spl": "^0.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"raklib\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"GPL-3.0"
|
||||
],
|
||||
"description": "A RakNet server implementation written in PHP",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/RakLib/tree/0.12.3",
|
||||
"issues": "https://github.com/pmmp/RakLib/issues"
|
||||
},
|
||||
"time": "2019-04-21T12:15:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/snooze",
|
||||
"version": "0.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Snooze.git",
|
||||
"reference": "b7bd231bdb75e69300cac89ccd515fc731c38c40"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/b7bd231bdb75e69300cac89ccd515fc731c38c40",
|
||||
"reference": "b7bd231bdb75e69300cac89ccd515fc731c38c40",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pthreads": ">=3.1.7dev",
|
||||
"php-64bit": ">=7.2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"pocketmine\\snooze\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"LGPL-3.0"
|
||||
],
|
||||
"description": "Thread notification management library for code using the pthreads extension",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/Snooze/tree/0.1.1",
|
||||
"issues": "https://github.com/pmmp/Snooze/issues"
|
||||
},
|
||||
"time": "2019-01-04T15:54:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/spl",
|
||||
"version": "0.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/SPL.git",
|
||||
"reference": "7fd53857cd000491ba69e8db865792a024dd2c49"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/SPL/zipball/7fd53857cd000491ba69e8db865792a024dd2c49",
|
||||
"reference": "7fd53857cd000491ba69e8db865792a024dd2c49",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"exclude-from-classmap": [
|
||||
"stubs"
|
||||
],
|
||||
"classmap": [
|
||||
"./"
|
||||
]
|
||||
},
|
||||
"license": [
|
||||
"LGPL-3.0"
|
||||
],
|
||||
"description": "Standard library files required by PocketMine-MP and related projects",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/SPL/tree/0.3.2"
|
||||
},
|
||||
"time": "2018-08-12T15:17:39+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"ext-pthreads": 20,
|
||||
"daverandom/callback-validator": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=7.2.0",
|
||||
"php-64bit": "*",
|
||||
"ext-bcmath": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-ctype": "*",
|
||||
"ext-date": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pthreads": ">=3.1.7dev",
|
||||
"ext-reflection": "*",
|
||||
"ext-sockets": "*",
|
||||
"ext-spl": "*",
|
||||
"ext-yaml": ">=2.0.0",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": ">=1.2.11"
|
||||
},
|
||||
"platform-dev": []
|
||||
}
|
2324
doxygen/doxygen.conf
2324
doxygen/doxygen.conf
File diff suppressed because it is too large
Load Diff
@ -1,10 +0,0 @@
|
||||
## PocketMine-MP API Documentation
|
||||
|
||||
This site contains auto-generated API documentation for PocketMine-MP (and dependencies which are not outsourced). Documentation here is regenerated for every release.
|
||||
|
||||
This site can be accessed via https://apidoc.pmmp.io.
|
||||
|
||||
### Additional developer resources
|
||||
- [DevTools](https://github.com/pmmp/PocketMine-DevTools/) - Development tools plugin for creating plugins
|
||||
- [ExamplePlugin](https://github.com/pmmp/ExamplePlugin/) - Example plugin demonstrating some basic API features
|
||||
- [DeveloperDocs](https://github.com/pmmp/DeveloperDocs/) - Reference, guides and specifications for the PocketMine-MP API
|
304
src/API/BanAPI.php
Normal file
304
src/API/BanAPI.php
Normal file
@ -0,0 +1,304 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class BanAPI{
|
||||
private $server;
|
||||
private $whitelist;
|
||||
private $banned;
|
||||
private $ops;
|
||||
private $bannedIPs;
|
||||
private $cmdWL = array();
|
||||
function __construct(PocketMinecraftServer $server){
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
public function init(){
|
||||
console("[INFO] Loading authentication lists...");
|
||||
$this->whitelist = new Config(DATA_PATH."white-list.txt", CONFIG_LIST);
|
||||
$this->bannedIPs = new Config(DATA_PATH."banned-ips.txt", CONFIG_LIST);
|
||||
$this->banned = new Config(DATA_PATH."banned.txt", CONFIG_LIST);
|
||||
$this->ops = new Config(DATA_PATH."ops.txt", CONFIG_LIST);
|
||||
$this->server->api->console->register("banip", "Manages IP Banning", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("ban", "Manages Bannning", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("kick", "Kicks a player", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("whitelist", "Manages White-listing", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("op", "Ops a player", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("deop", "De-ops a player", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("sudo", "Run a command as a player", array($this, "commandHandler"));
|
||||
$this->server->api->console->alias("ban-ip", "banip add");
|
||||
$this->server->api->console->alias("banlist", "ban list");
|
||||
$this->server->api->console->alias("pardon", "ban remove");
|
||||
$this->server->api->console->alias("pardon-ip", "banip remove");
|
||||
$this->server->addHandler("console.command", array($this, "permissionsCheck"), 1);
|
||||
$this->cmdWhitelist("help");
|
||||
}
|
||||
|
||||
public function cmdWhitelist($cmd){
|
||||
$this->cmdWhitelist[strtolower(trim($cmd))] = true;
|
||||
}
|
||||
|
||||
public function isOp($username){
|
||||
if($this->server->api->dhandle("op.check", $username) === true){
|
||||
return true;
|
||||
}elseif($this->ops->exists($username)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function permissionsCheck($data, $event){
|
||||
|
||||
if(isset($this->cmdWhitelist[$data["cmd"]])){
|
||||
return true;
|
||||
}
|
||||
|
||||
if($data["issuer"] instanceof Player){
|
||||
if($this->server->api->handle("console.check", $data) === true or $this->isOp($data["issuer"]->username)){
|
||||
return true;
|
||||
}
|
||||
}elseif($data["issuer"] === "console"){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "sudo":
|
||||
$target = strtolower(array_shift($params));
|
||||
$player = $this->server->api->player->get($target);
|
||||
if(!($player instanceof Player)){
|
||||
$output .= "Player not connected.\n";
|
||||
break;
|
||||
}
|
||||
$this->server->api->console->run(implode(" ", $params), $player);
|
||||
$output .= "Command ran as ".$player->username.".\n";
|
||||
break;
|
||||
case "op":
|
||||
$user = strtolower($params[0]);
|
||||
if($user == ""){
|
||||
break;
|
||||
}
|
||||
$this->ops->set($user);
|
||||
$this->ops->save();
|
||||
$output .= $user." is now op\n";
|
||||
$this->server->api->chat->sendTo(false, "You are now op.", $user);
|
||||
break;
|
||||
case "deop":
|
||||
$user = strtolower($params[0]);
|
||||
if($user == ""){
|
||||
break;
|
||||
}
|
||||
$this->ops->remove($user);
|
||||
$this->ops->save();
|
||||
$output .= $user." is not longer op\n";
|
||||
$this->server->api->chat->sendTo(false, "You are not longer op.", $user);
|
||||
break;
|
||||
case "kick":
|
||||
if(!isset($params[0])){
|
||||
$output .= "Usage: /kick <playername> [reason]\n";
|
||||
}else{
|
||||
$name = strtolower(array_shift($params));
|
||||
$player = $this->server->api->player->get($name);
|
||||
if($player === false){
|
||||
$output .= "Player \"".$name."\" does not exist\n";
|
||||
}else{
|
||||
$reason = implode(" ", $params);
|
||||
$reason = $reason == "" ? "No reason":$reason;
|
||||
$player->close("You have been kicked: ".$reason);
|
||||
if($issuer instanceof Player){
|
||||
$this->server->api->chat->broadcast($player->username." has been kicked by ".$issuer->username.": $reason\n");
|
||||
}else{
|
||||
$this->server->api->chat->broadcast($player->username." has been kicked: $reason\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "whitelist":
|
||||
$p = strtolower(array_shift($params));
|
||||
switch($p){
|
||||
case "remove":
|
||||
$user = strtolower($params[0]);
|
||||
$this->whitelist->remove($user);
|
||||
$this->whitelist->save();
|
||||
$output .= "Player \"$user\" removed from white-list\n";
|
||||
break;
|
||||
case "add":
|
||||
$user = strtolower($params[0]);
|
||||
$this->whitelist->set($user);
|
||||
$this->whitelist->save();
|
||||
$output .= "Player \"$user\" added to white-list\n";
|
||||
break;
|
||||
case "reload":
|
||||
$this->whitelist = new Config(DATA_PATH."white-list.txt", CONFIG_LIST);
|
||||
break;
|
||||
case "list":
|
||||
$output .= "White-list: ".implode(", ", $this->whitelist->getAll(true))."\n";
|
||||
break;
|
||||
case "on":
|
||||
case "true":
|
||||
case "1":
|
||||
$output .= "White-list turned on\n";
|
||||
$this->server->api->setProperty("white-list", true);
|
||||
break;
|
||||
case "off":
|
||||
case "false":
|
||||
case "0":
|
||||
$output .= "White-list turned off\n";
|
||||
$this->server->api->setProperty("white-list", false);
|
||||
break;
|
||||
default:
|
||||
$output .= "Usage: /whitelist <on | off | add | remove | reload | list> [username]\n";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "banip":
|
||||
$p = strtolower(array_shift($params));
|
||||
switch($p){
|
||||
case "pardon":
|
||||
case "remove":
|
||||
$ip = strtolower($params[0]);
|
||||
$this->bannedIPs->remove($ip);
|
||||
$this->bannedIPs->save();
|
||||
$output .= "IP \"$ip\" removed from ban list\n";
|
||||
break;
|
||||
case "add":
|
||||
case "ban":
|
||||
$ip = strtolower($params[0]);
|
||||
$this->bannedIPs->set($ip);
|
||||
$this->bannedIPs->save();
|
||||
$output .= "IP \"$ip\" added to ban list\n";
|
||||
break;
|
||||
case "reload":
|
||||
$this->bannedIPs = new Config(DATA_PATH."banned-ips.txt", CONFIG_LIST);
|
||||
break;
|
||||
case "list":
|
||||
$output .= "IP ban list: ".implode(", ", $this->bannedIPs->getAll(true))."\n";
|
||||
break;
|
||||
default:
|
||||
$output .= "Usage: /banip <add | remove | list | reload> [IP]\n";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "ban":
|
||||
$p = strtolower(array_shift($params));
|
||||
switch($p){
|
||||
case "pardon":
|
||||
case "remove":
|
||||
$user = strtolower($params[0]);
|
||||
$this->banned->remove($user);
|
||||
$this->banned->save();
|
||||
$output .= "Player \"$user\" removed from ban list\n";
|
||||
break;
|
||||
case "add":
|
||||
case "ban":
|
||||
$user = strtolower($params[0]);
|
||||
$this->banned->set($user);
|
||||
$this->banned->save();
|
||||
$player = $this->server->api->player->get($user);
|
||||
if($player !== false){
|
||||
$player->close("You have been banned");
|
||||
}
|
||||
if($issuer instanceof Player){
|
||||
$this->server->api->chat->broadcast($user." has been banned by ".$issuer->username."\n");
|
||||
}else{
|
||||
$this->server->api->chat->broadcast($user." has been banned\n");
|
||||
}
|
||||
$this->kick($user, "Banned");
|
||||
$output .= "Player \"$user\" added to ban list\n";
|
||||
break;
|
||||
case "reload":
|
||||
$this->banned = new Config(DATA_PATH."banned.txt", CONFIG_LIST);
|
||||
break;
|
||||
case "list":
|
||||
$output .= "Ban list: ".implode(", ", $this->banned->getAll(true))."\n";
|
||||
break;
|
||||
default:
|
||||
$output .= "Usage: /ban <add | remove | list | reload> [player]\n";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function ban($username){
|
||||
$this->commandHandler("ban", array("add", $username));
|
||||
}
|
||||
|
||||
public function pardon($username){
|
||||
$this->commandHandler("ban", array("pardon", $username));
|
||||
}
|
||||
|
||||
public function banIP($ip){
|
||||
$this->commandHandler("banip", array("add", $ip));
|
||||
}
|
||||
|
||||
public function pardonIP($ip){
|
||||
$this->commandHandler("banip", array("pardon", $ip));
|
||||
}
|
||||
|
||||
public function kick($username, $reason = "No Reason"){
|
||||
$this->commandHandler("kick", array($username, $reason));
|
||||
}
|
||||
|
||||
public function reload(){
|
||||
$this->commandHandler("ban", array("reload"));
|
||||
$this->commandHandler("banip", array("reload"));
|
||||
$this->commandHandler("whitelist", array("reload"));
|
||||
}
|
||||
|
||||
public function isIPBanned($ip){
|
||||
if($this->server->api->dhandle("api.ban.ip.check", $ip) === false){
|
||||
return true;
|
||||
}elseif($this->bannedIPs->exists($ip)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isBanned($username){
|
||||
$username = strtolower($username);
|
||||
if($this->server->api->dhandle("api.ban.check", $username) === false){
|
||||
return true;
|
||||
}elseif($this->banned->exists($username)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function inWhitelist($username){
|
||||
$username = strtolower($username);
|
||||
if($this->server->api->dhandle("api.ban.whitelist.check", $ip) === false){
|
||||
return true;
|
||||
}elseif($this->whitelist->exists($username)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
680
src/API/BlockAPI.php
Normal file
680
src/API/BlockAPI.php
Normal file
@ -0,0 +1,680 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
define("BLOCK_UPDATE_NORMAL", 0);
|
||||
define("BLOCK_UPDATE_RANDOM", 1);
|
||||
define("BLOCK_UPDATE_SCHEDULED", 2);
|
||||
define("BLOCK_UPDATE_WEAK", 3);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class BlockAPI{
|
||||
private $server;
|
||||
|
||||
public static function fromString($str, $multiple = false){
|
||||
if($multiple === true){
|
||||
$blocks = array();
|
||||
foreach(explode(",",$str) as $b){
|
||||
$blocks[] = BlockAPI::fromString($b, false);
|
||||
}
|
||||
return $blocks;
|
||||
}else{
|
||||
$b = explode(":", str_replace(" ", "_", trim($str)));
|
||||
if(!isset($b[1])){
|
||||
$meta = 0;
|
||||
}else{
|
||||
$meta = ((int) $b[1]) & 0xFFFF;
|
||||
}
|
||||
|
||||
if(defined(strtoupper($b[0]))){
|
||||
$item = BlockAPI::getItem(constant(strtoupper($b[0])), $meta);
|
||||
if($item->getID() === AIR and strtoupper($b[0]) !== "AIR"){
|
||||
$item = BlockAPI::getItem(((int) $b[0]) & 0xFFFF, $meta);
|
||||
}
|
||||
}else{
|
||||
$item = BlockAPI::getItem(((int) $b[0]) & 0xFFFF, $meta);
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get($id, $meta = 0, $v = false){
|
||||
$id = (int) $id;
|
||||
if(isset(Block::$class[$id])){
|
||||
$classname = Block::$class[$id];
|
||||
$b = new $classname($meta);
|
||||
}else{
|
||||
$b = new GenericBlock($id, $meta);
|
||||
}
|
||||
if($v instanceof Vector3){
|
||||
$b->position($v);
|
||||
}
|
||||
return $b;
|
||||
}
|
||||
|
||||
public static function getItem($id, $meta = 0, $count = 1){
|
||||
$id = (int) $id;
|
||||
if(isset(Item::$class[$id])){
|
||||
$classname = Item::$class[$id];
|
||||
$i = new $classname($meta, $count);
|
||||
}else{
|
||||
$i = new Item($id, $meta, $count);
|
||||
}
|
||||
return $i;
|
||||
}
|
||||
|
||||
public function setBlock(Vector3 $block, $id, $meta, $update = true, $tiles = false){
|
||||
if(($block instanceof Vector3) or (($block instanceof Block) and $block->inWorld === true)){
|
||||
$this->server->api->level->setBlock($block->x, $block->y, $block->z, (int) $id, (int) $meta, $update, $tiles);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getBlock($x, $y = 0, $z = 0){
|
||||
if($x instanceof Vector3){
|
||||
$y = $x->y;
|
||||
$z = $x->z;
|
||||
$x = $x->x;
|
||||
}
|
||||
$b = $this->server->api->level->getBlock($x, $y, $z);
|
||||
return BlockAPI::get($b[0], $b[1], new Vector3($b[2][0], $b[2][1], $b[2][2]));
|
||||
}
|
||||
|
||||
public function getBlockFace(Block $block, $face){
|
||||
return $this->getBlock($block->getSide($face));
|
||||
}
|
||||
|
||||
function __construct(PocketMinecraftServer $server){
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->server->addHandler("block.update", array($this, "updateBlockRemote"), 1);
|
||||
$this->server->api->console->register("give", "Give items to a player", array($this, "commandHandler"));
|
||||
}
|
||||
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "give":
|
||||
if(!isset($params[0]) or !isset($params[1])){
|
||||
$output .= "Usage: /give <username> <item> [amount] [damage]\n";
|
||||
break;
|
||||
}
|
||||
$username = $params[0];
|
||||
$item = BlockAPI::fromString($params[1]);
|
||||
|
||||
if(!isset($params[2])){
|
||||
$item->count = $item->getMaxStackSize();
|
||||
}else{
|
||||
$item->count = (int) $params[2];
|
||||
}
|
||||
|
||||
if(($player = $this->server->api->player->get($username)) !== false){
|
||||
$this->drop(new Vector3($player->entity->x - 0.5, $player->entity->y, $player->entity->z - 0.5), $item, true);
|
||||
$output .= "Giving ".$item->count." of ".$item->getName()." (".$item->getID().":".$item->getMetadata().") to ".$username."\n";
|
||||
}else{
|
||||
$output .= "Unknown player\n";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function cancelAction(Block $block, Player $player){
|
||||
$player->dataPacket(MC_UPDATE_BLOCK, array(
|
||||
"x" => $block->x,
|
||||
"y" => $block->y,
|
||||
"z" => $block->z,
|
||||
"block" => $block->getID(),
|
||||
"meta" => $block->getMetadata()
|
||||
));
|
||||
return false;
|
||||
}
|
||||
|
||||
public function playerBlockBreak(Player $player, Vector3 $vector){
|
||||
|
||||
$target = $this->getBlock($vector);
|
||||
$item = $player->equipment;
|
||||
|
||||
if($this->server->api->dhandle("player.block.touch", array("type" => "break", "player" => $player, "target" => $target, "item" => $item)) === false){
|
||||
return $this->cancelAction($target, $player);
|
||||
}
|
||||
|
||||
if(!$target->isBreakable($item, $player) or $player->gamemode === ADVENTURE or ($player->lastBreak + $target->getBreakTime($item, $player)) >= microtime(true)){
|
||||
return $this->cancelAction($target, $player);
|
||||
}
|
||||
|
||||
|
||||
if($this->server->api->dhandle("player.block.break", array("player" => $player, "target" => $target, "item" => $item)) !== false){
|
||||
$player->lastBreak = microtime(true);
|
||||
$drops = $target->getDrops($item, $player);
|
||||
$target->onBreak($this, $item, $player);
|
||||
}else{
|
||||
return $this->cancelAction($target, $player);
|
||||
}
|
||||
|
||||
|
||||
if($player->gamemode !== CREATIVE and count($drops) > 0){
|
||||
foreach($drops as $drop){
|
||||
$this->drop($target, BlockAPI::getItem($drop[0] & 0xFFFF, $drop[1] & 0xFFFF, $drop[2] & 0xFF));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function drop(Vector3 $pos, Item $item){
|
||||
if($item->getID() === AIR or $item->count <= 0){
|
||||
return;
|
||||
}
|
||||
$data = array(
|
||||
"x" => $pos->x + mt_rand(2, 8) / 10,
|
||||
"y" => $pos->y + 0.19,
|
||||
"z" => $pos->z + mt_rand(2, 8) / 10,
|
||||
"item" => $item,
|
||||
);
|
||||
if($this->server->api->handle("item.drop", $data) !== false){
|
||||
for($count = $item->count; $count > 0; ){
|
||||
$item->count = min($item->getMaxStackSize(), $count);
|
||||
$count -= $item->count;
|
||||
$server = ServerAPI::request();
|
||||
$e = $server->api->entity->add(ENTITY_ITEM, $item->getID(), $data);
|
||||
//$e->speedX = mt_rand(-10, 10) / 100;
|
||||
//$e->speedY = mt_rand(0, 5) / 100;
|
||||
//$e->speedZ = mt_rand(-10, 10) / 100;
|
||||
$server->api->entity->spawnToAll($e->eid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function playerBlockAction(Player $player, Vector3 $vector, $face, $fx, $fy, $fz){
|
||||
if($face < 0 or $face > 5){
|
||||
return false;
|
||||
}
|
||||
|
||||
$target = $this->getBlock($vector);
|
||||
$block = $this->getBlockFace($target, $face);
|
||||
$item = $player->equipment;
|
||||
|
||||
if($target->getID() === AIR){ //If no block exists
|
||||
$this->cancelAction($target, $player);
|
||||
return $this->cancelAction($block, $player);
|
||||
}
|
||||
|
||||
if($this->server->api->dhandle("player.block.touch", array("type" => "place", "player" => $player, "block" => $block, "target" => $target, "item" => $item)) === false){
|
||||
return $this->cancelAction($block, $player);
|
||||
}
|
||||
|
||||
if($target->isActivable === true){
|
||||
if($this->server->api->dhandle("player.block.activate", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) !== false and $target->onActivate($this, $item, $player) === true){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if($player->gamemode === ADVENTURE){ //Adventure mode!!
|
||||
return $this->cancelAction($block, $player);
|
||||
}
|
||||
|
||||
if($block->y > 127 or $block->y < 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($item->isActivable === true and $item->onActivate($this, $player, $block, $target, $face, $fx, $fy, $fz)){
|
||||
return $this->cancelAction($block, $player);
|
||||
}
|
||||
|
||||
if($item->isPlaceable()){
|
||||
$hand = $item->getBlock();
|
||||
}else{
|
||||
return $this->cancelAction($block, $player);
|
||||
}
|
||||
|
||||
if(!($block->isReplaceable === true or ($hand->getID() === SLAB and $block->getID() === SLAB))){
|
||||
return $this->cancelAction($block, $player);
|
||||
}
|
||||
|
||||
if($hand->isTransparent === false and $player->entity->inBlock($block->x, $block->y, $block->z)){
|
||||
return $this->cancelAction($block, $player); //Entity in block
|
||||
}
|
||||
|
||||
if($this->server->api->dhandle("player.block.place", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) === false){
|
||||
return $this->cancelAction($block, $player);
|
||||
}elseif($hand->place($this, $item, $player, $block, $target, $face, $fx, $fy, $fz) === false){
|
||||
return $this->cancelAction($block, $player);
|
||||
}
|
||||
if($hand->getID() === SIGN_POST or $hand->getID() === WALL_POST){
|
||||
$t = $this->server->api->tileentity->addSign($block->x, $block->y, $block->z);
|
||||
$t->data["creator"] = $player->username;
|
||||
}
|
||||
|
||||
if($this->server->gamemode === SURVIVAL or $this->server->gamemode === ADVENTURE){
|
||||
$player->removeItem($item->getID(), $item->getMetadata(), 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function blockScheduler($data){
|
||||
$this->updateBlock($data["x"], $data["y"], $data["z"], BLOCK_UPDATE_SCHEDULED);
|
||||
}
|
||||
|
||||
public function updateBlockRemote($data, $event){
|
||||
if($event !== "block.update"){
|
||||
return;
|
||||
}
|
||||
$this->updateBlock($data["x"], $data["y"], $data["z"], isset($data["type"]) ? $data["type"]:BLOCK_UPDATE_RANDOM);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function flowLavaOn($source, $face){
|
||||
$down = 0;
|
||||
if($face === BlockFace::BOTTOM){
|
||||
$level = 0;
|
||||
$down = 1;
|
||||
}else{
|
||||
$level = ($source[1] & 0x07) + 2;
|
||||
if($level > 0x07){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$spread = $this->server->api->level->getBlockFace($source, $face);
|
||||
if(($source[0] === 10 or $source[0] === 11) and $spread[0] === 10){
|
||||
if($level < ($spread[1] & 0x07)){
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $spread[2][0],
|
||||
"y" => $spread[2][1],
|
||||
"z" => $spread[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $spread[0], $level | $down, false);
|
||||
return true;
|
||||
}
|
||||
}elseif($spread[0] === 9 or $spread[0] === 8){
|
||||
if($source[0] === 11){
|
||||
$this->server->api->level->setBlock($source[2][0], $source[2][1], $source[2][2], 49, 0);
|
||||
}elseif($face === 0){
|
||||
$this->server->api->level->setBlock($source[2][0], $source[2][1], $source[2][2], 1, 0);
|
||||
}else{
|
||||
$this->server->api->level->setBlock($source[2][0], $source[2][1], $source[2][2], 4, 0);
|
||||
}
|
||||
return true;
|
||||
}elseif(isset(Material::$flowable[$spread[0]])){
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $spread[2][0],
|
||||
"y" => $spread[2][1],
|
||||
"z" => $spread[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 10, $level | $down, false);
|
||||
return true;
|
||||
}elseif(($source[1] & 0x08) === 0x08){
|
||||
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $source[0], $source[1] & 0x07, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function flowWaterOn($source, $face, &$spread = null){
|
||||
$down = 0;
|
||||
if($face === BlockFace::BOTTOM){
|
||||
$level = 0;
|
||||
$down = 1;
|
||||
}else{
|
||||
$level = ($source[1] & 0x07) + 1;
|
||||
if($level > 0x07){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$spread = $this->server->api->level->getBlockFace($source, $face);
|
||||
if(($source[0] === 8 or $source[0] === 9) and $spread[0] === 8){
|
||||
if($level < ($spread[1] & 0x07)){
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $spread[2][0],
|
||||
"y" => $spread[2][1],
|
||||
"z" => $spread[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $spread[0], $level | $down, false);
|
||||
return true;
|
||||
}
|
||||
}elseif($spread[0] === 11){
|
||||
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 49, 0, true);
|
||||
return true;
|
||||
}elseif($spread[0] === 10){
|
||||
if($face === 0 or ($spread[1] & 0x08) === 0){
|
||||
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 4, 0, true);
|
||||
return true;
|
||||
}
|
||||
}elseif(isset(Material::$flowable[$spread[0]])){
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $spread[2][0],
|
||||
"y" => $spread[2][1],
|
||||
"z" => $spread[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 8, $level | $down, false);
|
||||
return true;
|
||||
}elseif(($source[1] & 0x08) === 0x08){
|
||||
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $source[0], $source[1] & 0x07, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function updateBlock($x, $y, $z, $type = BLOCK_UPDATE_NORMAL){
|
||||
$block = $this->server->api->level->getBlock($x, $y, $z);
|
||||
$changed = false;
|
||||
|
||||
switch($block[0]){
|
||||
case 8:
|
||||
case 9:
|
||||
$faces = array();
|
||||
if(!$this->flowWaterOn($block, 0, $floor) or $block[0] === 9){
|
||||
$this->flowWaterOn($block, 2, $faces[0]);
|
||||
$this->flowWaterOn($block, 3, $faces[1]);
|
||||
$this->flowWaterOn($block, 4, $faces[2]);
|
||||
$this->flowWaterOn($block, 5, $faces[3]);
|
||||
}
|
||||
if($block[0] === 8){
|
||||
//Source creation
|
||||
if(!isset(Material::$flowable[$floor[0]])){
|
||||
$sources = 0;
|
||||
foreach($faces as $i => $b){
|
||||
if($b[0] === 9){
|
||||
++$sources;
|
||||
}
|
||||
}
|
||||
if($sources >= 2){
|
||||
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], 9, 0, false);
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$drained = true;
|
||||
$level = $block[1] & 0x07;
|
||||
$up = $this->server->api->level->getBlockFace($block, BlockFace::UP);
|
||||
if($up[0] === 8 or $up[0] === 9){
|
||||
$drained = false;
|
||||
}else{
|
||||
$b = $this->server->api->level->getBlockFace($block, BlockFace::NORTH);
|
||||
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
|
||||
$drained = false;
|
||||
}else{
|
||||
$b = $this->server->api->level->getBlockFace($block, BlockFace::SOUTH);
|
||||
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
|
||||
$drained = false;
|
||||
}else{
|
||||
$b = $this->server->api->level->getBlockFace($block, BlockFace::EAST);
|
||||
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
|
||||
$drained = false;
|
||||
}else{
|
||||
$b = $this->server->api->level->getBlockFace($block, BlockFace::WEST);
|
||||
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
|
||||
$drained = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($drained === true){
|
||||
++$level;
|
||||
if($level > 0x07){
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0] + 1,
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0] - 1,
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2] + 1,
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2] - 1,
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1] - 1,
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], 0, 0, false);
|
||||
}else{
|
||||
$block[1] = ($block[1] & 0x08) | $level;
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0] + 1,
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0] - 1,
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2] + 1,
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2] - 1,
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1] - 1,
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(10, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], $block[0], $block[1], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
case 11:
|
||||
if(!$this->flowLavaOn($block, 0) or $block[0] === 11){
|
||||
$this->flowLavaOn($block, 2);
|
||||
$this->flowLavaOn($block, 3);
|
||||
$this->flowLavaOn($block, 4);
|
||||
$this->flowLavaOn($block, 5);
|
||||
}
|
||||
if($block[0] === 10){
|
||||
$drained = true;
|
||||
$level = $block[1] & 0x07;
|
||||
$up = $this->server->api->level->getBlockFace($block, BlockFace::UP);
|
||||
if($up[0] === 10 or $up[0] === 11){
|
||||
$drained = false;
|
||||
}else{
|
||||
$b = $this->server->api->level->getBlockFace($block, BlockFace::NORTH);
|
||||
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
|
||||
$drained = false;
|
||||
}else{
|
||||
$b = $this->server->api->level->getBlockFace($block, BlockFace::SOUTH);
|
||||
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
|
||||
$drained = false;
|
||||
}else{
|
||||
$b = $this->server->api->level->getBlockFace($block, BlockFace::EAST);
|
||||
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
|
||||
$drained = false;
|
||||
}else{
|
||||
$b = $this->server->api->level->getBlockFace($block, BlockFace::WEST);
|
||||
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
|
||||
$drained = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($drained === true){
|
||||
++$level;
|
||||
if($level > 0x07){
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0] + 1,
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0] - 1,
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2] + 1,
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2] - 1,
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1] - 1,
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], 0, 0, false);
|
||||
}else{
|
||||
$block[1] = ($block[1] & 0x08) | $level;
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0] + 1,
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0] - 1,
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2] + 1,
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2] - 1,
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1] - 1,
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->schedule(20, array($this, "blockScheduler"), array(
|
||||
"x" => $block[2][0],
|
||||
"y" => $block[2][1],
|
||||
"z" => $block[2][2],
|
||||
"type" => BLOCK_UPDATE_NORMAL,
|
||||
));
|
||||
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], $block[0], $block[1], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 74:
|
||||
if($type === BLOCK_UPDATE_SCHEDULED or $type === BLOCK_UPDATE_RANDOM){
|
||||
$changed = true;
|
||||
$this->server->api->level->setBlock($x, $y, $z, 73, $block[1], false);
|
||||
$type = BLOCK_UPDATE_WEAK;
|
||||
}
|
||||
break;
|
||||
case 73:
|
||||
if($type === BLOCK_UPDATE_NORMAL){
|
||||
$changed = true;
|
||||
$this->server->api->level->setBlock($x, $y, $z, 74, $block[1], false);
|
||||
$this->server->schedule(mt_rand(40, 100), array($this, "blockScheduler"), array(
|
||||
"x" => $x,
|
||||
"y" => $y,
|
||||
"z" => $z,
|
||||
));
|
||||
$type = BLOCK_UPDATE_WEAK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if($type === BLOCK_TYPE_SCHEDULED){
|
||||
$type = BLOCK_UPDATE_WEAK;
|
||||
}
|
||||
if($changed === true){
|
||||
$this->updateBlocksAround($x, $y, $z, $type);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateBlocksAround($x, $y, $z, $type){
|
||||
$this->updateBlock($x + 1, $y, $z, $type);
|
||||
$this->updateBlock($x, $y + 1, $z, $type);
|
||||
$this->updateBlock($x, $y, $z + 1, $type);
|
||||
$this->updateBlock($x - 1, $y, $z, $type);
|
||||
$this->updateBlock($x, $y - 1, $z, $type);
|
||||
$this->updateBlock($x, $y, $z - 1, $type);
|
||||
}
|
||||
}
|
59
src/API/ChatAPI.php
Normal file
59
src/API/ChatAPI.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class ChatAPI{
|
||||
private $server;
|
||||
function __construct(PocketMinecraftServer $server){
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
public function init(){
|
||||
|
||||
}
|
||||
|
||||
public function broadcast($message){
|
||||
$this->send(false, $message);
|
||||
console("[CHAT] ".$message);
|
||||
}
|
||||
|
||||
public function sendTo($owner, $text, $player){
|
||||
$this->send($owner, $text, array($player));
|
||||
}
|
||||
|
||||
public function send($owner, $text, $whitelist = false, $blacklist = false){
|
||||
$message = "";
|
||||
if($owner !== false){
|
||||
if($owner instanceof Player){
|
||||
$message = "<".$owner->username."> ";
|
||||
}else{
|
||||
$message = "<".$owner."> ";
|
||||
}
|
||||
}
|
||||
$message .= $text;
|
||||
$this->server->handle("server.chat", new Container($message, $whitelist, $blacklist));
|
||||
}
|
||||
}
|
229
src/API/ConsoleAPI.php
Normal file
229
src/API/ConsoleAPI.php
Normal file
@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class ConsoleAPI{
|
||||
private $loop, $server, $event, $help, $cmds, $alias;
|
||||
function __construct(PocketMinecraftServer $server){
|
||||
$this->help = array();
|
||||
$this->cmds = array();
|
||||
$this->alias = array();
|
||||
$this->server = $server;
|
||||
$this->last = microtime(true);
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->event = $this->server->event("server.tick", array($this, "handle"));
|
||||
$this->loop = new ConsoleLoop;
|
||||
$this->loop->start();
|
||||
$this->register("help", "Show available commands", array($this, "defaultCommands"));
|
||||
$this->register("status", "Show server TPS and memory usage", array($this, "defaultCommands"));
|
||||
$this->alias("lag", "status");
|
||||
$this->register("difficulty", "Changes server difficulty", array($this, "defaultCommands"));
|
||||
$this->register("invisible", "Changes server visibility", array($this, "defaultCommands"));
|
||||
$this->register("say", "Broadcast a message", array($this, "defaultCommands"));
|
||||
$this->register("save-all", "Save pending changes to disk", array($this, "defaultCommands"));
|
||||
$this->register("stop", "Stops the server gracefully", array($this, "defaultCommands"));
|
||||
}
|
||||
|
||||
function __destruct(){
|
||||
$this->server->deleteEvent($this->event);
|
||||
$this->loop->stop = true;
|
||||
$this->loop->notify();
|
||||
$this->loop->join();
|
||||
}
|
||||
|
||||
public function defaultCommands($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "crash": //Crashes the server to generate an report
|
||||
$this->callNotDefinedMethodCrash();
|
||||
$this->server->api->server; //Access a private property
|
||||
callNotExistingFunction();
|
||||
break;
|
||||
case "invisible":
|
||||
$p = strtolower(array_shift($params));
|
||||
switch($p){
|
||||
case "on":
|
||||
case "true":
|
||||
case "1":
|
||||
$output .= "Server is invisible\n";
|
||||
$this->server->api->setProperty("invisible", true);
|
||||
break;
|
||||
case "off":
|
||||
case "false":
|
||||
case "0":
|
||||
$output .= "Server is visible\n";
|
||||
$this->server->api->setProperty("invisible", false);
|
||||
break;
|
||||
default:
|
||||
$output .= "Usage: /invisible <on | off>\n";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "status":
|
||||
case "lag":
|
||||
if(!($issuer instanceof Player) and $issuer === "console"){
|
||||
$this->server->debugInfo(true);
|
||||
}
|
||||
$info = $this->server->debugInfo();
|
||||
$output .= "TPS: ".$info["tps"].", Memory usage: ".$info["memory_usage"]." (Peak ".$info["memory_peak_usage"].")\n";
|
||||
break;
|
||||
case "update-done":
|
||||
$this->server->api->setProperty("last-update", time());
|
||||
break;
|
||||
case "stop":
|
||||
$this->loop->stop = true;
|
||||
$output .= "Stopping the server\n";
|
||||
$this->server->close();
|
||||
break;
|
||||
case "difficulty":
|
||||
$s = trim(array_shift($params));
|
||||
if($s == "" or (((int) $s) !== 0 and ((int) $s) !== 1)){
|
||||
$output .= "Usage: /difficulty <0 | 1>\n";
|
||||
break;
|
||||
}
|
||||
$this->server->api->setProperty("difficulty", (int) $s);
|
||||
$output .= "Difficulty changed to ".$this->server->difficulty."\n";
|
||||
loadConfig(true);
|
||||
break;
|
||||
case "say":
|
||||
$s = implode(" ", $params);
|
||||
if(trim($s) == ""){
|
||||
$output .= "Usage: /say <message>\n";
|
||||
break;
|
||||
}
|
||||
$this->server->api->chat->broadcast("[Server] ".$s);
|
||||
break;
|
||||
case "save-all":
|
||||
$this->server->save();
|
||||
break;
|
||||
|
||||
case "?":
|
||||
if($issuer !== "console"){
|
||||
break;
|
||||
}
|
||||
case "help":
|
||||
$max = ceil(count($this->help) / 5);
|
||||
$page = isset($params[0]) ? min($max - 1, max(0, intval($params[0]) - 1)):0;
|
||||
$output .= "- Showing help page ". ($page + 1) ." of $max (/help <page>) -\n";
|
||||
$current = 0;
|
||||
foreach($this->help as $c => $h){
|
||||
$curpage = (int) ($current / 5);
|
||||
if($curpage === $page){
|
||||
$output .= "/$c: ".$h."\n";
|
||||
}elseif($curpage > $page){
|
||||
break;
|
||||
}
|
||||
++$current;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$output .= "Command doesn't exist! Use /help\n";
|
||||
break;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function alias($alias, $cmd){
|
||||
$this->alias[strtolower(trim($alias))] = trim($cmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function register($cmd, $help, $callback){
|
||||
if(!is_callable($callback)){
|
||||
return false;
|
||||
}
|
||||
$cmd = strtolower(trim($cmd));
|
||||
$this->cmds[$cmd] = $callback;
|
||||
$this->help[$cmd] = $help;
|
||||
ksort($this->help, SORT_NATURAL | SORT_FLAG_CASE);
|
||||
}
|
||||
|
||||
public function run($line = "", $issuer = false, $alias = false){
|
||||
if($line != ""){
|
||||
$params = explode(" ", $line);
|
||||
$cmd = strtolower(array_shift($params));
|
||||
if(isset($this->alias[$cmd])){
|
||||
$this->run($this->alias[$cmd] . " " .implode(" ", $params), $issuer, $cmd);
|
||||
return;
|
||||
}
|
||||
if($issuer instanceof Player){
|
||||
console("[INFO] \"".$issuer->username."\" issued server command: $alias /$cmd ".implode(" ", $params));
|
||||
}else{
|
||||
console("[INFO] Issued server command: $alias /$cmd ".implode(" ", $params));
|
||||
}
|
||||
if($this->server->api->dhandle("console.command.".$cmd, array("cmd" => $cmd, "parameters" => $params, "issuer" => $issuer, "alias" => $alias)) === false
|
||||
or $this->server->api->dhandle("console.command", array("cmd" => $cmd, "parameters" => $params, "issuer" => $issuer, "alias" => $alias)) === false){
|
||||
$output = "You don't have permissions\n";
|
||||
}else{
|
||||
if(isset($this->cmds[$cmd]) and is_callable($this->cmds[$cmd])){
|
||||
$output = @call_user_func($this->cmds[$cmd], $cmd, $params, $issuer, $alias);
|
||||
}elseif($this->server->api->dhandle("console.command.unknown", array("cmd" => $cmd, "params" => $params, "issuer" => $issuer, "alias" => $alias)) !== false){
|
||||
$output = $this->defaultCommands($cmd, $params, $issuer, $alias);
|
||||
}
|
||||
}
|
||||
if($output != "" and ($issuer instanceof Player)){
|
||||
$issuer->sendChat(trim($output));
|
||||
}elseif($output != "" and $issuer === "console"){
|
||||
$mes = explode("\n", trim($output));
|
||||
foreach($mes as $m){
|
||||
console("[CMD] ".$m);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handle($time){
|
||||
if($this->loop->line !== false){
|
||||
$line = trim($this->loop->line);
|
||||
$this->loop->line = false;
|
||||
$this->run($line, "console");
|
||||
}else{
|
||||
$this->loop->notify();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ConsoleLoop extends Thread{
|
||||
public $line, $stop;
|
||||
public function __construct(){
|
||||
$this->line = false;
|
||||
$this->stop = false;
|
||||
}
|
||||
|
||||
public function run(){
|
||||
$fp = fopen("php://stdin", "r");
|
||||
while($this->stop === false and ($line = fgets($fp)) !== false){
|
||||
$this->line = $line;
|
||||
$this->wait();
|
||||
$this->line = false;
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
}
|
106
src/API/EntityAPI.php
Normal file
106
src/API/EntityAPI.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class EntityAPI{
|
||||
private $server;
|
||||
function __construct(PocketMinecraftServer $server){
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
public function get($eid){
|
||||
if(isset($this->server->entities[$eid])){
|
||||
return $this->server->entities[$eid];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function init(){
|
||||
|
||||
}
|
||||
|
||||
public function getAll(){
|
||||
return $this->server->entities;
|
||||
}
|
||||
|
||||
public function heal($eid, $heal = 1, $cause){
|
||||
$this->harm($eid, -$heal, $cause);
|
||||
}
|
||||
|
||||
public function harm($eid, $attack = 1, $cause, $force = false){
|
||||
$e = $this->get($eid);
|
||||
if($e === false or $e->dead === true){
|
||||
return false;
|
||||
}
|
||||
$e->setHealth($e->getHealth() - $attack, $cause, $force);
|
||||
}
|
||||
|
||||
public function add($class, $type = 0, $data = array()){
|
||||
$eid = $this->server->eidCnt++;
|
||||
$this->server->entities[$eid] = new Entity($this->server, $eid, $class, $type, $data);
|
||||
$this->server->handle("entity.add", $this->server->entities[$eid]);
|
||||
return $this->server->entities[$eid];
|
||||
}
|
||||
|
||||
public function spawnTo($eid, $player){
|
||||
$e = $this->get($eid);
|
||||
if($e === false){
|
||||
return false;
|
||||
}
|
||||
$e->spawn($player);
|
||||
}
|
||||
|
||||
public function spawnToAll($eid){
|
||||
$e = $this->get($eid);
|
||||
if($e === false){
|
||||
return false;
|
||||
}
|
||||
foreach($this->server->api->player->getAll() as $player){
|
||||
if($player->eid !== false and $player->eid !== $eid){
|
||||
$e->spawn($player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function spawnAll($player){
|
||||
foreach($this->getAll() as $e){
|
||||
$e->spawn($player);
|
||||
}
|
||||
}
|
||||
|
||||
public function remove($eid){
|
||||
if(isset($this->server->entities[$eid])){
|
||||
$entity = $this->server->entities[$eid];
|
||||
$this->server->entities[$eid] = null;
|
||||
unset($this->server->entities[$eid]);
|
||||
$entity->closed = true;
|
||||
$this->server->query("DELETE FROM entities WHERE EID = ".$entity->eid.";");
|
||||
$this->server->api->dhandle("entity.remove", $entity);
|
||||
$entity = null;
|
||||
unset($entity);
|
||||
}
|
||||
}
|
||||
}
|
145
src/API/LevelAPI.php
Normal file
145
src/API/LevelAPI.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class LevelAPI{
|
||||
private $server, $map;
|
||||
function __construct(PocketMinecraftServer $server){
|
||||
$this->server = $server;
|
||||
$this->map = $this->server->map;
|
||||
$this->heightMap = array_fill(0, 256, array());
|
||||
}
|
||||
|
||||
public function init(){
|
||||
|
||||
}
|
||||
|
||||
public function handle($data, $event){
|
||||
switch($event){
|
||||
}
|
||||
}
|
||||
|
||||
public function getSpawn(){
|
||||
return $this->server->spawn;
|
||||
}
|
||||
|
||||
public function getChunk($X, $Z){
|
||||
return $this->map->map[$X][$Z];
|
||||
}
|
||||
|
||||
public function getBlockFace($block, $face){
|
||||
$data = array("x" => $block[2][0], "y" => $block[2][1], "z" => $block[2][2]);
|
||||
BlockFace::setPosition($data, $face);
|
||||
return $this->getBlock($data["x"], $data["y"], $data["z"]);
|
||||
}
|
||||
|
||||
public function getBlock($x, $y, $z){
|
||||
$b = $this->map->getBlock($x, $y, $z);
|
||||
$b[2] = array($x, $y, $z);
|
||||
return $b;
|
||||
}
|
||||
|
||||
public function getFloor($x, $z){
|
||||
if(!isset($this->heightMap[$z][$x])){
|
||||
$this->heightMap[$z][$x] = $this->map->getFloor($x, $z);
|
||||
}
|
||||
return $this->heightMap[$z][$x];
|
||||
}
|
||||
|
||||
public function setBlock($x, $y, $z, $block, $meta = 0, $update = true, $tiles = false){
|
||||
if($x < 0 or $y < 0 or $z < 0){
|
||||
return false;
|
||||
}
|
||||
if($this->server->api->dhandle("block.change", array(
|
||||
"x" => $x,
|
||||
"y" => $y,
|
||||
"z" => $z,
|
||||
"block" => $block,
|
||||
"meta" => $meta,
|
||||
)) !== false){
|
||||
$this->map->setBlock($x, $y, $z, $block, $meta);
|
||||
$this->heightMap[$z][$x] = $this->map->getFloor($x, $z);
|
||||
if($update === true){
|
||||
$this->server->api->block->updateBlock($x, $y, $z, BLOCK_UPDATE_NORMAL);
|
||||
$this->server->api->block->updateBlocksAround($x, $y, $z, BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
if($tiles === true){
|
||||
if(($t = $this->server->api->tileentity->get($x, $y, $z)) !== false){
|
||||
$t[0]->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getOrderedChunks($X, $Z, $columnsPerPacket = 2){
|
||||
$columnsPerPacket = max(1, (int) $columnsPerPacket);
|
||||
$ordered = array();
|
||||
$i = 0;
|
||||
$cnt = 0;
|
||||
$ordered[$i] = "";
|
||||
for($z = 0; $z < 16; ++$z){
|
||||
for($x = 0; $x < 16; ++$x){
|
||||
if($cnt >= $columnsPerPacket){
|
||||
++$i;
|
||||
$ordered[$i] = str_repeat("\x00", $i * $columnsPerPacket);
|
||||
$cnt = 0;
|
||||
}
|
||||
$ordered[$i] .= "\xff";
|
||||
$block = $this->map->getChunkColumn($X, $Z, $x, $z, 0);
|
||||
$meta = $this->map->getChunkColumn($X, $Z, $x, $z, 1);
|
||||
for($k = 0; $k < 8; ++$k){
|
||||
$ordered[$i] .= substr($block, $k << 4, 16);
|
||||
$ordered[$i] .= substr($meta, $k << 3, 8);
|
||||
}
|
||||
++$cnt;
|
||||
}
|
||||
}
|
||||
return $ordered;
|
||||
}
|
||||
|
||||
public function getMiniChunk($X, $Z, $Y, $MTU){
|
||||
$ordered = array();
|
||||
$i = 0;
|
||||
$ordered[$i] = "";
|
||||
$cnt = 0;
|
||||
for($z = 0; $z < 16; ++$z){
|
||||
for($x = 0; $x < 16; ++$x){
|
||||
if((strlen($ordered[$i]) + 16 + 8 + 1) > $MTU){
|
||||
++$i;
|
||||
$ordered[$i] = str_repeat("\x00", $cnt);
|
||||
}
|
||||
$ordered[$i] .= chr(1 << $Y);
|
||||
$block = $this->map->getChunkColumn($X, $Z, $x, $z, 0);
|
||||
$meta = $this->map->getChunkColumn($X, $Z, $x, $z, 1);
|
||||
$ordered[$i] .= substr($block, $Y << 4, 16);
|
||||
$ordered[$i] .= substr($meta, $Y << 3, 8);
|
||||
++$cnt;
|
||||
}
|
||||
}
|
||||
return $ordered;
|
||||
}
|
||||
}
|
318
src/API/PlayerAPI.php
Normal file
318
src/API/PlayerAPI.php
Normal file
@ -0,0 +1,318 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class PlayerAPI{
|
||||
private $server;
|
||||
function __construct(PocketMinecraftServer $server){
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->server->addHandler("server.regeneration", array($this, "handle"));
|
||||
$this->server->addHandler("player.death", array($this, "handle"), 1);
|
||||
$this->server->api->console->register("list", "Shows connected player list", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("kill", "Kills a player", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("gamemode", "Changes the player gamemode", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("tppos", "Teleports a player to a position", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("tp", "Teleports a player to another player", array($this, "commandHandler"));
|
||||
$this->server->api->console->alias("suicide", "kill");
|
||||
}
|
||||
|
||||
public function handle($data, $event){
|
||||
switch($event){
|
||||
case "server.regeneration":
|
||||
$result = $this->server->query("SELECT EID FROM entities WHERE class = ".ENTITY_PLAYER." AND health < 20;");
|
||||
if($result !== true and $result !== false){
|
||||
while(($player = $result->fetchArray()) !== false){
|
||||
if(($player = $this->server->api->entity->get($player["EID"])) !== false){
|
||||
if($player->getHealth() <= 0){
|
||||
continue;
|
||||
}
|
||||
$player->setHealth(min(20, $player->getHealth() + $data), "regeneration");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case "player.death":
|
||||
$message = $data["name"];
|
||||
if(is_numeric($data["cause"]) and isset($this->entities[$data["cause"]])){
|
||||
$e = $this->api->entity->get($data["cause"]);
|
||||
switch($e->class){
|
||||
case ENTITY_PLAYER:
|
||||
$message .= " was killed by ".$e->name;
|
||||
break;
|
||||
default:
|
||||
$message .= " was killed";
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
switch($data["cause"]){
|
||||
case "cactus":
|
||||
$message .= " was pricked to death";
|
||||
break;
|
||||
case "lava":
|
||||
$message .= " tried to swim in lava";
|
||||
break;
|
||||
case "fire":
|
||||
$message .= " went up in flames";
|
||||
break;
|
||||
case "burning":
|
||||
$message .= " burned to death";
|
||||
break;
|
||||
case "suffocation":
|
||||
$message .= " suffocated in a wall";
|
||||
break;
|
||||
case "water":
|
||||
$message .= " drowned";
|
||||
break;
|
||||
case "void":
|
||||
$message .= " fell out of the world";
|
||||
break;
|
||||
case "fall":
|
||||
$message .= " hit the ground too hard";
|
||||
break;
|
||||
case "flying":
|
||||
$message .= " tried to fly up to the sky";
|
||||
break;
|
||||
default:
|
||||
$message .= " died";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->server->chat(false, $message);
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "gamemode":
|
||||
$gm = -1;
|
||||
$player = false;
|
||||
if(!isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
|
||||
$player = $issuer;
|
||||
$gm = (int) $params[1];
|
||||
}elseif(isset($params[1]) and isset($params[0])){
|
||||
$player = $this->server->api->player->get($params[0]);
|
||||
$gm = (int) $params[1];
|
||||
}
|
||||
if(!($player instanceof Player) or $gm < 0 or $gm > 2){
|
||||
$output .= "Usage: /gamemode [player] <0 | 1 | 2>\n";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if($player->setGamemode($gm)){
|
||||
$output .= "Gamemode of ".$player->username." changed to ".$player->getGamemode()."\n";
|
||||
}
|
||||
break;
|
||||
case "tp":
|
||||
if(!isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
|
||||
$name = $issuer->username;
|
||||
$target = $params[1];
|
||||
}elseif(isset($params[1]) and isset($params[0])){
|
||||
$name = $params[0];
|
||||
$target = $params[1];
|
||||
}else{
|
||||
$output .= "Usage: /tp [player] <target>\n";
|
||||
break;
|
||||
}
|
||||
if($this->teleport($name, $target)){
|
||||
$output .= "\"$name\" teleported to \"$target\"\n";
|
||||
}else{
|
||||
$output .= "Couldn't teleport\n";
|
||||
}
|
||||
break;
|
||||
case "tppos":
|
||||
if(!isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0]) and ($issuer instanceof Player)){
|
||||
$name = $issuer->username;
|
||||
$x = (float) $params[0];
|
||||
$y = (float) $params[1];
|
||||
$z = (float) $params[2];
|
||||
}elseif(isset($params[3]) and isset($params[2]) and isset($params[1]) and isset($params[0])){
|
||||
$name = $params[0];
|
||||
$x = (float) $params[1];
|
||||
$y = (float) $params[2];
|
||||
$z = (float) $params[3];
|
||||
}else{
|
||||
$output .= "Usage: /tp [player] <x> <y> <z>\n";
|
||||
break;
|
||||
}
|
||||
if($this->tppos($name, $x, $y, $z)){
|
||||
$output .= "\"$name\" teleported to ($x, $y, $z)\n";
|
||||
}else{
|
||||
$output .= "Couldn't teleport\n";
|
||||
}
|
||||
break;
|
||||
case "kill":
|
||||
case "suicide":
|
||||
if(!isset($params[0]) and ($issuer instanceof Player)){
|
||||
$player = $issuer;
|
||||
}else{
|
||||
$player = $this->get($params[0]);
|
||||
}
|
||||
if($player instanceof Player){
|
||||
$this->server->api->entity->harm($player->eid, 20, "console", true);
|
||||
}else{
|
||||
$output .= "Usage: /kill [player]\n";
|
||||
}
|
||||
break;
|
||||
case "list":
|
||||
$output .= "Player list:\n";
|
||||
foreach($this->server->clients as $c){
|
||||
$output .= $c->username." (".$c->ip.":".$c->port."), ClientID ".$c->clientID.", (".round($c->entity->x, 2).", ".round($c->entity->y, 2).", ".round($c->entity->z, 2).")\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function teleport($name, $target){
|
||||
$target = $this->get($target);
|
||||
if(($target instanceof Player) and ($target->entity instanceof Entity)){
|
||||
return $this->tppos($name, $target->entity->x, $target->entity->y, $target->entity->z);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function tppos($name, $x, $y, $z){
|
||||
$player = $this->get($name);
|
||||
if(($player instanceof Player) and ($player->entity instanceof Entity)){
|
||||
$player->teleport(new Vector3($x, $y, $z));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get($name){
|
||||
$CID = $this->server->query("SELECT ip,port FROM players WHERE name = '".$name."';", true);
|
||||
$CID = $this->server->clientID($CID["ip"], $CID["port"]);
|
||||
if(isset($this->server->clients[$CID])){
|
||||
return $this->server->clients[$CID];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getAll(){
|
||||
return $this->server->clients;
|
||||
}
|
||||
|
||||
public function getByEID($eid){
|
||||
$eid = (int) $eid;
|
||||
$CID = $this->server->query("SELECT ip,port FROM players WHERE EID = '".$eid."';", true);
|
||||
$CID = $this->server->clientID($CID["ip"], $CID["port"]);
|
||||
if(isset($this->server->clients[$CID])){
|
||||
return $this->server->clients[$CID];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getByClientID($clientID){
|
||||
$clientID = (int) $clientID;
|
||||
$CID = $this->server->query("SELECT ip,port FROM players WHERE clientID = '".$clientID."';", true);
|
||||
$CID = $this->server->clientID($CID["ip"], $CID["port"]);
|
||||
if(isset($this->server->clients[$CID])){
|
||||
return $this->server->clients[$CID];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function online(){
|
||||
$o = array();
|
||||
foreach($this->server->clients as $p){
|
||||
if($p->auth === true){
|
||||
$o[] = $p->username;
|
||||
}
|
||||
}
|
||||
return $o;
|
||||
}
|
||||
|
||||
public function add($CID){
|
||||
if(isset($this->server->clients[$CID])){
|
||||
$player = $this->server->clients[$CID];
|
||||
console("[INFO] Player \"\x1b[33m".$player->username."\x1b[0m\" connected from \x1b[36m".$player->ip.":".$player->port."\x1b[0m");
|
||||
$player->data = $this->getOffline($player->username);
|
||||
$player->gamemode = $player->data->get("gamemode");
|
||||
$this->server->query("INSERT OR REPLACE INTO players (clientID, ip, port, name) VALUES (".$player->clientID.", '".$player->ip."', ".$player->port.", '".$player->username."');");
|
||||
}
|
||||
}
|
||||
|
||||
public function remove($CID){
|
||||
if(isset($this->server->clients[$CID])){
|
||||
$player = $this->server->clients[$CID];
|
||||
$this->server->clients[$CID] = null;
|
||||
unset($this->server->clients[$CID]);
|
||||
$player->close();
|
||||
if($player->username != "" and ($player->data instanceof Config)){
|
||||
$this->saveOffline($player->data);
|
||||
}
|
||||
$this->server->query("DELETE FROM players WHERE name = '".$player->username."';");
|
||||
if($player->entity instanceof Entity){
|
||||
$player->entity->player = null;
|
||||
$player->entity = null;
|
||||
}
|
||||
$this->server->api->entity->remove($player->eid);
|
||||
$player = null;
|
||||
unset($player);
|
||||
}
|
||||
}
|
||||
|
||||
public function getOffline($name){
|
||||
$iname = strtolower($name);
|
||||
$default = array(
|
||||
"position" => array(
|
||||
"x" => $this->server->spawn["x"],
|
||||
"y" => $this->server->spawn["y"],
|
||||
"z" => $this->server->spawn["z"],
|
||||
),
|
||||
"inventory" => array_fill(0, 36, array(AIR, 0, 0)),
|
||||
"armor" => array_fill(0, 4, array(AIR, 0, 0)),
|
||||
"gamemode" => $this->server->gamemode,
|
||||
"health" => 20,
|
||||
"lastIP" => "",
|
||||
"lastID" => 0,
|
||||
);
|
||||
$data = new Config(DATA_PATH."players/".$iname.".yml", CONFIG_YAML, $default);
|
||||
if(!file_exists(DATA_PATH."players/".$iname.".yml")){
|
||||
console("[NOTICE] Player data not found for \"".$iname."\", creating new profile");
|
||||
$data->save();
|
||||
}
|
||||
if($this->server->gamemode === CREATIVE){
|
||||
$data->set("health", 20);
|
||||
}
|
||||
$this->server->handle("player.offline.get", $data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function saveOffline(Config $data){
|
||||
$this->server->handle("player.offline.save", $data);
|
||||
$data->save();
|
||||
}
|
||||
}
|
200
src/API/PluginAPI.php
Normal file
200
src/API/PluginAPI.php
Normal file
@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class PluginAPI extends stdClass{
|
||||
private $server;
|
||||
private $plugins = array();
|
||||
public function __construct(PocketMinecraftServer $server){
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
public function getList(){
|
||||
$list = array();
|
||||
foreach($this->plugins as $p){
|
||||
$list[] = $p[1];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function getInfo($className){
|
||||
$className = strtolower($className);
|
||||
if(!isset($this->plugins[$className])){
|
||||
return false;
|
||||
}
|
||||
$plugin = $this->plugins[$className];
|
||||
return array($plugin[1], get_class_methods($plugin[0]));
|
||||
}
|
||||
|
||||
public function load($file){
|
||||
if(strtolower(substr($file, -3)) === "pmf"){
|
||||
$pmf = new PMFPlugin($file);
|
||||
$info = $pmf->getPluginInfo();
|
||||
}else{
|
||||
$content = file_get_contents($file);
|
||||
$info = strstr($content, "*/", true);
|
||||
$content = substr(strstr($content, "*/"),2);
|
||||
if(preg_match_all('#([a-zA-Z0-9\-_]*)=([^\r\n]*)#u', $info, $matches) == 0){ //false or 0 matches
|
||||
console("[ERROR] [PluginAPI] Failed parsing of ".basename($file));
|
||||
return false;
|
||||
}
|
||||
$info = array();
|
||||
foreach($matches[1] as $k => $i){
|
||||
$v = $matches[2][$k];
|
||||
switch(strtolower($v)){
|
||||
case "on":
|
||||
case "true":
|
||||
case "yes":
|
||||
$v = true;
|
||||
break;
|
||||
case "off":
|
||||
case "false":
|
||||
case "no":
|
||||
$v = false;
|
||||
break;
|
||||
}
|
||||
$info[$i] = $v;
|
||||
}
|
||||
$info["code"] = $content;
|
||||
$info["class"] = trim(strtolower($info["class"]));
|
||||
}
|
||||
if(!isset($info["name"]) or !isset($info["version"]) or !isset($info["class"]) or !isset($info["author"])){
|
||||
console("[ERROR] [PluginAPI] Failed parsing of ".basename($file));
|
||||
return false;
|
||||
}
|
||||
console("[INFO] [PluginAPI] Loading plugin \"\x1b[32m".$info["name"]."\x1b[0m\" \x1b[35m".$info["version"]." #".intval($info["apiversion"])."\x1b[0m by \x1b[36m".$info["author"]."\x1b[0m");
|
||||
if(class_exists($info["class"])){
|
||||
console("[ERROR] [PluginAPI] Failed loading plugin: class exists");
|
||||
return false;
|
||||
}
|
||||
if(eval($info["code"]) === false or !class_exists($info["class"])){
|
||||
console("[ERROR] [PluginAPI] Failed loading plugin: evaluation error");
|
||||
return false;
|
||||
}
|
||||
|
||||
$className = $info["class"];
|
||||
if(isset($info["apiversion"]) and intval($info["apiversion"]) > CURRENT_API_VERSION){
|
||||
console("[ERROR] [PluginAPI] Plugin \"".$info["name"]."\" uses a newer API! It can crash or corrupt the server!");
|
||||
}elseif(!isset($info["apiversion"]) or intval($info["apiversion"]) < CURRENT_API_VERSION){
|
||||
console("[DEBUG] [PluginAPI] Plugin \"".$info["name"]."\" uses an old API", true, true, 2);
|
||||
}
|
||||
$object = new $className($this->server->api, false);
|
||||
if(!($object instanceof Plugin)){
|
||||
console("[ERROR] [PluginAPI] Plugin \"\x1b[36m".$info["name"]."\x1b[0m\" doesn't use the Plugin Interface");
|
||||
if(method_exists($object, "__destruct")){
|
||||
$object->__destruct();
|
||||
}
|
||||
$object = null;
|
||||
unset($object);
|
||||
}else{
|
||||
$this->plugins[$className] = array($object, $info);
|
||||
}
|
||||
}
|
||||
|
||||
public function get(Plugin $plugin){
|
||||
foreach($this->plugins as &$p){
|
||||
if($p[0] === $plugin){
|
||||
return $p;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function configPath(Plugin $plugin){
|
||||
$p = $this->get($plugin);
|
||||
if($p === false){
|
||||
return false;
|
||||
}
|
||||
$path = DATA_PATH."plugins/".$p[1]["name"]."/";
|
||||
$this->plugins[$p[1]["class"]][1]["path"] = $path;
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function createConfig(Plugin $plugin, $default = array()){
|
||||
$p = $this->get($plugin);
|
||||
if($p === false){
|
||||
return false;
|
||||
}
|
||||
$path = DATA_PATH."plugins/".$p[1]["name"]."/";
|
||||
@mkdir($path);
|
||||
$this->plugins[$p[1]["class"]][1]["path"] = $path;
|
||||
$cnf = new Config($path."config.yml", CONFIG_YAML, $default);
|
||||
$cnf->save();
|
||||
return $path;
|
||||
}
|
||||
|
||||
private function fillDefaults($default, &$yaml){
|
||||
foreach($default as $k => $v){
|
||||
if(is_array($v)){
|
||||
if(!isset($yaml[$k]) or !is_array($yaml[$k])){
|
||||
$yaml[$k] = array();
|
||||
}
|
||||
$this->fillDefaults($v, $yaml[$k]);
|
||||
}elseif(!isset($yaml[$k])){
|
||||
$yaml[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function readYAML($file){
|
||||
return Spyc::YAMLLoad(file_get_contents($file));
|
||||
}
|
||||
|
||||
public function writeYAML($file, $data){
|
||||
return file_put_contents($file, Spyc::YAMLDump($data));
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->server->event("server.start", array($this, "initAll"));
|
||||
$this->loadAll();
|
||||
}
|
||||
|
||||
public function loadAll(){
|
||||
console("[INFO] Loading Plugins...");
|
||||
$dir = dir(DATA_PATH."plugins/");
|
||||
while(false !== ($file = $dir->read())){
|
||||
if($file{0} !== "."){
|
||||
$ext = strtolower(substr($file, -3));
|
||||
if($ext === "php" or $ext === "pmf"){
|
||||
$this->load(DATA_PATH."plugins/" . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function initAll(){
|
||||
foreach($this->plugins as $p){
|
||||
$p[0]->init(); //ARGHHH!!! Plugin loading randomly fails!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface Plugin{
|
||||
public function __construct(ServerAPI $api, $server = false);
|
||||
public function init();
|
||||
public function __destruct();
|
||||
}
|
473
src/API/ServerAPI.php
Normal file
473
src/API/ServerAPI.php
Normal file
@ -0,0 +1,473 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class ServerAPI{
|
||||
var $restart = false;
|
||||
private static $serverRequest = false;
|
||||
private $server;
|
||||
private $config;
|
||||
private $apiList = array();
|
||||
|
||||
public static function request(){
|
||||
return self::$serverRequest;
|
||||
}
|
||||
|
||||
public function run(){
|
||||
$this->load();
|
||||
return $this->init();
|
||||
}
|
||||
|
||||
public function load(){
|
||||
@mkdir(DATA_PATH."logs/", 0777, true);
|
||||
@mkdir(DATA_PATH."players/", 0777);
|
||||
@mkdir(DATA_PATH."worlds/", 0777);
|
||||
@mkdir(DATA_PATH."plugins/", 0777);
|
||||
console("[INFO] Starting ServerAPI server handler...");
|
||||
file_put_contents(DATA_PATH."logs/packets.log", "");
|
||||
if(!file_exists(DATA_PATH."logs/test.bin.log") or md5_file(DATA_PATH."logs/test.bin.log") !== TEST_MD5){
|
||||
console("[NOTICE] Executing tests...");
|
||||
console("[INFO] OS: ".PHP_OS.", ".Utils::getOS());
|
||||
console("[INFO] uname -a: ".php_uname("a"));
|
||||
console("[INFO] PHP Version: ".phpversion());
|
||||
console("[INFO] Endianness: ".ENDIANNESS);
|
||||
$test = b"";
|
||||
$test .= Utils::writeLong("5567381823242127440");
|
||||
$test .= Utils::writeLong("2338608908624488819");
|
||||
$test .= Utils::writeLong("2333181766244987936");
|
||||
$test .= Utils::writeLong("2334669371112169504");
|
||||
$test .= Utils::writeShort(Utils::readShort("\xff\xff\xff\xff"));
|
||||
$test .= Utils::writeShort(Utils::readShort("\xef\xff\xff\xff"));
|
||||
$test .= Utils::writeInt(Utils::readInt("\xff\xff\xff\xff"));
|
||||
$test .= Utils::writeInt(1);
|
||||
$test .= Utils::writeInt(-1);
|
||||
$test .= Utils::writeFloat(Utils::readFloat("\xff\xff\xff\xff"));
|
||||
$test .= Utils::writeFloat(-1.584563155838E+29);
|
||||
$test .= Utils::writeFloat(1);
|
||||
$test .= Utils::writeLDouble(Utils::readLDouble("\xff\xff\xff\xff\xff\xff\xff\xff"));
|
||||
$test .= Utils::writeLong("-1152921504606846977");
|
||||
$test .= Utils::writeLong("-1152921504606846976");
|
||||
$str = new Java_String("TESTING\x00\n\r\t\xff");
|
||||
$test .= Utils::writeInt($str->hashCode());
|
||||
$test .= Utils::writeDataArray(array("a", "b", "c", "\xff\xff\xff\xff"));
|
||||
$test .= Utils::hexToStr("012334567890");
|
||||
file_put_contents(DATA_PATH."logs/test.bin.log", $test);
|
||||
$md5 = md5($test);
|
||||
console("[INFO] MD5 of test: ".$md5);
|
||||
if($md5 !== TEST_MD5){
|
||||
console("[ERROR] Test error, please send your console.log + test.bin.log to the Github repo");
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
console("[DEBUG] Loading server.properties...", true, true, 2);
|
||||
$this->config = new Config(DATA_PATH . "server.properties", CONFIG_PROPERTIES, array(
|
||||
"server-name" => "Minecraft Server",
|
||||
"description" => "Server made using PocketMine-MP",
|
||||
"motd" => "Welcome @username to this server!",
|
||||
"invisible" => false,
|
||||
"server-ip" => "0.0.0.0",
|
||||
"port" => 19132,
|
||||
"memory-limit" => "256M",
|
||||
"last-update" => false,
|
||||
"white-list" => false,
|
||||
"debug" => 1,
|
||||
"max-players" => 20,
|
||||
"server-type" => "normal",
|
||||
"time-per-second" => 20,
|
||||
"gamemode" => 1,
|
||||
"difficulty" => 1,
|
||||
"generator" => "",
|
||||
"generator-settings" => "",
|
||||
"level-name" => false,
|
||||
"server-id" => false,
|
||||
"upnp-forwarding" => false,
|
||||
"send-usage" => true,
|
||||
));
|
||||
$this->parseProperties();
|
||||
define("DEBUG", $this->getProperty("debug"));
|
||||
$this->server = new PocketMinecraftServer($this->getProperty("server-name"), $this->getProperty("gamemode"), false, $this->getProperty("port"), $this->getProperty("server-id"), $this->getProperty("server-ip"));
|
||||
self::$serverRequest = $this->server;
|
||||
$this->setProperty("server-id", $this->server->serverID);
|
||||
$this->server->api = $this;
|
||||
$gitsha1 = false;
|
||||
if(file_exists(FILE_PATH.".git/refs/heads/master")){ //Found Git information!
|
||||
$gitsha1 = trim(file_get_contents(FILE_PATH.".git/refs/heads/master"));
|
||||
console("[GIT] Commit \x1b[33m".$gitsha1);
|
||||
}
|
||||
|
||||
if($this->getProperty("upnp-forwarding") === true){
|
||||
console("[INFO] [UPnP] Trying to port forward...");
|
||||
UPnP_PortForward($this->getProperty("port"));
|
||||
}
|
||||
if(($ip = Utils::getIP()) !== false){
|
||||
console("[INFO] External IP: ".$ip);
|
||||
}
|
||||
if($this->getProperty("last-update") === false or ($this->getProperty("last-update") + 3600) < time()){
|
||||
console("[INFO] Checking for new server version");
|
||||
console("[INFO] Last check: \x1b[36m".date("Y-m-d H:i:s", $this->getProperty("last-update"))."\x1b[0m");
|
||||
$info = json_decode(Utils::curl_get("http://www.pocketmine.net/latest"), true);
|
||||
if($this->server->version->isDev()){
|
||||
if($info === false or !isset($info["development"])){
|
||||
console("[ERROR] PocketMine API error");
|
||||
}else{
|
||||
$last = $info["development"]["date"];
|
||||
if($last >= $this->getProperty("last-update") and $this->getProperty("last-update") !== false and $gitsha1 != $info["development"]["commit"]){
|
||||
console("[NOTICE] \x1b[33mA new DEVELOPMENT version of PocketMine-MP has been released");
|
||||
console("[NOTICE] \x1b[33mVersion \"".$info["development"]["version"]."\" [".substr($info["development"]["commit"], 0, 10)."]");
|
||||
console("[NOTICE] \x1b[36mIf you want to update, get the latest version at ".$info["development"]["download"]);
|
||||
console("[NOTICE] This message will dissapear after issuing the command \"/update-done\"");
|
||||
sleep(3);
|
||||
}else{
|
||||
$this->setProperty("last-update", time());
|
||||
console("[INFO] \x1b[36mThis is the latest DEVELOPMENT version");
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if($info === false or !isset($info["stable"])){
|
||||
console("[ERROR] PocketMine API error");
|
||||
}else{
|
||||
$newest = new VersionString(MAJOR_VERSION);
|
||||
$newestN = $newest->getNumber();
|
||||
$update = new VersionString($info["stable"]["version"]);
|
||||
$updateN = $update->getNumber();
|
||||
if($updateN > $newestN){
|
||||
console("[NOTICE] \x1b[33mA new STABLE version of PocketMine-MP has been released");
|
||||
console("[NOTICE] \x1b[36mVersion \"".$info["stable"]["version"]."\" #".$updateN);
|
||||
console("[NOTICE] Download it at ".$info["stable"]["download"]);
|
||||
console("[NOTICE] This message will dissapear as soon as you update");
|
||||
sleep(5);
|
||||
}else{
|
||||
$this->setProperty("last-update", time());
|
||||
console("[INFO] \x1b[36mThis is the latest STABLE version");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if(file_exists(DATA_PATH."worlds/level.dat")){
|
||||
console("[NOTICE] Detected unimported map data. Importing...");
|
||||
$this->importMap(DATA_PATH."worlds/", true);
|
||||
}
|
||||
$this->server->mapName = $this->getProperty("level-name");
|
||||
$this->server->mapDir = DATA_PATH."worlds/".$this->server->mapName."/";
|
||||
if($this->server->mapName === false or trim($this->server->mapName) === "" or (!file_exists($this->server->mapDir."chunks.dat") and !file_exists($this->server->mapDir."chunks.dat.gz"))){
|
||||
if($this->server->mapName === false or trim($this->server->mapName) === ""){
|
||||
$this->server->mapName = "world";
|
||||
}
|
||||
$this->server->mapDir = DATA_PATH."worlds/".$this->server->mapName."/";
|
||||
$generator = "SuperflatGenerator";
|
||||
if($this->getProperty("generator") !== false and class_exists($this->getProperty("generator"))){
|
||||
$generator = $this->getProperty("generator");
|
||||
}
|
||||
$this->gen = new WorldGenerator($generator, $this->server->seed);
|
||||
if($this->getProperty("generator-settings") !== false and trim($this->getProperty("generator-settings")) != ""){
|
||||
$this->gen->set("preset", $this->getProperty("generator-settings"));
|
||||
}
|
||||
$this->gen->init();
|
||||
$this->gen->generate();
|
||||
$this->gen->save($this->server->mapDir, $this->server->mapName);
|
||||
$this->setProperty("level-name", $this->server->mapName);
|
||||
$this->setProperty("gamemode", 1);
|
||||
}
|
||||
$this->loadProperties();
|
||||
$this->server->loadMap();
|
||||
|
||||
console("[INFO] Loading default APIs");
|
||||
|
||||
$this->loadAPI("console", "ConsoleAPI");
|
||||
$this->loadAPI("level", "LevelAPI");
|
||||
$this->loadAPI("block", "BlockAPI");
|
||||
$this->loadAPI("chat", "ChatAPI");
|
||||
$this->loadAPI("ban", "BanAPI");
|
||||
$this->loadAPI("entity", "EntityAPI");
|
||||
$this->loadAPI("tileentity", "TileEntityAPI");
|
||||
$this->loadAPI("player", "PlayerAPI");
|
||||
$this->loadAPI("time", "TimeAPI");
|
||||
|
||||
foreach($this->apiList as $ob){
|
||||
if(is_callable(array($ob, "init"))){
|
||||
$ob->init(); //Fails sometimes!!!
|
||||
}
|
||||
}
|
||||
$this->loadAPI("plugin", "PluginAPI"); //fix :(
|
||||
$this->plugin->init();
|
||||
|
||||
|
||||
$this->server->loadEntities();
|
||||
}
|
||||
|
||||
public function sendUsage(){
|
||||
console("[INTERNAL] Sending usage data...", true, true, 3);
|
||||
Utils::curl_post("http://stats.pocketmine.net/usage.php", array(
|
||||
"serverid" => $this->server->serverID,
|
||||
"os" => Utils::getOS(),
|
||||
"version" => MAJOR_VERSION,
|
||||
"protocol" => CURRENT_PROTOCOL,
|
||||
"online" => count($this->server->clients),
|
||||
"max" => $this->server->maxClients,
|
||||
));
|
||||
}
|
||||
|
||||
public function __destruct(){
|
||||
foreach($this->apiList as $ob){
|
||||
if(is_callable($ob, "__destruct")){
|
||||
$ob->__destruct();
|
||||
unset($this->apiList[$ob]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function loadProperties(){
|
||||
if(($memory = $this->getProperty("memory-limit")) !== false){
|
||||
$value = array("M" => 1, "G" => 1024);
|
||||
$real = ((int) substr($memory, 0, -1)) * $value[substr($memory, -1)];
|
||||
if($real < 128){
|
||||
console("[ERROR] PocketMine doesn't work right with less than 128MB of RAM", true, true, 0);
|
||||
}
|
||||
@ini_set("memory_limit", $memory);
|
||||
}else{
|
||||
$this->setProperty("memory-limit", "256M");
|
||||
}
|
||||
if(!$this->config->exists("invisible")){
|
||||
$this->config->set("invisible", false);
|
||||
}
|
||||
if($this->server instanceof PocketMinecraftServer){
|
||||
$this->server->setType($this->getProperty("server-type"));
|
||||
$this->server->timePerSecond = $this->getProperty("time-per-second");
|
||||
$this->server->invisible = $this->getProperty("invisible");
|
||||
$this->server->maxClients = $this->getProperty("max-players");
|
||||
$this->server->description = $this->getProperty("description");
|
||||
$this->server->motd = $this->getProperty("motd");
|
||||
$this->server->gamemode = $this->getProperty("gamemode");
|
||||
$this->server->difficulty = $this->getProperty("difficulty");
|
||||
$this->server->whitelist = $this->getProperty("white-list");
|
||||
$this->server->reloadConfig();
|
||||
}
|
||||
}
|
||||
|
||||
private function writeProperties(){
|
||||
$this->config->save();
|
||||
}
|
||||
|
||||
private function parseProperties(){
|
||||
foreach($this->config->getAll() as $n => $v){
|
||||
switch($n){
|
||||
case "last-update":
|
||||
if($v === false){
|
||||
$v = time();
|
||||
}else{
|
||||
$v = (int) $v;
|
||||
}
|
||||
break;
|
||||
case "gamemode":
|
||||
case "max-players":
|
||||
case "port":
|
||||
case "debug":
|
||||
case "difficulty":
|
||||
case "time-per-second":
|
||||
$v = (int) $v;
|
||||
break;
|
||||
case "server-id":
|
||||
if($v !== false){
|
||||
$v = preg_match("/[^0-9\-]/", $v) > 0 ? Utils::readInt(substr(md5($v, true), 0, 4)):$v;
|
||||
}
|
||||
break;
|
||||
}
|
||||
$this->config->set($n, $v);
|
||||
}
|
||||
}
|
||||
|
||||
public function init(){
|
||||
if($this->getProperty("send-usage") !== false){
|
||||
$this->server->schedule(36000, array($this, "sendUsage"), array(), true); //Send usage data every 30 minutes
|
||||
$this->sendUsage();
|
||||
}
|
||||
$this->server->init();
|
||||
unregister_tick_function(array($this->server, "tick"));
|
||||
$this->__destruct();
|
||||
unset($this->server);
|
||||
if($this->getProperty("upnp-forwarding") === true ){
|
||||
console("[INFO] [UPnP] Removing port forward...");
|
||||
UPnP_RemovePortForward($this->getProperty("port"));
|
||||
}
|
||||
return $this->restart;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
public function addHandler($e, $c, $p = 5){
|
||||
return $this->server->addHandler($e, $c, $p);
|
||||
}
|
||||
|
||||
public function dhandle($e, $d){
|
||||
return $this->server->handle($e, $d);
|
||||
}
|
||||
|
||||
public function handle($e, &$d){
|
||||
return $this->server->handle($e, $d);
|
||||
}
|
||||
|
||||
public function action($t, $c, $r = true){
|
||||
return $this->server->action($t, $c, $r);
|
||||
}
|
||||
|
||||
public function schedule($t, $c, $d, $r = false, $e = "server.schedule"){
|
||||
return $this->server->schedule($t, $c, $d, $r, $e);
|
||||
}
|
||||
|
||||
public function event($e, $d){
|
||||
return $this->server->event($e, $d);
|
||||
}
|
||||
|
||||
public function trigger($e, $d){
|
||||
return $this->server->trigger($e, $d);
|
||||
}
|
||||
|
||||
public function deleteEvent($id){
|
||||
return $this->server->deleteEvent($id);
|
||||
}
|
||||
|
||||
public function importMap($dir, $remove = false){
|
||||
if(file_exists($dir."level.dat")){
|
||||
$nbt = new NBT();
|
||||
$level = parseNBTData($nbt->loadFile($dir."level.dat"));
|
||||
if($level["LevelName"] == ""){
|
||||
$level["LevelName"] = "world".time();
|
||||
}
|
||||
console("[DEBUG] Importing map \"".$level["LevelName"]."\" gamemode ".$level["GameType"]." with seed ".$level["RandomSeed"], true, true, 2);
|
||||
unset($level["Player"]);
|
||||
$lvName = $level["LevelName"]."/";
|
||||
@mkdir(DATA_PATH."worlds/".$lvName, 0777);
|
||||
file_put_contents(DATA_PATH."worlds/".$lvName."level.dat", serialize($level));
|
||||
$entities = parseNBTData($nbt->loadFile($dir."entities.dat"));
|
||||
file_put_contents(DATA_PATH."worlds/".$lvName."entities.dat", serialize($entities["Entities"]));
|
||||
if(!isset($entities["TileEntities"])){
|
||||
$entities["TileEntities"] = array();
|
||||
}
|
||||
file_put_contents(DATA_PATH."worlds/".$lvName."tileEntities.dat", serialize($entities["TileEntities"]));
|
||||
console("[DEBUG] Imported ".count($entities["Entities"])." Entities and ".count($entities["TileEntities"])." TileEntities", true, true, 2);
|
||||
|
||||
if($remove === true){
|
||||
rename($dir."chunks.dat", DATA_PATH."worlds/".$lvName."chunks.dat");
|
||||
unlink($dir."level.dat");
|
||||
@unlink($dir."level.dat_old");
|
||||
@unlink($dir."player.dat");
|
||||
unlink($dir."entities.dat");
|
||||
}else{
|
||||
copy($dir."chunks.dat", DATA_PATH."worlds/".$lvName."chunks.dat");
|
||||
}
|
||||
if($this->getProperty("level-name") === false){
|
||||
console("[INFO] Setting default level to \"".$level["LevelName"]."\"");
|
||||
$this->setProperty("level-name", $level["LevelName"]);
|
||||
$this->setProperty("gamemode", $level["GameType"]);
|
||||
$this->server->seed = $level["RandomSeed"];
|
||||
$this->server->spawn = array("x" => $level["SpawnX"], "y" => $level["SpawnY"], "z" => $level["SpawnZ"]);
|
||||
$this->writeProperties();
|
||||
}
|
||||
console("[INFO] Map \"".$level["LevelName"]."\" importing done!");
|
||||
unset($level, $entities, $nbt);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getProperties(){
|
||||
return $this->config->getAll();
|
||||
}
|
||||
|
||||
public function getProperty($name){
|
||||
if(($v = arg($name)) !== false){ //Allow for command-line arguments
|
||||
switch(strtolower(trim($v))){
|
||||
case "on":
|
||||
case "true":
|
||||
case "yes":
|
||||
$v = true;
|
||||
break;
|
||||
case "off":
|
||||
case "false":
|
||||
case "no":
|
||||
$v = false;
|
||||
break;
|
||||
}
|
||||
switch($name){
|
||||
case "last-update":
|
||||
if($v === false){
|
||||
$v = time();
|
||||
}else{
|
||||
$v = (int) $v;
|
||||
}
|
||||
break;
|
||||
case "gamemode":
|
||||
case "max-players":
|
||||
case "port":
|
||||
case "debug":
|
||||
case "difficulty":
|
||||
case "time-per-second":
|
||||
$v = (int) $v;
|
||||
break;
|
||||
case "server-id":
|
||||
if($v !== false){
|
||||
$v = preg_match("/[^0-9\-]/", $v) > 0 ? Utils::readInt(substr(md5($v, true), 0, 4)):$v;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $v;
|
||||
}
|
||||
return $this->config->get($name);
|
||||
}
|
||||
|
||||
public function setProperty($name, $value){
|
||||
$this->config->set($name, $value);
|
||||
$this->writeProperties();
|
||||
$this->loadProperties();
|
||||
}
|
||||
|
||||
public function getList(){
|
||||
return $this->apiList;
|
||||
}
|
||||
|
||||
public function loadAPI($name, $class, $dir = false){
|
||||
if(isset($this->$name)){
|
||||
return false;
|
||||
}elseif(!class_exists($class)){
|
||||
if($dir === false){
|
||||
$dir = FILE_PATH."src/API/";
|
||||
}
|
||||
$file = $dir.$class.".php";
|
||||
if(!file_exists($file)){
|
||||
console("[ERROR] API ".$name." [".$class."] in ".$dir." doesn't exist", true, true, 0);
|
||||
return false;
|
||||
}
|
||||
require_once($file);
|
||||
}
|
||||
$this->$name = new $class($this->server);
|
||||
$this->apiList[] = $this->$name;
|
||||
console("[INFO] API \x1b[36m".$name."\x1b[0m [\x1b[30;1m".$class."\x1b[0m] loaded");
|
||||
}
|
||||
|
||||
}
|
136
src/API/TileEntityAPI.php
Normal file
136
src/API/TileEntityAPI.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class TileEntityAPI{
|
||||
private $server;
|
||||
function __construct(PocketMinecraftServer $server){
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
public function get($x, $y = false, $z = false){
|
||||
if(($x instanceof Vector3) or ($x instanceof Block)){
|
||||
$z = (int) $x->z;
|
||||
$y = (int) $x->y;
|
||||
$x = (int) $x->x;
|
||||
}else{
|
||||
$x = (int) $x;
|
||||
$y = (int) $y;
|
||||
$z = (int) $z;
|
||||
}
|
||||
$tiles = $this->server->query("SELECT * FROM tileentities WHERE x = $x AND y = $y AND z = $z;");
|
||||
$ret = array();
|
||||
if($tiles !== false and $tiles !== true){
|
||||
while(($t = $tiles->fetchArray(SQLITE3_ASSOC)) !== false){
|
||||
if(($tile = $this->getByID($t["ID"])) !== false){
|
||||
if($tile->normal === true){
|
||||
$ret[] = $tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(count($ret) === 0){
|
||||
return false;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function getByID($id){
|
||||
if($id instanceof TileEntity){
|
||||
return $id;
|
||||
}elseif(isset($this->server->tileEntities[$id])){
|
||||
return $this->server->tileEntities[$id];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function init(){
|
||||
|
||||
}
|
||||
|
||||
public function getAll(){
|
||||
return $this->server->tileEntities;
|
||||
}
|
||||
|
||||
public function add($class, $x, $y, $z, $data = array()){
|
||||
$id = $this->tCnt++;
|
||||
$this->server->tileEntities[$id] = new TileEntity($this->server, $id, $class, $x, $y, $z, $data);
|
||||
$this->spawnToAll($id);
|
||||
return $this->server->tileEntities[$id];
|
||||
}
|
||||
|
||||
public function addSign($x, $y, $z, $lines = array("", "", "", "")){
|
||||
return $this->add(TILE_SIGN, $x, $y, $z, $data = array(
|
||||
"id" => "Sign",
|
||||
"x" => $x,
|
||||
"y" => $y,
|
||||
"z" => $z,
|
||||
"Text1" => $lines[0],
|
||||
"Text2" => $lines[1],
|
||||
"Text3" => $lines[2],
|
||||
"Text4" => $lines[3],
|
||||
));
|
||||
}
|
||||
|
||||
public function spawnTo($id, $player, $queue = false){
|
||||
$t = $this->getByID($id);
|
||||
if($t === false){
|
||||
return false;
|
||||
}
|
||||
$t->spawn($player, $queue);
|
||||
}
|
||||
|
||||
public function spawnToAll($id){
|
||||
$t = $this->getByID($id);
|
||||
if($t === false){
|
||||
return false;
|
||||
}
|
||||
foreach($this->server->api->player->getAll() as $player){
|
||||
if($player->eid !== false){
|
||||
$t->spawn($player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function spawnAll($player){
|
||||
foreach($this->getAll() as $t){
|
||||
$t->spawn($player);
|
||||
}
|
||||
}
|
||||
|
||||
public function remove($id){
|
||||
if(isset($this->server->tileEntities[$id])){
|
||||
$t = $this->server->tileEntities[$id];
|
||||
$this->server->tileEntities[$id] = null;
|
||||
unset($this->server->tileEntities[$id]);
|
||||
$t->closed = true;
|
||||
$t->close();
|
||||
$this->server->query("DELETE FROM tileentities WHERE ID = ".$id.";");
|
||||
$t = null;
|
||||
unset($t);
|
||||
}
|
||||
}
|
||||
}
|
129
src/API/TimeAPI.php
Normal file
129
src/API/TimeAPI.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class TimeAPI{
|
||||
var $phases = array(
|
||||
"day" => 0,
|
||||
"sunset" => 9500,
|
||||
"night" => 10900,
|
||||
"sunrise" => 17800,
|
||||
);
|
||||
private $server;
|
||||
function __construct(PocketMinecraftServer $server){
|
||||
$this->server = $server;
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->server->api->console->register("time", "Manages server time", array($this, "commandHandler"));
|
||||
}
|
||||
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "time":
|
||||
$p = strtolower(array_shift($params));
|
||||
switch($p){
|
||||
case "check":
|
||||
$output .= "Time: ".$this->getDate().", ".$this->getPhase()." (".$this->get(true).")\n";
|
||||
break;
|
||||
case "add":
|
||||
$this->add(array_shift($params));
|
||||
break;
|
||||
case "set":
|
||||
$this->set(array_shift($params));
|
||||
break;
|
||||
case "sunrise":
|
||||
$this->sunrise();
|
||||
break;
|
||||
case "day":
|
||||
$this->day();
|
||||
break;
|
||||
case "sunset":
|
||||
$this->sunset();
|
||||
break;
|
||||
case "night":
|
||||
$this->night();
|
||||
break;
|
||||
default:
|
||||
$output .= "Usage: /time <check | set | add | sunrise | day | sunset | night> [time]\n";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function night(){
|
||||
$this->set("night");
|
||||
}
|
||||
public function day(){
|
||||
$this->set("day");
|
||||
}
|
||||
public function sunrise(){
|
||||
$this->set("sunrise");
|
||||
}
|
||||
public function sunset(){
|
||||
$this->set("sunset");
|
||||
}
|
||||
|
||||
public function get($raw = false){
|
||||
return $raw === true ? $this->server->time:abs($this->server->time) % 19200;
|
||||
}
|
||||
|
||||
public function add($time){
|
||||
$this->server->time += (int) $time;
|
||||
}
|
||||
|
||||
public function getDate($time = false){
|
||||
$time = $time === false ? $this->get():$time;
|
||||
return str_pad(strval((floor($time /800) + 6) % 24), 2, "0", STR_PAD_LEFT).":".str_pad(strval(floor(($time % 800) / 13.33)), 2, "0", STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
public function getPhase($time = false){
|
||||
$time = $time === false ? $this->get():$time;
|
||||
if($time < $this->phase["sunset"]){
|
||||
$time = "day";
|
||||
}elseif($time < $this->phase["night"]){
|
||||
$time = "sunset";
|
||||
}elseif($time < $this->phase["sunrise"]){
|
||||
$time = "night";
|
||||
}else{
|
||||
$time = "sunrise";
|
||||
}
|
||||
return $time;
|
||||
}
|
||||
|
||||
public function set($time){
|
||||
if(is_string($time) and isset($this->phases[$time])){
|
||||
$this->server->time = $this->phases[$time];
|
||||
}else{
|
||||
$this->server->time = (int) $time;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
71
src/Async.php
Normal file
71
src/Async.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class Async extends Thread {
|
||||
/**
|
||||
* Provide a passthrough to call_user_func_array
|
||||
**/
|
||||
public function __construct($method, $params = array()){
|
||||
$this->method = $method;
|
||||
$this->params = $params;
|
||||
$this->result = null;
|
||||
$this->joined = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The smallest thread in the world
|
||||
**/
|
||||
public function run(){
|
||||
if(($this->result=call_user_func_array($this->method, $this->params))){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to create your threads from functions ...
|
||||
**/
|
||||
public static function call($method, $params = array()){
|
||||
$thread = new Async($method, $params);
|
||||
if($thread->start()){
|
||||
return $thread;
|
||||
} /** else throw Nastyness **/
|
||||
}
|
||||
|
||||
/**
|
||||
* Do whatever, result stored in $this->result, don't try to join twice
|
||||
**/
|
||||
public function __toString(){
|
||||
if(!$this->joined) {
|
||||
$this->joined = true;
|
||||
$this->join();
|
||||
}
|
||||
|
||||
return $this->result;
|
||||
}
|
||||
}
|
31
src/BlockIterator.php
Normal file
31
src/BlockIterator.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
/*
|
||||
class BlockIterator implements Iterator{
|
||||
|
||||
|
||||
}*/
|
262
src/Data.php
Normal file
262
src/Data.php
Normal file
@ -0,0 +1,262 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class BlockFace{
|
||||
const BOTTOM = 0;
|
||||
const TOP = 1;
|
||||
const DOWN = 0;
|
||||
const UP = 1;
|
||||
const SOUTH = 3;
|
||||
const EAST = 5;
|
||||
const NORTH = 2;
|
||||
const WEST = 4;
|
||||
public static function setPosition(&$data, $face){
|
||||
switch((int) $face){
|
||||
case 0:
|
||||
--$data["y"];
|
||||
break;
|
||||
case 1:
|
||||
++$data["y"];
|
||||
break;
|
||||
case 2:
|
||||
--$data["z"];
|
||||
break;
|
||||
case 3:
|
||||
++$data["z"];
|
||||
break;
|
||||
case 4:
|
||||
--$data["x"];
|
||||
break;
|
||||
case 5:
|
||||
++$data["x"];
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class Material{
|
||||
static $flowable = array(
|
||||
0 => true,
|
||||
6 => true,
|
||||
30 => true,
|
||||
31 => true,
|
||||
32 => true,
|
||||
37 => true,
|
||||
38 => true,
|
||||
39 => true,
|
||||
40 => true,
|
||||
50 => true,
|
||||
51 => true,
|
||||
55 => true,
|
||||
59 => true,
|
||||
78 => true,
|
||||
105 => true,
|
||||
);
|
||||
static $unbreakable = array(
|
||||
0 => true,
|
||||
7 => true,
|
||||
8 => true,
|
||||
9 => true,
|
||||
10 => true,
|
||||
11 => true,
|
||||
);
|
||||
static $transparent = array(
|
||||
0 => true,
|
||||
6 => true,
|
||||
8 => true,
|
||||
9 => true,
|
||||
10 => true,
|
||||
11 => true,
|
||||
18 => true,
|
||||
20 => true,
|
||||
26 => true,
|
||||
30 => true,
|
||||
31 => true,
|
||||
32 => true,
|
||||
37 => true,
|
||||
38 => true,
|
||||
39 => true,
|
||||
40 => true,
|
||||
44 => true,
|
||||
46 => true,
|
||||
50 => true,
|
||||
51 => true,
|
||||
53 => true,
|
||||
59 => true,
|
||||
63 => true,
|
||||
64 => true,
|
||||
65 => true,
|
||||
67 => true,
|
||||
68 => true,
|
||||
71 => true,
|
||||
78 => true,
|
||||
79 => true,
|
||||
83 => true,
|
||||
85 => true,
|
||||
89 => true,
|
||||
96 => true,
|
||||
102 => true,
|
||||
105 => true,
|
||||
107 => true,
|
||||
108 => true,
|
||||
109 => true,
|
||||
114 => true,
|
||||
128 => true,
|
||||
156 => true,
|
||||
);
|
||||
static $replaceable = array(
|
||||
0 => true,
|
||||
8 => true,
|
||||
9 => true,
|
||||
10 => true,
|
||||
11 => true,
|
||||
31 => true,
|
||||
51 => true,
|
||||
78 => true,
|
||||
);
|
||||
static $activable = array(
|
||||
2 => true,
|
||||
3 => true,
|
||||
6 => true,
|
||||
26 => true,
|
||||
31 => true,
|
||||
//46 => true,
|
||||
51 => true,
|
||||
54 => true,
|
||||
58 => true,
|
||||
59 => true,
|
||||
61 => true,
|
||||
62 => true,
|
||||
64 => true,
|
||||
71 => true,
|
||||
78 => true,
|
||||
96 => true,
|
||||
105 => true,
|
||||
107 => true,
|
||||
245 => true,
|
||||
247 => true,
|
||||
);
|
||||
static $placeable = array(
|
||||
1 => true,
|
||||
2 => true,
|
||||
3 => true,
|
||||
4 => true,
|
||||
5 => true,
|
||||
6 => true,
|
||||
//7 => true,
|
||||
8 => true,
|
||||
9 => true,
|
||||
10 => true,
|
||||
11 => true,
|
||||
12 => true,
|
||||
13 => true,
|
||||
14 => true,
|
||||
15 => true,
|
||||
16 => true,
|
||||
17 => true,
|
||||
18 => true,
|
||||
19 => true,
|
||||
20 => true,
|
||||
21 => true,
|
||||
22 => true,
|
||||
24 => true,
|
||||
355 => 26,
|
||||
30 => true,
|
||||
35 => true,
|
||||
37 => true,
|
||||
38 => true,
|
||||
39 => true,
|
||||
40 => true,
|
||||
41 => true,
|
||||
42 => true,
|
||||
43 => true,
|
||||
44 => true,
|
||||
45 => true,
|
||||
46 => true,
|
||||
47 => true,
|
||||
48 => true,
|
||||
49 => true,
|
||||
50 => true,
|
||||
53 => true,
|
||||
54 => true,
|
||||
56 => true,
|
||||
59 => true,
|
||||
57 => true,
|
||||
58 => true,
|
||||
295 => 59,
|
||||
61 => true,
|
||||
324 => 64,
|
||||
65 => true,
|
||||
67 => true,
|
||||
330 => 71,
|
||||
73 => true,
|
||||
79 => true,
|
||||
80 => true,
|
||||
81 => true,
|
||||
82 => true,
|
||||
83 => true,
|
||||
85 => true,
|
||||
86 => true,
|
||||
87 => true,
|
||||
88 => true,
|
||||
89 => true,
|
||||
91 => true,
|
||||
96 => true,
|
||||
98 => true,
|
||||
102 => true,
|
||||
103 => true,
|
||||
362 => 105,
|
||||
107 => true,
|
||||
108 => true,
|
||||
109 => true,
|
||||
112 => true,
|
||||
114 => true,
|
||||
128 => true,
|
||||
155 => true,
|
||||
156 => true,
|
||||
245 => true,
|
||||
246 => true,
|
||||
247 => true,
|
||||
323 => true, //Special case of signs
|
||||
338 => 83,
|
||||
);
|
||||
static $blocks = array(
|
||||
0 => "Air",
|
||||
1 => "Stone",
|
||||
2 => "Grass",
|
||||
3 => "Dirt",
|
||||
4 => "Cobblestone",
|
||||
5 => "Wooden Planks",
|
||||
6 => "Sapling",
|
||||
7 => "Bedrock",
|
||||
);
|
||||
|
||||
|
||||
}
|
39
src/Deprecation.php
Normal file
39
src/Deprecation.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
class Deprecation{
|
||||
public static $events = array(
|
||||
"world.block.change" => "block.change",
|
||||
"block.drop" => "item.drop",
|
||||
"api.op.check" => "op.check",
|
||||
"api.player.offline.get" => "player.offline.get",
|
||||
"api.player.offline.save" => "player.offline.save",
|
||||
);
|
||||
|
||||
|
||||
}
|
1077
src/Player.php
Normal file
1077
src/Player.php
Normal file
File diff suppressed because it is too large
Load Diff
743
src/PocketMinecraftServer.php
Normal file
743
src/PocketMinecraftServer.php
Normal file
@ -0,0 +1,743 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class PocketMinecraftServer{
|
||||
public $tCnt;
|
||||
public $version, $invisible, $api, $tickMeasure, $preparedSQL, $seed, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $spawn, $entities, $mapDir, $mapName, $map, $levelData, $tileEntities;
|
||||
private $serverip, $database, $interface, $evCnt, $handCnt, $events, $eventsID, $handlers, $serverType, $lastTick, $ticker;
|
||||
|
||||
private function load(){
|
||||
$this->version = new VersionString();
|
||||
console("[INFO] \x1b[33;1mPocketMine-MP ".MAJOR_VERSION." #".$this->version->getNumber()." by @shoghicp, LGPL License", true, true, 0);
|
||||
console("[INFO] Target Minecraft PE: \x1b[36;1m".CURRENT_MINECRAFT_VERSION."\x1b[0m, protocol #".CURRENT_PROTOCOL, true, true, 0);
|
||||
if($this->version->isDev()){
|
||||
console("[INFO] \x1b[31;1mThis is a Development version");
|
||||
}
|
||||
console("[INFO] Starting Minecraft PE Server at ".$this->serverip.":".$this->port);
|
||||
if($this->port < 19132 or $this->port > 19135){ //Mojang =(
|
||||
console("[WARNING] You've selected a not-standard port. Normal port range is from 19132 to 19135 included");
|
||||
}
|
||||
$this->serverID = $this->serverID === false ? Utils::readLong(Utils::getRandomBytes(8, false)):$this->serverID;
|
||||
$this->seed = $this->seed === false ? Utils::readInt(Utils::getRandomBytes(4, false)):$this->seed;
|
||||
console("[INFO] Loading database...");
|
||||
$this->startDatabase();
|
||||
$this->doTick = false;
|
||||
$this->api = false;
|
||||
$this->tCnt = 1;
|
||||
$this->mapDir = false;
|
||||
$this->mapName = false;
|
||||
$this->events = array();
|
||||
$this->eventsID = array();
|
||||
$this->handlers = array();
|
||||
$this->map = false;
|
||||
$this->invisible = false;
|
||||
$this->levelData = false;
|
||||
$this->difficulty = 1;
|
||||
$this->tileEntities = array();
|
||||
$this->entities = array();
|
||||
$this->custom = array();
|
||||
$this->evCnt = 1;
|
||||
$this->handCnt = 1;
|
||||
$this->eidCnt = 1;
|
||||
$this->maxClients = 20;
|
||||
$this->schedule = array();
|
||||
$this->scheduleCnt = 1;
|
||||
$this->description = "";
|
||||
$this->whitelist = false;
|
||||
$this->clients = array();
|
||||
$this->spawn = array("x" => 128.5,"y" => 100,"z" => 128.5);
|
||||
$this->time = 0;
|
||||
$this->timePerSecond = 10;
|
||||
$this->tickMeasure = array_fill(0, 40, 0);
|
||||
$this->setType("normal");
|
||||
$this->interface = new MinecraftInterface("255.255.255.255", $this->port, true, false);
|
||||
$this->reloadConfig();
|
||||
console("[INFO] Server Name: \x1b[36m".$this->name."\x1b[0m");
|
||||
console("[DEBUG] Server ID: ".$this->serverID, true, true, 2);
|
||||
$this->stop = false;
|
||||
}
|
||||
|
||||
function __construct($name, $gamemode = CREATIVE, $seed = false, $port = 19132, $serverID = false, $serverip = "0.0.0.0"){
|
||||
$this->port = (int) $port; //19132 - 19135
|
||||
$this->gamemode = (int) $gamemode;
|
||||
$this->name = $name;
|
||||
$this->motd = "Welcome to ".$name;
|
||||
$this->serverID = $serverID;
|
||||
$this->seed = $seed;
|
||||
$this->serverip = $serverip;
|
||||
$this->load();
|
||||
}
|
||||
|
||||
public function getTPS(){
|
||||
$v = array_values($this->tickMeasure);
|
||||
$tps = 40 / ($v[39] - $v[0]);
|
||||
return round($tps, 4);
|
||||
}
|
||||
|
||||
public function titleTick(){
|
||||
if(ENABLE_ANSI === true){
|
||||
echo "\x1b]0;PocketMine-MP ".MAJOR_VERSION." | Online ". count($this->clients)." | RAM ".round((memory_get_usage(true) / 1024) / 1024, 2)."MB | TPS ".$this->getTPS()."\x07";
|
||||
}
|
||||
}
|
||||
|
||||
public function loadEvents(){
|
||||
if(ENABLE_ANSI === true){
|
||||
$this->action(1500000, '$this->titleTick();');
|
||||
}
|
||||
$this->action(500000, '$this->time += (int) ($this->timePerSecond / 2);$this->api->dhandle("server.time", $this->time);');
|
||||
$this->action(5000000, 'if($this->difficulty < 2){$this->api->dhandle("server.regeneration", 1);}');
|
||||
$this->action(1000000 * 15, 'if($this->getTPS() < 15){console("[WARNING] Can\'t keep up! Is the server overloaded?");}');
|
||||
$this->action(1000000 * 60 * 10, '$this->custom = array();');
|
||||
if($this->api instanceof ServerAPI){
|
||||
$this->action(1000000 * 80, '$cnt = count($this->clients); if($cnt > 1){$this->api->chat->broadcast("Online (".$cnt."): ".implode(", ",$this->api->player->online()));}');
|
||||
}
|
||||
}
|
||||
|
||||
public function startDatabase(){
|
||||
$this->preparedSQL = new stdClass();
|
||||
$this->database = new SQLite3(":memory:");
|
||||
//$this->query("PRAGMA journal_mode = OFF;");
|
||||
//$this->query("PRAGMA encoding = \"UTF-8\";");
|
||||
//$this->query("PRAGMA secure_delete = OFF;");
|
||||
$this->query("CREATE TABLE players (clientID INTEGER PRIMARY KEY, EID NUMERIC, ip TEXT, port NUMERIC, name TEXT UNIQUE COLLATE NOCASE);");
|
||||
$this->query("CREATE TABLE entities (EID INTEGER PRIMARY KEY, type NUMERIC, class NUMERIC, name TEXT, x NUMERIC, y NUMERIC, z NUMERIC, yaw NUMERIC, pitch NUMERIC, health NUMERIC);");
|
||||
$this->query("CREATE TABLE tileentities (ID INTEGER PRIMARY KEY, class TEXT, x NUMERIC, y NUMERIC, z NUMERIC, spawnable NUMERIC);");
|
||||
$this->query("CREATE TABLE actions (ID INTEGER PRIMARY KEY, interval NUMERIC, last NUMERIC, code TEXT, repeat NUMERIC);");
|
||||
$this->query("CREATE TABLE handlers (ID INTEGER PRIMARY KEY, name TEXT, priority NUMERIC);");
|
||||
//$this->query("PRAGMA synchronous = OFF;");
|
||||
$this->preparedSQL->selectHandlers = $this->database->prepare("SELECT DISTINCT ID FROM handlers WHERE name = :name ORDER BY priority DESC;");
|
||||
$this->preparedSQL->selectActions = $this->database->prepare("SELECT ID,code,repeat FROM actions WHERE last <= (:time - interval);");
|
||||
$this->preparedSQL->updateActions = $this->database->prepare("UPDATE actions SET last = :time WHERE last <= (:time - interval);");
|
||||
}
|
||||
|
||||
public function query($sql, $fetch = false){
|
||||
console("[INTERNAL] [SQL] ".$sql, true, true, 3);
|
||||
$result = $this->database->query($sql) or console("[ERROR] [SQL Error] ".$this->database->lastErrorMsg().". Query: ".$sql, true, true, 0);
|
||||
if($fetch === true and ($result !== false and $result !== true)){
|
||||
$result = $result->fetchArray(SQLITE3_ASSOC);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function reloadConfig(){
|
||||
|
||||
}
|
||||
|
||||
public function debugInfo($console = false){
|
||||
$info = array();
|
||||
$info["tps"] = $this->getTPS();
|
||||
$info["memory_usage"] = round((memory_get_usage(true) / 1024) / 1024, 2)."MB";
|
||||
$info["memory_peak_usage"] = round((memory_get_peak_usage(true) / 1024) / 1024, 2)."MB";
|
||||
$info["entities"] = $this->query("SELECT count(EID) as count FROM entities;", true);
|
||||
$info["entities"] = $info["entities"]["count"];
|
||||
$info["events"] = count($this->eventsID);
|
||||
$info["handlers"] = $this->query("SELECT count(ID) as count FROM handlers;", true);
|
||||
$info["handlers"] = $info["handlers"]["count"];
|
||||
$info["actions"] = $this->query("SELECT count(ID) as count FROM actions;", true);
|
||||
$info["actions"] = $info["actions"]["count"];
|
||||
$info["garbage"] = gc_collect_cycles();
|
||||
$this->handle("server.debug", $info);
|
||||
if($console === true){
|
||||
console("[DEBUG] TPS: ".$info["tps"].", Memory usage: ".$info["memory_usage"]." (Peak ".$info["memory_peak_usage"]."), Entities: ".$info["entities"].", Events: ".$info["events"].", Handlers: ".$info["handlers"].", Actions: ".$info["actions"].", Garbage: ".$info["garbage"], true, true, 2);
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
public function close($reason = "stop"){
|
||||
if($this->stop !== true){
|
||||
if(is_int($reason)){
|
||||
$reason = "signal stop";
|
||||
}
|
||||
if(($this->api instanceof ServerAPI) === true){
|
||||
if(($this->api->chat instanceof ChatAPI) === true){
|
||||
$this->api->chat->send(false, "Stopping server...");
|
||||
}
|
||||
}
|
||||
//$this->ticker->stop = true;
|
||||
$this->save(true);
|
||||
$this->stop = true;
|
||||
$this->trigger("server.close", $reason);
|
||||
$this->interface->close();
|
||||
}
|
||||
}
|
||||
|
||||
public function chat($owner, $text, $target = false){
|
||||
$this->api->chat->send($owner, $text, $target);
|
||||
}
|
||||
|
||||
public function setType($type = "normal"){
|
||||
switch($type){
|
||||
case "normal":
|
||||
$this->serverType = "MCCPP;Demo;";
|
||||
break;
|
||||
case "minecon":
|
||||
$this->serverType = "MCCPP;MINECON;";
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function addHandler($event,callable $callable, $priority = 5){
|
||||
if(!is_callable($callable)){
|
||||
return false;
|
||||
}elseif(isset(Deprecation::$events[$event])){
|
||||
$sub = "";
|
||||
if(Deprecation::$events[$event] !== false){
|
||||
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
|
||||
}
|
||||
console("[ERROR] Event \"$event\" has been deprecated.$sub [Adding handle to ".(is_array($callable) ? get_class($callable[0])."::".$callable[1]:$callable)."]");
|
||||
}
|
||||
$priority = (int) $priority;
|
||||
$hnid = $this->handCnt++;
|
||||
$this->handlers[$hnid] = $callable;
|
||||
$this->query("INSERT INTO handlers (ID, name, priority) VALUES (".$hnid.", '".str_replace("'", "\\'", $event)."', ".$priority.");");
|
||||
console("[INTERNAL] New handler ".(is_array($callable) ? get_class($callable[0])."::".$callable[1]:$callable)." to special event ".$event." (ID ".$hnid.")", true, true, 3);
|
||||
return $hnid;
|
||||
}
|
||||
|
||||
public function handle($event, &$data){
|
||||
$this->preparedSQL->selectHandlers->reset();
|
||||
$this->preparedSQL->selectHandlers->clear();
|
||||
$this->preparedSQL->selectHandlers->bindValue(":name", $event, SQLITE3_TEXT);
|
||||
$handlers = $this->preparedSQL->selectHandlers->execute();
|
||||
$result = null;
|
||||
if($handlers !== false and $handlers !== true){
|
||||
console("[INTERNAL] Handling ".$event, true, true, 3);
|
||||
$call = array();
|
||||
while(($hn = $handlers->fetchArray(SQLITE3_ASSOC)) !== false){
|
||||
$call[(int) $hn["ID"]] = true;
|
||||
}
|
||||
$handlers->finalize();
|
||||
foreach($call as $hnid => $boolean){
|
||||
if($result !== false and $result !== true){
|
||||
$called[$hnid] = true;
|
||||
$handler = $this->handlers[$hnid];
|
||||
if(is_array($handler)){
|
||||
$method = $handler[1];
|
||||
$result = $handler[0]->$method($data, $event);
|
||||
}else{
|
||||
$result = $handler($data, $event);
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}elseif(isset(Deprecation::$events[$event])){
|
||||
$sub = "";
|
||||
if(Deprecation::$events[$event] !== false){
|
||||
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
|
||||
}
|
||||
console("[ERROR] Event \"$event\" has been deprecated.$sub [Handler]");
|
||||
}
|
||||
|
||||
if($result !== false){
|
||||
$this->trigger($event, $data);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function eventHandler($data, $event){
|
||||
switch($event){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function loadMap(){
|
||||
if($this->mapName !== false and trim($this->mapName) !== ""){
|
||||
$this->levelData = unserialize(file_get_contents($this->mapDir."level.dat"));
|
||||
if($this->levelData === false){
|
||||
console("[ERROR] Invalid world data for \"".$this->mapDir."\. Please import the world correctly");
|
||||
$this->close("invalid world data");
|
||||
}
|
||||
console("[INFO] Map: ".$this->levelData["LevelName"]);
|
||||
$this->time = (int) $this->levelData["Time"];
|
||||
$this->seed = (int) $this->levelData["RandomSeed"];
|
||||
if(isset($this->levelData["SpawnX"])){
|
||||
$this->spawn = array("x" => $this->levelData["SpawnX"], "y" => $this->levelData["SpawnY"], "z" => $this->levelData["SpawnZ"]);
|
||||
}else{
|
||||
$this->levelData["SpawnX"] = $this->spawn["x"];
|
||||
$this->levelData["SpawnY"] = $this->spawn["y"];
|
||||
$this->levelData["SpawnZ"] = $this->spawn["z"];
|
||||
}
|
||||
$this->levelData["Time"] = $this->time;
|
||||
console("[INFO] Spawn: X \x1b[36m".$this->levelData["SpawnX"]."\x1b[0m Y \x1b[36m".$this->levelData["SpawnY"]."\x1b[0m Z \x1b[36m".$this->levelData["SpawnZ"]."\x1b[0m");
|
||||
console("[INFO] Time: \x1b[36m".$this->time."\x1b[0m");
|
||||
console("[INFO] Seed: \x1b[36m".$this->seed."\x1b[0m");
|
||||
console("[INFO] Gamemode: \x1b[36m".$this->getGamemode()."\x1b[0m");
|
||||
$d = array(0 => "peaceful", 1 => "easy", 2 => "normal", 3 => "hard");
|
||||
console("[INFO] Difficulty: \x1b[36m".$d[$this->difficulty]."\x1b[0m");
|
||||
console("[INFO] Loading map...");
|
||||
$this->map = new ChunkParser();
|
||||
if(!$this->map->loadFile($this->mapDir."chunks.dat")){
|
||||
console("[ERROR] Couldn't load the map \"\x1b[32m".$this->levelData["LevelName"]."\x1b[0m\"!", true, true, 0);
|
||||
$this->map = false;
|
||||
}else{
|
||||
$this->map->loadMap();
|
||||
}
|
||||
}else{
|
||||
console("[INFO] Time: \x1b[36m".$this->time."\x1b[0m");
|
||||
console("[INFO] Seed: \x1b[36m".$this->seed."\x1b[0m");
|
||||
console("[INFO] Gamemode: \x1b[36m".$this->getGamemode()."\x1b[0m");
|
||||
}
|
||||
}
|
||||
|
||||
public function getGamemode(){
|
||||
switch($this->gamemode){
|
||||
case SURVIVAL:
|
||||
return "survival";
|
||||
case CREATIVE:
|
||||
return "creative";
|
||||
case ADVENTURE:
|
||||
return "adventure";
|
||||
}
|
||||
}
|
||||
|
||||
public function loadEntities(){
|
||||
if($this->map !== false){
|
||||
console("[INFO] Loading entities...");
|
||||
$entities = unserialize(file_get_contents($this->mapDir."entities.dat"));
|
||||
if($entities === false or !is_array($entities)){
|
||||
console("[ERROR] Invalid world data for \"".$this->mapDir."\. Please import the world correctly");
|
||||
$this->close("invalid world data");
|
||||
}
|
||||
foreach($entities as $entity){
|
||||
if(!isset($entity["id"])){
|
||||
break;
|
||||
}
|
||||
if(isset($this->api) and $this->api !== false){
|
||||
if($entity["id"] === 64){ //Item Drop
|
||||
$e = $this->api->entity->add(ENTITY_ITEM, $entity["Item"]["id"], array(
|
||||
"meta" => $entity["Item"]["Damage"],
|
||||
"stack" => $entity["Item"]["Count"],
|
||||
"x" => $entity["Pos"][0],
|
||||
"y" => $entity["Pos"][1],
|
||||
"z" => $entity["Pos"][2],
|
||||
"yaw" => $entity["Rotation"][0],
|
||||
"pitch" => $entity["Rotation"][1],
|
||||
));
|
||||
}elseif($entity["id"] === OBJECT_PAINTING){ //Painting
|
||||
$e = $this->api->entity->add(ENTITY_OBJECT, $entity["id"], $entity);
|
||||
$e->setPosition($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2], $entity["Rotation"][0], $entity["Rotation"][1]);
|
||||
$e->setHealth($entity["Health"]);
|
||||
}else{
|
||||
$e = $this->api->entity->add(ENTITY_MOB, $entity["id"], $entity);
|
||||
$e->setPosition($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2], $entity["Rotation"][0], $entity["Rotation"][1]);
|
||||
$e->setHealth($entity["Health"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$tiles = unserialize(file_get_contents($this->mapDir."tileEntities.dat"));
|
||||
foreach($tiles as $tile){
|
||||
if(!isset($tile["id"])){
|
||||
break;
|
||||
}
|
||||
$t = $this->api->tileentity->add($tile["id"], $tile["x"], $tile["y"], $tile["z"], $tile);
|
||||
}
|
||||
$this->action(1000000 * 60 * 25, '$this->api->chat->broadcast("Forcing save...");$this->save();');
|
||||
}
|
||||
}
|
||||
|
||||
public function save($final = false){
|
||||
if($this->mapName !== false){
|
||||
$this->levelData["Time"] = $this->time;
|
||||
file_put_contents($this->mapDir."level.dat", serialize($this->levelData));
|
||||
$this->map->saveMap($final);
|
||||
$this->trigger("server.save", $final);
|
||||
console("[INFO] Saving entities...");
|
||||
if(count($this->entities) > 0){
|
||||
$entities = array();
|
||||
foreach($this->entities as $entity){
|
||||
if($entity->class === ENTITY_MOB){
|
||||
$entities[] = array(
|
||||
"id" => $entity->type,
|
||||
"Color" => @$entity->data["Color"],
|
||||
"Sheared" => @$entity->data["Sheared"],
|
||||
"Health" => $entity->health,
|
||||
"Pos" => array(
|
||||
0 => $entity->x,
|
||||
1 => $entity->y,
|
||||
2 => $entity->z,
|
||||
),
|
||||
"Rotation" => array(
|
||||
0 => $entity->yaw,
|
||||
1 => $entity->pitch,
|
||||
),
|
||||
);
|
||||
}elseif($entity->class === ENTITY_OBJECT){
|
||||
$entities[] = array(
|
||||
"id" => $entity->type,
|
||||
"TileX" => $entity->x,
|
||||
"TileX" => $entity->y,
|
||||
"TileX" => $entity->z,
|
||||
"Health" => $entity->health,
|
||||
"Motive" => $entity->data["Motive"],
|
||||
"Pos" => array(
|
||||
0 => $entity->x,
|
||||
1 => $entity->y,
|
||||
2 => $entity->z,
|
||||
),
|
||||
"Rotation" => array(
|
||||
0 => $entity->yaw,
|
||||
1 => $entity->pitch,
|
||||
),
|
||||
);
|
||||
}elseif($entity->class === ENTITY_ITEM){
|
||||
$entities[] = array(
|
||||
"id" => 64,
|
||||
"Item" => array(
|
||||
"id" => $entity->type,
|
||||
"Damage" => $entity->meta,
|
||||
"Count" => $entity->stack,
|
||||
),
|
||||
"Health" => $entity->health,
|
||||
"Pos" => array(
|
||||
0 => $entity->x,
|
||||
1 => $entity->y,
|
||||
2 => $entity->z,
|
||||
),
|
||||
"Rotation" => array(
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
file_put_contents($this->mapDir."entities.dat", serialize($entities));
|
||||
}
|
||||
if(count($this->tileEntities) > 0){
|
||||
$tiles = array();
|
||||
foreach($this->tileEntities as $tile){
|
||||
$tiles[] = $tile->data;
|
||||
}
|
||||
file_put_contents($this->mapDir."tileEntities.dat", serialize($tiles));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init(){
|
||||
if($this->mapName !== false and $this->map === false){
|
||||
$this->loadMap();
|
||||
$this->loadEntities();
|
||||
}
|
||||
console("[INFO] Loading events...");
|
||||
$this->loadEvents();
|
||||
//$this->ticker = new TickLoop($this);
|
||||
//$this->ticker->start();
|
||||
declare(ticks=15);
|
||||
register_tick_function(array($this, "tick"));
|
||||
register_shutdown_function(array($this, "dumpError"));
|
||||
register_shutdown_function(array($this, "close"));
|
||||
if(function_exists("pcntl_signal")){
|
||||
pcntl_signal(SIGTERM, array($this, "close"));
|
||||
pcntl_signal(SIGINT, array($this, "close"));
|
||||
pcntl_signal(SIGHUP, array($this, "close"));
|
||||
}
|
||||
$this->trigger("server.start", microtime(true));
|
||||
console("[INFO] Server started!");
|
||||
$this->process();
|
||||
}
|
||||
|
||||
public function dumpError(){
|
||||
console("[ERROR] An Unrecovereable has ocurred and the server has Crashed. Creating an Error Dump");
|
||||
$dump = "# PocketMine-MP Error Dump ".date("D M j H:i:s T Y")."\r\n";
|
||||
$er = error_get_last();
|
||||
$dump .= "Error: ".var_export($er, true)."\r\n\r\n";
|
||||
$dump .= "Code: \r\n";
|
||||
$file = file($er["file"], FILE_IGNORE_NEW_LINES);
|
||||
for($l = max(0, $er["line"] - 10); $l < $er["line"] + 10; ++$l){
|
||||
$dump .= "[".($l + 1)."] ".$file[$l]."\r\n";
|
||||
}
|
||||
$dump .= "\r\n\r\n";
|
||||
$version = new VersionString();
|
||||
$dump .= "PM Version: ".$version." #".$version->getNumber()." [Protocol ".CURRENT_PROTOCOL."]\r\n";
|
||||
$dump .= "uname -a: ".php_uname("a")."\r\n";
|
||||
$dump .= "PHP Version: " .phpversion()."\r\n";
|
||||
$dump .= "Zend version: ".zend_version()."\r\n";
|
||||
$dump .= "OS : " .PHP_OS.", ".Utils::getOS()."\r\n";
|
||||
$dump .= "Debug Info: ".var_export($this->debugInfo(false), true)."\r\n\r\n\r\n";
|
||||
global $arguments;
|
||||
$dump .= "Parameters: ".var_export($arguments, true)."\r\n\r\n\r\n";
|
||||
$dump .= "server.properties: ".var_export($this->api->getProperties(), true)."\r\n\r\n\r\n";
|
||||
if($this->api->plugin instanceof PluginAPI){
|
||||
$dump .= "Loaded plugins: ".var_export($this->api->plugin->getList(), true)."\r\n\r\n\r\n";
|
||||
}
|
||||
$dump .= "Loaded Modules: ".var_export(get_loaded_extensions(), true)."\r\n\r\n";
|
||||
$name = "error_dump_".time();
|
||||
logg($dump, $name, true, 0, true);
|
||||
console("[ERROR] Please submit the \"logs/{$name}.log\" file to the Bug Reporting page. Give as much info as you can.", true, true, 0);
|
||||
}
|
||||
|
||||
public function tick(){
|
||||
/*if($this->ticker->tick === true and $this->ticker->isWaiting() === true){
|
||||
$this->ticker->tick = false;
|
||||
$time = microtime(true);
|
||||
array_shift($this->tickMeasure);
|
||||
$this->tickMeasure[] = $this->lastTick = $time;
|
||||
$this->tickerFunction($time);
|
||||
$this->trigger("server.tick", $time);
|
||||
$this->ticker->notify();
|
||||
}*/
|
||||
$time = microtime(true);
|
||||
if($this->lastTick <= ($time - 0.05)){
|
||||
array_shift($this->tickMeasure);
|
||||
$this->tickMeasure[] = $this->lastTick = $time;
|
||||
$this->tickerFunction($time);
|
||||
$this->trigger("server.tick", $time);
|
||||
}
|
||||
}
|
||||
|
||||
public function clientID($ip, $port){
|
||||
return md5($ip . $port, true);
|
||||
}
|
||||
|
||||
public function packetHandler($packet){
|
||||
$data =& $packet["data"];
|
||||
$CID = $this->clientID($packet["ip"], $packet["port"]);
|
||||
if(isset($this->clients[$CID])){
|
||||
$this->clients[$CID]->handle($packet["pid"], $data);
|
||||
}else{
|
||||
if($this->handle("server.noauthpacket", $packet) === false){
|
||||
return;
|
||||
}
|
||||
switch($packet["pid"]){
|
||||
case 0x02:
|
||||
if($this->invisible === true){
|
||||
$this->send(0x1c, array(
|
||||
$data[0],
|
||||
$this->serverID,
|
||||
MAGIC,
|
||||
$this->serverType,
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
break;
|
||||
}
|
||||
if($this->api->ban->isIPBanned($packet["ip"])){
|
||||
$this->send(0x1c, array(
|
||||
$data[0],
|
||||
$this->serverID,
|
||||
MAGIC,
|
||||
$this->serverType. $this->name . " [You're banned]",
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
break;
|
||||
}
|
||||
if(!isset($this->custom["times_".$CID])){
|
||||
$this->custom["times_".$CID] = 0;
|
||||
}
|
||||
$ln = 15;
|
||||
if($this->description == "" or substr($this->description, -1) != " "){
|
||||
$this->description .= " ";
|
||||
}
|
||||
$txt = substr($this->description, $this->custom["times_".$CID], $ln);
|
||||
$txt .= substr($this->description, 0, $ln - strlen($txt));
|
||||
$this->send(0x1c, array(
|
||||
$data[0],
|
||||
$this->serverID,
|
||||
MAGIC,
|
||||
$this->serverType. $this->name . " [".($this->gamemode === CREATIVE ? "C":($this->gamemode === ADVENTURE ? "A":"S")).($this->whitelist !== false ? "W":"")." ".count($this->clients)."/".$this->maxClients."] ".$txt,
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
$this->custom["times_".$CID] = ($this->custom["times_".$CID] + 1) % strlen($this->description);
|
||||
break;
|
||||
case 0x05:
|
||||
if($this->api->ban->isIPBanned($packet["ip"]) or count($this->clients) >= $this->maxClients){
|
||||
$this->send(0x80, array(
|
||||
0,
|
||||
0x00,
|
||||
array(
|
||||
"id" => MC_LOGIN_STATUS,
|
||||
"status" => 1,
|
||||
),
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
$this->send(0x80, array(
|
||||
1,
|
||||
0x00,
|
||||
array(
|
||||
"id" => MC_DISCONNECT,
|
||||
),
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
break;
|
||||
}
|
||||
$version = $data[1];
|
||||
$size = strlen($data[2]);
|
||||
if($version !== CURRENT_STRUCTURE){
|
||||
console("[DEBUG] Incorrect structure #$version from ".$packet["ip"].":".$packet["port"], true, true, 2);
|
||||
$this->send(0x1a, array(
|
||||
CURRENT_STRUCTURE,
|
||||
MAGIC,
|
||||
$this->serverID,
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
}else{
|
||||
$this->send(0x06, array(
|
||||
MAGIC,
|
||||
$this->serverID,
|
||||
0,
|
||||
strlen($packet["raw"]),
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
}
|
||||
break;
|
||||
case 0x07:
|
||||
if($this->api->ban->isIPBanned($packet["ip"]) or count($this->clients) >= $this->maxClients){
|
||||
$this->send(0x80, array(
|
||||
0,
|
||||
0x00,
|
||||
array(
|
||||
"id" => MC_LOGIN_STATUS,
|
||||
"status" => 1,
|
||||
),
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
$this->send(0x80, array(
|
||||
1,
|
||||
0x00,
|
||||
array(
|
||||
"id" => MC_DISCONNECT,
|
||||
),
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
break;
|
||||
}
|
||||
$port = $data[2];
|
||||
$MTU = $data[3];
|
||||
$clientID = $data[4];
|
||||
$this->clients[$CID] = new Player($this, $clientID, $packet["ip"], $packet["port"], $MTU); //New Session!
|
||||
$this->clients[$CID]->handle(0x07, $data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function send($pid, $data = array(), $raw = false, $dest = false, $port = false){
|
||||
$this->interface->writePacket($pid, $data, $raw, $dest, $port);
|
||||
}
|
||||
|
||||
public function process(){
|
||||
while($this->stop === false){
|
||||
$packet = $this->interface->readPacket();
|
||||
if($packet !== false){
|
||||
$this->packetHandler($packet);
|
||||
}else{
|
||||
usleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function trigger($event, $data = ""){
|
||||
if(isset($this->events[$event])){
|
||||
foreach($this->events[$event] as $evid => $ev){
|
||||
if(!is_callable($ev)){
|
||||
$this->deleteEvent($evid);
|
||||
continue;
|
||||
}
|
||||
if(is_array($ev)){
|
||||
$method = $ev[1];
|
||||
$ev[0]->$method($data, $event);
|
||||
}else{
|
||||
$ev($data, $event);
|
||||
}
|
||||
}
|
||||
}elseif(isset(Deprecation::$events[$event])){
|
||||
$sub = "";
|
||||
if(Deprecation::$events[$event] !== false){
|
||||
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
|
||||
}
|
||||
console("[ERROR] Event \"$event\" has been deprecated.$sub [Trigger]");
|
||||
}
|
||||
}
|
||||
|
||||
public function schedule($ticks,callable $callback, $data = array(), $repeat = false, $eventName = "server.schedule"){
|
||||
if(!is_callable($callback)){
|
||||
return false;
|
||||
}
|
||||
$add = "";
|
||||
$chcnt = $this->scheduleCnt++;
|
||||
if($repeat === false){
|
||||
$add = '$this->schedule['.$chcnt.']=null;unset($this->schedule['.$chcnt.']);';
|
||||
}
|
||||
$this->schedule[$chcnt] = array($callback, $data, $eventName);
|
||||
$this->action(50000 * $ticks, '$schedule=$this->schedule['.$chcnt.'];'.$add.'if(!is_callable($schedule[0])){$this->schedule['.$chcnt.']=null;unset($this->schedule['.$chcnt.']);return false;}return call_user_func($schedule[0],$schedule[1],$schedule[2]);', (bool) $repeat);
|
||||
return $chcnt;
|
||||
}
|
||||
|
||||
public function action($microseconds, $code, $repeat = true){
|
||||
$this->query("INSERT INTO actions (interval, last, code, repeat) VALUES(".($microseconds / 1000000).", ".microtime(true).", '".base64_encode($code)."', ".($repeat === true ? 1:0).");");
|
||||
console("[INTERNAL] Attached to action ".$microseconds, true, true, 3);
|
||||
}
|
||||
|
||||
public function tickerFunction($time){
|
||||
//actions that repeat every x time will go here
|
||||
$this->preparedSQL->selectActions->reset();
|
||||
$this->preparedSQL->selectActions->clear();
|
||||
$this->preparedSQL->selectActions->bindValue(":time", $time, SQLITE3_FLOAT);
|
||||
$actions = $this->preparedSQL->selectActions->execute();
|
||||
|
||||
if($actions === false or $actions === true){
|
||||
return;
|
||||
}
|
||||
while(($action = $actions->fetchArray(SQLITE3_ASSOC)) !== false){
|
||||
$return = eval(base64_decode($action["code"]));
|
||||
if($action["repeat"] === 0 or $return === false){
|
||||
$this->query("DELETE FROM actions WHERE ID = ".$action["ID"].";");
|
||||
}
|
||||
}
|
||||
$actions->finalize();
|
||||
$this->preparedSQL->updateActions->reset();
|
||||
$this->preparedSQL->updateActions->clear();
|
||||
$this->preparedSQL->updateActions->bindValue(":time", $time, SQLITE3_FLOAT);
|
||||
$this->preparedSQL->updateActions->execute();
|
||||
}
|
||||
|
||||
public function event($event,callable $func){
|
||||
if(!is_callable($func)){
|
||||
return false;
|
||||
}elseif(isset(Deprecation::$events[$event])){
|
||||
$sub = "";
|
||||
if(Deprecation::$events[$event] !== false){
|
||||
$sub = " Substitute \"".Deprecation::$events[$event]."\" found.";
|
||||
}
|
||||
console("[ERROR] Event \"$event\" has been deprecated.$sub [Attach to ".(is_array($func) ? get_class($func[0])."::".$func[1]:$func)."]");
|
||||
}
|
||||
$evid = $this->evCnt++;
|
||||
if(!isset($this->events[$event])){
|
||||
$this->events[$event] = array();
|
||||
}
|
||||
$this->events[$event][$evid] = $func;
|
||||
$this->eventsID[$evid] = $event;
|
||||
console("[INTERNAL] Attached ".(is_array($func) ? get_class($func[0])."::".$func[1]:$func)." to event ".$event." (ID ".$evid.")", true, true, 3);
|
||||
return $evid;
|
||||
}
|
||||
|
||||
public function deleteEvent($id){
|
||||
$id = (int) $id;
|
||||
if(isset($this->eventsID[$id])){
|
||||
$ev = $this->eventsID[$id];
|
||||
$this->eventsID[$id] = null;
|
||||
unset($this->eventsID[$id]);
|
||||
$this->events[$ev][$id] = null;
|
||||
unset($this->events[$ev][$id]);
|
||||
if(count($this->events[$ev]) === 0){
|
||||
unset($this->events[$ev]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
51
src/config.php
Normal file
51
src/config.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
set_time_limit(0);
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
gc_enable();
|
||||
error_reporting(E_ALL ^ E_NOTICE);
|
||||
ini_set("allow_url_fopen", 1);
|
||||
ini_set("display_errors", 1);
|
||||
ini_set('default_charset', 'utf-8');
|
||||
if(defined("POCKETMINE_COMPILE") and POCKETMINE_COMPILE === true){
|
||||
define("FILE_PATH", realpath(dirname(__FILE__))."/");
|
||||
}else{
|
||||
define("FILE_PATH", realpath(dirname(__FILE__)."/../")."/");
|
||||
}
|
||||
set_include_path(get_include_path() . PATH_SEPARATOR . FILE_PATH);
|
||||
|
||||
ini_set("memory_limit", "256M"); //Default
|
||||
define("LOG", true);
|
||||
define("MAGIC", "\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78");
|
||||
define("TEST_MD5", "ffe889db5932db1e3371d48773590e59");
|
||||
define("MAJOR_VERSION", "Alpha_1.2.2");
|
||||
define("CURRENT_STRUCTURE", 5);
|
||||
define("CURRENT_PROTOCOL", 9);
|
||||
define("CURRENT_MINECRAFT_VERSION", "v0.6.1 alpha");
|
||||
define("CURRENT_API_VERSION", 5);
|
||||
define("CURRENT_PHP_VERSION", "5.4.13");
|
158
src/constants/BlockIDs.php
Normal file
158
src/constants/BlockIDs.php
Normal file
@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
define("AIR", 0);
|
||||
define("STONE", 1);
|
||||
define("GRASS", 2);
|
||||
define("DIRT", 3);
|
||||
define("COBBLESTONE", 4);
|
||||
define("COBBLE", 4);
|
||||
define("PLANK", 5);
|
||||
define("PLANKS", 5);
|
||||
define("WOODEN_PLANK", 5);
|
||||
define("SAPLING", 6);
|
||||
define("SAPLINGS", 6);
|
||||
define("BEDROCK", 7);
|
||||
define("WATER", 8);
|
||||
define("STILL_WATER", 9);
|
||||
define("LAVA", 10);
|
||||
define("STILL_LAVA", 11);
|
||||
define("SAND", 12);
|
||||
define("GRAVEL", 13);
|
||||
define("GOLD_ORE", 14);
|
||||
define("IRON_ORE", 15);
|
||||
define("COAL_ORE", 16);
|
||||
define("WOOD", 17);
|
||||
define("TRUNK", 17);
|
||||
define("LEAVES", 18);
|
||||
define("LEAVE", 18);
|
||||
|
||||
define("GLASS", 20);
|
||||
define("LAPIS_ORE", 21);
|
||||
define("LAPIS_BLOCK", 22);
|
||||
|
||||
define("SANDSTONE", 24);
|
||||
|
||||
define("BED_BLOCK", 26);
|
||||
|
||||
|
||||
define("COBWEB", 30);
|
||||
define("TALL_GRASS", 31);
|
||||
define("BUSH", 32);
|
||||
define("DEAD_BUSH", 32);
|
||||
define("WOOL", 35);
|
||||
define("DANDELION", 37);
|
||||
define("ROSE", 38);
|
||||
define("CYAN_FLOWER", 38);
|
||||
define("BROWN_MUSHROOM", 39);
|
||||
define("RED_MUSHROOM", 40);
|
||||
define("GOLD_BLOCK", 41);
|
||||
define("IRON_BLOCK", 42);
|
||||
define("DOUBLE_SLAB", 43);
|
||||
define("DOUBLE_SLABS", 43);
|
||||
define("SLAB", 44);
|
||||
define("SLABS", 44);
|
||||
define("BRICKS", 45);
|
||||
define("BRICKS_BLOCK", 45);
|
||||
define("TNT", 46);
|
||||
define("BOOKSHELF", 47);
|
||||
define("MOSS_STONE", 48);
|
||||
define("MOSSY_STONE", 48);
|
||||
define("OBSIDIAN", 49);
|
||||
define("TORCH", 50);
|
||||
define("FIRE", 51);
|
||||
|
||||
define("WOOD_STAIRS", 53);
|
||||
define("WOODEN_STAIRS", 53);
|
||||
define("CHEST", 54);
|
||||
|
||||
define("DIAMOND_ORE", 56);
|
||||
define("DIAMOND_BLOCK", 57);
|
||||
define("CRAFTING_TABLE", 58);
|
||||
define("WORKBENCH", 58);
|
||||
define("WHEAT_BLOCK", 59);
|
||||
define("FARMLAND", 60);
|
||||
define("FURNACE", 61);
|
||||
define("BURNING_FURNACE", 62);
|
||||
define("LIT_FURNACE", 62);
|
||||
define("SIGN_POST", 63);
|
||||
define("DOOR_BLOCK", 64);
|
||||
define("WOODEN_DOOR_BLOCK", 64);
|
||||
define("WOOD_DOOR_BLOCK", 64);
|
||||
define("LADDER", 65);
|
||||
|
||||
define("COBBLE_STAIRS", 67);
|
||||
define("COBBLESTONE_STAIRS", 67);
|
||||
define("WALL_SIGN", 68);
|
||||
|
||||
define("IRON_DOOR_BLOCK", 71);
|
||||
|
||||
define("REDSTONE_ORE", 73);
|
||||
define("GLOWING_REDSTONE_ORE", 74);
|
||||
define("LIT_REDSTONE_ORE", 74);
|
||||
|
||||
define("SNOW", 78);
|
||||
define("SNOW_LAYER", 78);
|
||||
define("ICE", 79);
|
||||
define("SNOW_BLOCK", 80);
|
||||
define("CACTUS", 81);
|
||||
define("CLAY_BLOCK", 82);
|
||||
define("SUGARCANE_BLOCK", 83);
|
||||
|
||||
define("FENCE", 85);
|
||||
|
||||
define("NETHERRACK", 87);
|
||||
define("SOUL_SAND", 88);
|
||||
define("GLOWSTONE_BLOCK", 89);
|
||||
|
||||
define("TRAPDOOR", 96);
|
||||
|
||||
define("STONE_BRICKS", 98);
|
||||
define("STONE_BRICK", 98);
|
||||
|
||||
define("GLASS_PANE", 102);
|
||||
define("GLASS_PANEL", 102);
|
||||
define("MELON_BLOCK", 103);
|
||||
|
||||
define("MELON_STEM", 105);
|
||||
|
||||
define("FENCE_GATE", 107);
|
||||
define("BRICK_STAIRS", 108);
|
||||
define("STONE_BRICK_STAIRS", 109);
|
||||
|
||||
define("NETHER_BRICKS", 112);
|
||||
|
||||
define("NETHER_BRICKS_STAIRS", 114);
|
||||
|
||||
define("SANDSTONE_STAIRS", 128);
|
||||
|
||||
define("QUARTZ_BLOCK", 155);
|
||||
define("QUARTZ_STAIRS", 156);
|
||||
|
||||
define("STONECUTTER", 245);
|
||||
define("GLOWING_OBSIDIAN", 246);
|
||||
define("NETHER_REACTOR", 247);
|
31
src/constants/GeneralConstants.php
Normal file
31
src/constants/GeneralConstants.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
//Gamemodes
|
||||
define("SURVIVAL", 0);
|
||||
define("CREATIVE", 1);
|
||||
define("ADVENTURE", 2);
|
145
src/constants/ItemIDs.php
Normal file
145
src/constants/ItemIDs.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
define("IRON_SHOVEL", 256);//Implemented
|
||||
define("IRON_PICKAXE", 257);//Implemented
|
||||
define("IRON_AXE", 258);//Implemented
|
||||
define("FLINT_STEEL", 259);
|
||||
define("APPLE", 260);//Implemented
|
||||
define("BOW", 261);
|
||||
define("ARROW", 262);
|
||||
define("COAL", 263);//Implemented
|
||||
define("DIAMOND", 264);//Implemented
|
||||
define("IRON_INGOT", 265);//Implemented
|
||||
define("GOLD_INGOT", 266);//Implemented
|
||||
define("IRON_SWORD", 267);
|
||||
define("WOODEN_SWORD", 268);
|
||||
define("WOODEN_SHOVEL", 269);
|
||||
define("WOODEN_PICKAXE", 270);
|
||||
define("WOODEN_AXE", 271);
|
||||
define("STONE_SWORD", 272);
|
||||
define("STONE_SHOVEL", 273);
|
||||
define("STONE_PICKAXE", 274);
|
||||
define("STONE_AXE", 275);
|
||||
define("DIAMOND_SWORD", 276);
|
||||
define("DIAMOND_SHOVEL", 277);
|
||||
define("DIAMOND_PICKAXE", 278);
|
||||
define("DIAMOND_AXE", 279);
|
||||
define("STICK", 280);//Implemented
|
||||
define("BOWL", 281);//Implemented
|
||||
define("MUSHROOM_STEW", 282);
|
||||
define("GOLD_SWORD", 283);
|
||||
define("GOLD_SHOVEL", 284);
|
||||
define("GOLD_PICKAXE", 285);
|
||||
define("GOLD_AXE", 286);
|
||||
define("STRING", 287);
|
||||
define("FEATHER", 288);//Implemented
|
||||
define("GUNPOWDER", 289);
|
||||
define("WOODEN_HOE", 290);
|
||||
define("STONE_HOE", 291);
|
||||
define("IRON_HOE", 292);//Implemented
|
||||
define("DIAMOND_HOE", 293);
|
||||
define("GOLD_HOE", 294);
|
||||
define("SEEDS", 295);
|
||||
define("WHEAT_SEEDS", 295);
|
||||
define("WHEAT", 296);
|
||||
define("BREAD", 297);
|
||||
define("LEATHER_CAP", 298);
|
||||
define("LEATHER_TUNIC", 299);
|
||||
define("LEATHER_PANTS", 300);
|
||||
define("LEATHER_BOOTS", 301);
|
||||
define("CHAIN_HELMET", 302);
|
||||
define("CHAIN_CHESTPLATE", 303);
|
||||
define("CHAIN_LEGGINS", 304);
|
||||
define("CHAIN_BOOTS", 305);
|
||||
define("IRON_HELMET", 306);
|
||||
define("IRON_CHESTPLATE", 307);
|
||||
define("IRON_LEGGINS", 308);
|
||||
define("IRON_BOOTS", 309);
|
||||
define("DIAMOND_HELMET", 310);
|
||||
define("DIAMOND_CHESTPLATE", 311);
|
||||
define("DIAMOND_LEGGINS", 312);
|
||||
define("DIAMOND_BOOTS", 313);
|
||||
define("GOLD_HELMET", 314);
|
||||
define("GOLD_CHESTPLATE", 315);
|
||||
define("GOLD_LEGGINS", 316);
|
||||
define("GOLD_BOOTS", 317);
|
||||
define("FLINT", 318);
|
||||
define("RAW_PORKCHOP", 319);
|
||||
define("COOKED_PORKCHOP", 320);
|
||||
define("PAINTING", 321);
|
||||
define("GOLDEN_APPLE", 322);
|
||||
define("SIGN", 323);
|
||||
define("WOODEN_DOOR", 324);
|
||||
|
||||
define("IRON_DOOR", 330);
|
||||
|
||||
define("SNOWBALL", 332);
|
||||
|
||||
define("LEATHER", 334);
|
||||
|
||||
define("BRICK", 336);
|
||||
define("CLAY", 337);
|
||||
define("SUGARCANE", 338);
|
||||
define("SUGAR_CANE", 338);
|
||||
define("SUGAR_CANES", 338);
|
||||
define("PAPER", 339);
|
||||
define("SLIMEBALL", 341);
|
||||
|
||||
define("EGG", 344);
|
||||
define("COMPASS", 345);
|
||||
|
||||
define("GLOWSTONE_DUST", 348);
|
||||
define("RAW_FISH", 349);
|
||||
define("COOKED_FISH", 350);
|
||||
define("DYE", 351);
|
||||
define("BONE", 352);
|
||||
define("SUGAR", 353);
|
||||
|
||||
define("BED", 355);
|
||||
|
||||
|
||||
define("COOKIE", 357);
|
||||
|
||||
|
||||
define("SHEARS", 359);
|
||||
define("MELON", 360);
|
||||
define("MELON_SLICE", 360);
|
||||
|
||||
define("MELON_SEEDS", 362);
|
||||
define("RAW_BEEF", 363);
|
||||
define("STEAK", 364);
|
||||
define("COOKED_BEEF", 364);
|
||||
|
||||
define("RAW_CHICKEN", 365);
|
||||
define("COOKED_CHICKEN", 366);
|
||||
|
||||
define("NETHER_BRICK", 405);
|
||||
define("QUARTZ", 406);
|
||||
define("NETHER_QUARTZ", 406);
|
||||
|
||||
define("CAMERA", 456);
|
346
src/constants/ProtocolInfo.php
Normal file
346
src/constants/ProtocolInfo.php
Normal file
@ -0,0 +1,346 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
define("MC_KEEP_ALIVE", 0x00);
|
||||
|
||||
define("MC_CLIENT_CONNECT", 0x09);
|
||||
define("MC_SERVER_HANDSHAKE", 0x10);
|
||||
|
||||
define("MC_CLIENT_HANDSHAKE", 0x13);
|
||||
|
||||
define("MC_DISCONNECT", 0x15);
|
||||
|
||||
define("MC_LOGIN", 0x82);
|
||||
define("MC_LOGIN_STATUS", 0x83);
|
||||
define("MC_READY", 0x84);
|
||||
define("MC_CHAT", 0x85);
|
||||
define("MC_SET_TIME", 0x86);
|
||||
define("MC_START_GAME", 0x87);
|
||||
define("MC_ADD_MOB", 0x88);
|
||||
define("MC_ADD_PLAYER", 0x89);
|
||||
//define("MC_REMOVE_PLAYER", 0x8a);
|
||||
|
||||
define("MC_ADD_ENTITY", 0x8c);
|
||||
define("MC_REMOVE_ENTITY", 0x8d);
|
||||
define("MC_ADD_ITEM_ENTITY", 0x8e);
|
||||
define("MC_TAKE_ITEM_ENTITY", 0x8f);
|
||||
define("MC_MOVE_ENTITY", 0x90);
|
||||
|
||||
define("MC_MOVE_ENTITY_POSROT", 0x93);
|
||||
define("MC_MOVE_PLAYER", 0x94);
|
||||
define("MC_PLACE_BLOCK", 0x95);
|
||||
define("MC_REMOVE_BLOCK", 0x96);
|
||||
define("MC_UPDATE_BLOCK", 0x97);
|
||||
define("MC_ADD_PAINTING", 0x98);
|
||||
define("MC_EXPLOSION", 0x99);
|
||||
define("MC_LEVEL_EVENT", 0x9a);
|
||||
//define("MC_TILE_EVENT", 0x9b);
|
||||
define("MC_ENTITY_EVENT", 0x9c);
|
||||
define("MC_REQUEST_CHUNK", 0x9d);
|
||||
define("MC_CHUNK_DATA", 0x9e);
|
||||
define("MC_PLAYER_EQUIPMENT", 0x9f);
|
||||
define("MC_PLAYER_ARMOR_EQUIPMENT", 0xa0);
|
||||
define("MC_INTERACT", 0xa1);
|
||||
define("MC_USE_ITEM", 0xa2);
|
||||
define("MC_PLAYER_ACTION", 0xa3);
|
||||
|
||||
define("MC_HURT_ARMOR", 0xa5);
|
||||
define("MC_SET_ENTITY_DATA", 0xa6);
|
||||
define("MC_SET_ENTITY_MOTION", 0xa7);
|
||||
define("MC_SET_HEALTH", 0xa8);
|
||||
define("MC_SET_SPAWN_POSITION", 0xa9);
|
||||
define("MC_ANIMATE", 0xaa);
|
||||
define("MC_RESPAWN", 0xab);
|
||||
define("MC_SEND_INVENTORY", 0xac);
|
||||
define("MC_DROP_ITEM", 0xad);
|
||||
define("MC_CONTAINER_OPEN", 0xae);
|
||||
define("MC_CONTAINER_CLOSE", 0xaf);
|
||||
define("MC_CONTAINER_SET_SLOT", 0xb0);
|
||||
//define("MC_CONTAINER_SET_DATA", 0xb1);
|
||||
//define("MC_CONTAINER_SET_CONTENT", 0xb2);
|
||||
//define("MC_CONTAINER_ACK", 0xb3);
|
||||
define("MC_CLIENT_MESSAGE", 0xb4);
|
||||
define("MC_SIGN_UPDATE", 0xb5);
|
||||
define("MC_ADVENTURE_SETTINGS", 0xb6);
|
||||
|
||||
|
||||
class Protocol{
|
||||
public static $dataName = array(
|
||||
MC_KEEP_ALIVE => "Keep Alive",
|
||||
|
||||
MC_CLIENT_CONNECT => "Client Connect",
|
||||
MC_SERVER_HANDSHAKE => "Server Handshake",
|
||||
|
||||
MC_CLIENT_HANDSHAKE => "Client Handshake",
|
||||
|
||||
MC_DISCONNECT => "Disconnect",
|
||||
|
||||
0x18 => "Unknown",
|
||||
|
||||
MC_LOGIN => "Login",
|
||||
MC_LOGIN_STATUS => "Login Status",
|
||||
MC_READY => "Ready",
|
||||
MC_CHAT => "Chat",
|
||||
MC_SET_TIME => "Set Time",
|
||||
MC_START_GAME => "Start Game",
|
||||
|
||||
MC_ADD_MOB => "Add Mob",
|
||||
MC_ADD_PLAYER => "Add Player",
|
||||
|
||||
MC_ADD_ENTITY => "Add Entity",
|
||||
MC_REMOVE_ENTITY => "Remove Entity",
|
||||
MC_ADD_ITEM_ENTITY => "Add Item",
|
||||
MC_TAKE_ITEM_ENTITY => "Take Item",
|
||||
|
||||
MC_MOVE_ENTITY => "Move Entity",
|
||||
|
||||
MC_MOVE_ENTITY_POSROT => "Move Entity PosRot",
|
||||
MC_MOVE_PLAYER => "Move Player",
|
||||
MC_PLACE_BLOCK => "Place Block",
|
||||
MC_REMOVE_BLOCK => "Remove Block",
|
||||
MC_UPDATE_BLOCK => "Update Block",
|
||||
MC_ADD_PAINTING => "Add Painting",
|
||||
MC_EXPLOSION => "Explosion",
|
||||
|
||||
MC_LEVEL_EVENT => "Level Event",
|
||||
|
||||
MC_ENTITY_EVENT => "Entity Event",
|
||||
MC_REQUEST_CHUNK => "Chunk Request",
|
||||
MC_CHUNK_DATA => "Chunk Data",
|
||||
|
||||
MC_PLAYER_EQUIPMENT => "Player Equipment",
|
||||
MC_PLAYER_ARMOR_EQUIPMENT => "Player Armor",
|
||||
MC_INTERACT => "Interact",
|
||||
MC_USE_ITEM => "Use Item",
|
||||
MC_PLAYER_ACTION => "Player Action",
|
||||
MC_SET_ENTITY_DATA => "Entity Data",
|
||||
MC_SET_ENTITY_MOTION => "Entity Motion",
|
||||
MC_HURT_ARMOR => "Hurt Armor",
|
||||
MC_SET_HEALTH => "Set Health",
|
||||
MC_SET_SPAWN_POSITION => "Set Spawn Position",
|
||||
MC_ANIMATE => "Animate",
|
||||
MC_RESPAWN => "Respawn",
|
||||
MC_SEND_INVENTORY => "Send Inventory",
|
||||
MC_DROP_ITEM => "Drop Item",
|
||||
MC_CONTAINER_OPEN => "Open Container",
|
||||
MC_CONTAINER_CLOSE => "Close Container",
|
||||
MC_CONTAINER_SET_SLOT => "Set Container Slot",
|
||||
|
||||
MC_CLIENT_MESSAGE => "Client Message",
|
||||
MC_SIGN_UPDATE => "Sign Update",
|
||||
MC_ADVENTURE_SETTINGS => "Adventure Settings",
|
||||
);
|
||||
|
||||
public static $packetName = array(
|
||||
0x02 => "ID_UNCONNECTED_PING_OPEN_CONNECTIONS", //RakNet
|
||||
0x05 => "ID_OPEN_CONNECTION_REQUEST_1", //RakNet
|
||||
0x06 => "ID_OPEN_CONNECTION_REPLY_1", //RakNet
|
||||
0x07 => "ID_OPEN_CONNECTION_REQUEST_2", //RakNet
|
||||
0x08 => "ID_OPEN_CONNECTION_REPLY_2", //RakNet
|
||||
0x1a => "ID_INCOMPATIBLE_PROTOCOL_VERSION", //RakNet
|
||||
0x1c => "ID_UNCONNECTED_PONG", //RakNet
|
||||
0x1d => "ID_ADVERTISE_SYSTEM", //RakNet
|
||||
0x80 => "Custom Packet", //Minecraft Implementation
|
||||
0x84 => "Custom Packet", //Minecraft Implementation
|
||||
0x88 => "Custom Packet", //Minecraft Implementation
|
||||
0x8c => "Custom Packet", //Minecraft Implementation
|
||||
0xa0 => "NACK", //Minecraft Implementation
|
||||
0xc0 => "ACK", //Minecraft Implementation
|
||||
);
|
||||
|
||||
public static $raknet = array(
|
||||
0x02 => array(
|
||||
"long", //Ping ID
|
||||
"magic",
|
||||
),
|
||||
|
||||
0x05 => array(
|
||||
"magic",
|
||||
"byte", //Protocol Version
|
||||
"special1", //MTU Size Null Lenght
|
||||
),
|
||||
|
||||
0x06 => array(
|
||||
"magic",
|
||||
"long", //Server GUID
|
||||
"byte", //Server Security
|
||||
"short", //MTU Size
|
||||
),
|
||||
|
||||
0x07 => array(
|
||||
"magic",
|
||||
5, //Security Cookie (idk why it's sent here)
|
||||
"short", //Server UDP Port
|
||||
"short", //MTU Size
|
||||
"long", //Client GUID
|
||||
),
|
||||
|
||||
0x08 => array(
|
||||
"magic",
|
||||
"long", //Server GUID
|
||||
"short", //Client UDP Port
|
||||
"short", //MTU Size
|
||||
"byte", //Security
|
||||
),
|
||||
|
||||
0x1a => array(
|
||||
"byte", //Server Version
|
||||
"magic",
|
||||
"long", //Server GUID
|
||||
),
|
||||
|
||||
0x1c => array(
|
||||
"long", //Ping ID
|
||||
"long", //Server GUID
|
||||
"magic",
|
||||
"string", //Data
|
||||
),
|
||||
|
||||
0x1d => array(
|
||||
"long", //Ping ID
|
||||
"long", //Server GUID
|
||||
"magic",
|
||||
"string", //Data
|
||||
),
|
||||
|
||||
0x80 => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
|
||||
0x81 => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x82 => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x83 => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x84 => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x85 => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x86 => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x87 => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x88 => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x89 => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x8a => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x8b => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x8c => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x8d => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x8e => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
0x8f => array(
|
||||
"itriad",
|
||||
"ubyte",
|
||||
"customData",
|
||||
),
|
||||
|
||||
|
||||
|
||||
0xa0 => array(
|
||||
"short",
|
||||
"bool",
|
||||
"itriad",
|
||||
"special1",
|
||||
),
|
||||
|
||||
0xc0 => array(
|
||||
"short",
|
||||
"bool",
|
||||
"itriad",
|
||||
"special1",
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
}
|
96
src/dependencies.php
Normal file
96
src/dependencies.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/***REM_START***/
|
||||
require_once(dirname(__FILE__)."/config.php");
|
||||
require_once(FILE_PATH."/src/functions.php");
|
||||
/***REM_END***/
|
||||
define(DATA_PATH, realpath(arg("data-path", FILE_PATH))."/");
|
||||
|
||||
if(strpos(strtoupper(php_uname("s")), "WIN") === false or arg("enable-ansi", false) === true){
|
||||
define("ENABLE_ANSI", true);
|
||||
}else{
|
||||
define("ENABLE_ANSI", false);
|
||||
}
|
||||
set_error_handler("fatal_handler", E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_RECOVERABLE_ERROR | E_DEPRECATED);
|
||||
|
||||
$errors = 0;
|
||||
|
||||
if(version_compare("5.4.0", PHP_VERSION) > 0){
|
||||
console("[ERROR] Use PHP >= 5.4.0", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(version_compare(CURRENT_PHP_VERSION, PHP_VERSION) > 0){
|
||||
console("[NOTICE] PocketMine-MP hasn't been tested with PHP < ".CURRENT_PHP_VERSION, true, true, 0);
|
||||
}elseif(version_compare(CURRENT_PHP_VERSION, PHP_VERSION) < 0){
|
||||
console("[NOTICE] PocketMine-MP hasn't been tested with PHP > ".CURRENT_PHP_VERSION, true, true, 0);
|
||||
}
|
||||
|
||||
if(php_sapi_name() !== "cli"){
|
||||
console("[ERROR] You must run PocketMine-MP using the CLI.", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("sockets") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "sockets." . PHP_SHLIB_SUFFIX) === false){
|
||||
console("[ERROR] Unable to find the Socket extension.", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("pthreads") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "pthreads." . PHP_SHLIB_SUFFIX) === false){
|
||||
console("[ERROR] Unable to find the pthreads extension.", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("curl") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "curl." . PHP_SHLIB_SUFFIX) === false){
|
||||
console("[ERROR] Unable to find the cURL extension.", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("sqlite3") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "sqlite3." . PHP_SHLIB_SUFFIX) === false){
|
||||
console("[ERROR] Unable to find the SQLite3 extension.", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("zlib") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "zlib." . PHP_SHLIB_SUFFIX) === false){
|
||||
console("[ERROR] Unable to find the Zlib extension.", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("gmp") and @dl((PHP_SHLIB_SUFFIX === "dll" ? "php_":"") . "gmp." . PHP_SHLIB_SUFFIX) === false){
|
||||
console("[ERROR] Unable to find the GMP extension.", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if($errors > 0){
|
||||
console("[ERROR] Please use the installer provided on the homepage.", true, true, 0);
|
||||
exit(1); //Exit with error
|
||||
}
|
||||
|
||||
/***REM_START***/
|
||||
require_all(FILE_PATH . "src/");
|
||||
/***REM_END***/
|
230
src/functions.php
Normal file
230
src/functions.php
Normal file
@ -0,0 +1,230 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
function kill($pid){
|
||||
switch(Utils::getOS()){
|
||||
case "win":
|
||||
ob_start();
|
||||
passthru("%WINDIR%\\System32\\taskkill.exe /F /PID ".((int) $pid));
|
||||
ob_end_clean();
|
||||
break;
|
||||
case "mac":
|
||||
case "linux":
|
||||
default:
|
||||
ob_start();
|
||||
passthru("kill -9 ".((int) $pid));
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function require_all($path, &$count = 0){
|
||||
$dir = dir($path."/");
|
||||
$dirs = array();
|
||||
while(false !== ($file = $dir->read())){
|
||||
if($file !== "." and $file !== ".."){
|
||||
if(!is_dir($path.$file) and strtolower(substr($file, -3)) === "php"){
|
||||
require_once($path.$file);
|
||||
++$count;
|
||||
}elseif(is_dir($path.$file)){
|
||||
$dirs[] = $path.$file."/";
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach($dirs as $dir){
|
||||
require_all($dir, $count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function hard_unset(&$var){
|
||||
if(is_object($var)){
|
||||
$unset = new ReflectionClass($var);
|
||||
foreach($unset->getProperties() as $prop){
|
||||
$prop->setAccessible(true);
|
||||
@hard_unset($prop->getValue($var));
|
||||
$prop->setValue($var, null);
|
||||
}
|
||||
$var = null;
|
||||
unset($var);
|
||||
}elseif(is_array($var)){
|
||||
foreach($var as $i => $v){
|
||||
hard_unset($var[$i]);
|
||||
}
|
||||
$var = null;
|
||||
unset($var);
|
||||
}else{
|
||||
$var = null;
|
||||
unset($var);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function parseNBTData($data){
|
||||
$x = array();
|
||||
if(isset($data["value"])){
|
||||
return parseNBTData($data["value"]);
|
||||
}
|
||||
foreach($data as $d){
|
||||
if(!isset($d["value"]) and is_array($d) and count($d) == 1){
|
||||
return parseNBTData(array_pop($d));
|
||||
}elseif(!isset($d["value"]) and is_array($d)){
|
||||
$x[] = parseNBTData($d);
|
||||
}elseif(is_array($d["value"]) and isset($d["name"])){
|
||||
$x[$d["name"]] = parseNBTData($d["value"]);
|
||||
}elseif(is_array($d["value"]) and $d["type"] == 10){
|
||||
return parseNBTData($d["value"]);
|
||||
}elseif($d["name"] != ""){
|
||||
$x[$d["name"]] = $d["value"];
|
||||
}
|
||||
}
|
||||
if(count($x) == 0){
|
||||
$x = $data;
|
||||
}
|
||||
return $x;
|
||||
}
|
||||
|
||||
|
||||
function arg($name, $default = false){
|
||||
global $arguments, $argv;
|
||||
if(!isset($arguments)){
|
||||
$arguments = arguments($argv);
|
||||
}
|
||||
|
||||
if(isset($arguments["commands"][$name])){
|
||||
return $arguments["commands"][$name];
|
||||
}else{
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
function arguments ( $args ){
|
||||
if(!is_array($args)){
|
||||
$args = array();
|
||||
}
|
||||
array_shift( $args );
|
||||
$args = join( $args, ' ' );
|
||||
|
||||
preg_match_all('/ (--[\w\-]+ (?:[= ] [^-]+ [^\s-] )? ) | (-\w+) | (\w+) /x', $args, $match );
|
||||
$args = array_shift( $match );
|
||||
|
||||
$ret = array(
|
||||
'input' => array(),
|
||||
'commands' => array(),
|
||||
'flags' => array()
|
||||
);
|
||||
|
||||
foreach ( $args as $arg ) {
|
||||
|
||||
// Is it a command? (prefixed with --)
|
||||
if ( substr( $arg, 0, 2 ) === '--' ) {
|
||||
|
||||
$value = preg_split( '/[= ]/', $arg, 2 );
|
||||
$com = substr( array_shift($value), 2 );
|
||||
$value = join($value);
|
||||
|
||||
$ret['commands'][$com] = !empty($value) ? $value : true;
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
// Is it a flag? (prefixed with -)
|
||||
if ( substr( $arg, 0, 1 ) === '-' ) {
|
||||
$ret['flags'][] = substr( $arg, 1 );
|
||||
continue;
|
||||
}
|
||||
|
||||
$ret['input'][] = $arg;
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function console($message, $EOL = true, $log = true, $level = 1){
|
||||
if(!defined("DEBUG") or DEBUG >= $level){
|
||||
$message .= $EOL === true ? PHP_EOL:"";
|
||||
$time = (ENABLE_ANSI === true ? "\x1b[36m".date("H:i:s")."\x1b[0m":date("H:i:s")) . " ";
|
||||
$replaced = preg_replace('/\x1b\[[0-9;]*m/', "", $time . $message);
|
||||
if($log === true and (!defined("LOG") or LOG === true)){
|
||||
logg($replaced, "console", false, $level);
|
||||
}
|
||||
if(ENABLE_ANSI === true){
|
||||
if(preg_match("/\[([a-zA-Z0-9]*)\]/", $message, $matches) > 0){
|
||||
$add = "\x1b";
|
||||
switch($matches[1]){
|
||||
case "ERROR":
|
||||
$add .= "[31;1m";
|
||||
break;
|
||||
case "INTERNAL":
|
||||
case "DEBUG":
|
||||
$add .= "[30;1m";
|
||||
break;
|
||||
case "WARNING":
|
||||
$add .= "[33;1m";
|
||||
break;
|
||||
case "NOTICE":
|
||||
$add .= "[37;1m";
|
||||
break;
|
||||
default:
|
||||
$add = "";
|
||||
break;
|
||||
}
|
||||
$message = $time . $add . $message . "\x1b[0m";
|
||||
}
|
||||
}else{
|
||||
$message = $replaced;
|
||||
}
|
||||
echo $message;
|
||||
}
|
||||
}
|
||||
|
||||
function fatal_handler($errno, $errstr, $errfile, $errline){
|
||||
console("[ERROR] A level ".$errno." error happened: \"$errstr\" in \"$errfile\" at line $errline", true, true, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
function logg($message, $name, $EOL = true, $level = 2, $close = false){
|
||||
global $fpointers;
|
||||
if((!defined("DEBUG") or DEBUG >= $level) and (!defined("LOG") or LOG === true)){
|
||||
$message .= $EOL === true ? PHP_EOL:"";
|
||||
if(!isset($fpointers)){
|
||||
$fpointers = array();
|
||||
}
|
||||
if(!isset($fpointers[$name]) or $fpointers[$name] === false){
|
||||
$fpointers[$name] = @fopen(DATA_PATH."logs/".$name.".log", "ab");
|
||||
}
|
||||
@fwrite($fpointers[$name], $message);
|
||||
if($close === true){
|
||||
fclose($fpointers[$name]);
|
||||
unset($fpointers[$name]);
|
||||
}
|
||||
}
|
||||
}
|
39
src/inventory/Window.php
Normal file
39
src/inventory/Window.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
define("WINDOW_CHEST", 0);
|
||||
define("WINDOW_WORKBENCH", 1);
|
||||
define("WINDOW_FURNACE", 2);
|
||||
|
||||
class Window{
|
||||
private $server;
|
||||
public function __construct(PocketMinecraftServer $server){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
221
src/material/Block.php
Normal file
221
src/material/Block.php
Normal file
@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/***REM_START***/
|
||||
require_once(FILE_PATH."/src/math/Vector3.php");
|
||||
/***REM_END***/
|
||||
|
||||
abstract class Block extends Vector3{
|
||||
public static $class = array(
|
||||
AIR => "AirBlock",
|
||||
STONE => "StoneBlock",
|
||||
GRASS => "GrassBlock",
|
||||
DIRT => "DirtBlock",
|
||||
COBBLESTONE => "CobblestoneBlock",
|
||||
PLANKS => "PlanksBlock",
|
||||
SAPLING => "SaplingBlock",
|
||||
BEDROCK => "BedrockBlock",
|
||||
WATER => "WaterBlock",
|
||||
STILL_WATER => "StillWaterBlock",
|
||||
LAVA => "LavaBlock",
|
||||
STILL_LAVA => "StillLavaBlock",
|
||||
SAND => "SandBlock",
|
||||
GRAVEL => "GravelBlock",
|
||||
GOLD_ORE => "GoldOreBlock",
|
||||
IRON_ORE => "IronOreBlock",
|
||||
COAL_ORE => "CoalOreBlock",
|
||||
WOOD => "WoodBlock",
|
||||
LEAVES => "LeavesBlock",
|
||||
GLASS => "GlassBlock",
|
||||
LAPIS_ORE => "LapisOreBlock",
|
||||
LAPIS_BLOCK => "LapisBlock",
|
||||
SANDSTONE => "SandstoneBlock",
|
||||
BED_BLOCK => "BedBlock",
|
||||
COBWEB => "CobwebBlock",
|
||||
TALL_GRASS => "TallGrassBlock",
|
||||
DEAD_BUSH => "DeadBushBlock",
|
||||
WOOL => "WoolBlock",
|
||||
DANDELION => "DandelionBlock",
|
||||
CYAN_FLOWER => "CyanFlowerBlock",
|
||||
BROWN_MUSHROOM => "BrownMushroomBlock",
|
||||
RED_MUSHROOM => "RedMushRoomBlock",
|
||||
GOLD_BLOCK => "GoldBlock",
|
||||
IRON_BLOCK => "IronBlock",
|
||||
DOUBLE_SLAB => "DoubleSlabBlock",
|
||||
SLAB => "SlabBlock",
|
||||
BRICKS_BLOCK => "BricksBlock",
|
||||
TNT => "TNTBlock",
|
||||
BOOKSHELF => "BookshelfBlock",
|
||||
MOSS_STONE => "MossStoneBlock",
|
||||
OBSIDIAN => "ObsidianBlock",
|
||||
TORCH => "TorchBlock",
|
||||
FIRE => "FireBlock",
|
||||
|
||||
WOOD_STAIRS => "WoodStairsBlock",
|
||||
CHEST => "ChestBlock",
|
||||
|
||||
DIAMOND_ORE => "DiamondOreBlock",
|
||||
DIAMOND_BLOCK => "DiamondBlock",
|
||||
WORKBENCH => "WorkbenchBlock",
|
||||
WHEAT_BLOCK => "WheatBlock",
|
||||
FARMLAND => "FarmlandBlock",
|
||||
FURNACE => "FurnaceBlock",
|
||||
BURNING_FURNACE => "BurningFurnaceBlock",
|
||||
SIGN_POST => "SignPostBlock",
|
||||
WOOD_DOOR_BLOCK => "WoodDoorBlock",
|
||||
LADDER => "LadderBlock",
|
||||
|
||||
COBBLESTONE_STAIRS => "CobblestoneStairsBlock",
|
||||
WALL_SIGN => "WallSignBlock",
|
||||
|
||||
IRON_DOOR_BLOCK => "IronDoorBlock",
|
||||
REDSTONE_ORE => "RedstoneOreBlock",
|
||||
GLOWING_REDSTONE_ORE => "GlowingRedstoneOreBlock",
|
||||
|
||||
SNOW_LAYER => "SnowLayerBlock",
|
||||
ICE => "IceBlock",
|
||||
SNOW_BLOCK => "SnowBlock",
|
||||
CACTUS => "CactusBlock",
|
||||
CLAY_BLOCK => "ClayBlock",
|
||||
SUGARCANE_BLOCK => "SugarcaneBlock",
|
||||
|
||||
FENCE => "FenceBlock",
|
||||
|
||||
NETHERRACK => "NetherrackBlock",
|
||||
SOUL_SAND => "SoulSandBlock",
|
||||
GLOWSTONE_BLOCK => "GlowstoneBlock",
|
||||
|
||||
TRAPDOOR => "TrapdoorBlock",
|
||||
|
||||
STONE_BRICKS => "StoneBricksBlock",
|
||||
|
||||
GLASS_PANE => "GlassPaneBlock",
|
||||
MELON_BLOCK => "MelonBlock",
|
||||
|
||||
MELON_STEM => "MelonStemBlock",
|
||||
|
||||
FENCE_GATE => "FenceGateBlock",
|
||||
BRICK_STAIRS => "BrickStairsBlock",
|
||||
STONE_BRICK_STAIRS => "StoneBrickStairsBlock",
|
||||
|
||||
NETHER_BRICKS => "NetherBricksBlock",
|
||||
|
||||
NETHER_BRICKS_STAIRS => "NetherBricksStairsBlock",
|
||||
|
||||
SANDSTONE_STAIRS => "SandstoneStairsBlock",
|
||||
|
||||
QUARTZ_BLOCK => "QuartzBlock",
|
||||
QUARTZ_STAIRS => "QuartzStairsBlock",
|
||||
|
||||
STONECUTTER => "StonecutterBlock",
|
||||
GLOWING_OBSIDIAN => "GlowingObsidianBlock",
|
||||
NETHER_REACTOR => "NetherReactorBlock",
|
||||
);
|
||||
protected $id;
|
||||
protected $meta;
|
||||
protected $name;
|
||||
protected $breakTime;
|
||||
public $isActivable = false;
|
||||
public $breakable = true;
|
||||
public $isFlowable = false;
|
||||
public $isTransparent = false;
|
||||
public $isReplaceable = false;
|
||||
public $isPlaceable = true;
|
||||
public $inWorld = false;
|
||||
public $hasPhysics = false;
|
||||
public $isLiquid = false;
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
$this->id = (int) $id;
|
||||
$this->meta = (int) $meta;
|
||||
$this->name = $name;
|
||||
$this->breakTime = 0.25;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
final public function getID(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
final public function getMetadata(){
|
||||
return $this->meta & 0x0F;
|
||||
}
|
||||
|
||||
final public function position(Vector3 $v){
|
||||
$this->inWorld = true;
|
||||
$this->x = (int) $v->x;
|
||||
$this->y = (int) $v->y;
|
||||
$this->z = (int) $v->z;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
if(!isset(Block::$class[$this->id])){ //Unknown blocks
|
||||
return array();
|
||||
}else{
|
||||
return array(
|
||||
array($this->id, $this->meta, 1),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item, Player $player){
|
||||
if($player->gamemode === CREATIVE){
|
||||
return 0.25;
|
||||
}
|
||||
return $this->breakTime;
|
||||
}
|
||||
|
||||
final public function __toString(){
|
||||
return "Block ". $this->name ." (".$this->id.":".$this->meta.")";
|
||||
}
|
||||
|
||||
abstract function isBreakable(Item $item, Player $player);
|
||||
|
||||
abstract function onBreak(BlockAPI $level, Item $item, Player $player);
|
||||
|
||||
abstract function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz);
|
||||
|
||||
abstract function onActivate(BlockAPI $level, Item $item, Player $player);
|
||||
|
||||
abstract function onUpdate(BlockAPI $level, $type);
|
||||
}
|
||||
|
||||
/***REM_START***/
|
||||
require_once("block/GenericBlock.php");
|
||||
require_once("block/SolidBlock.php");
|
||||
require_once("block/TransparentBlock.php");
|
||||
require_once("block/FallableBlock.php");
|
||||
require_once("block/LiquidBlock.php");
|
||||
require_once("block/StairBlock.php");
|
||||
require_once("block/DoorBlock.php");
|
||||
/***REM_END***/
|
142
src/material/Item.php
Normal file
142
src/material/Item.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class Item{
|
||||
public static $class = array(
|
||||
SUGARCANE => "SugarcaneItem",
|
||||
WHEAT_SEEDS => "WheatSeedsItem",
|
||||
MELON_SEEDS => "MelonSeedsItem",
|
||||
SIGN => "SignItem",
|
||||
WOODEN_DOOR => "WoodenDoorItem",
|
||||
IRON_DOOR => "IronDoorItem",
|
||||
BED => "BedItem",
|
||||
PAINTING => "PaintingItem",
|
||||
COAL => "CoalItem",
|
||||
APPLE => "AppleItem",
|
||||
DIAMOND => "DiamondItem",
|
||||
STICK => "StickItem",
|
||||
BOWL => "BowlItem",
|
||||
FEATHER => "FeatherItem",
|
||||
BRICK => "BrickItem",
|
||||
IRON_INGOT => "IronIngotItem",
|
||||
GOLD_INGOT => "GoldIngotItem",
|
||||
IRON_SHOVEL => "IronShovelItem",
|
||||
IRON_PICKAXE => "IronPickaxeItem",
|
||||
IRON_AXE => "IronAxeItem",
|
||||
IRON_HOE => "IronHoeItem",
|
||||
);
|
||||
protected $block;
|
||||
protected $id;
|
||||
protected $meta;
|
||||
public $count;
|
||||
protected $maxStackSize = 64;
|
||||
protected $durability = 0;
|
||||
protected $name;
|
||||
public $isActivable = false;
|
||||
|
||||
public function __construct($id, $meta = 0, $count = 1, $name = "Unknown"){
|
||||
$this->id = (int) $id;
|
||||
$this->meta = (int) $meta;
|
||||
$this->count = (int) $count;
|
||||
$this->name = $name;
|
||||
if(!isset($this->block) and $this->id <= 0xff and isset(Block::$class[$this->id])){
|
||||
$this->block = BlockAPI::get($this->id, $this->meta);
|
||||
$this->name = $this->block->getName();
|
||||
}
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function isPlaceable(){
|
||||
return (($this->block instanceof Block) and $this->block->isPlaceable === true);
|
||||
}
|
||||
|
||||
public function getBlock(){
|
||||
if($this->block instanceof Block){
|
||||
return $this->block;
|
||||
}else{
|
||||
return BlockAPI::get(AIR);
|
||||
}
|
||||
}
|
||||
|
||||
public function getID(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getMetadata(){
|
||||
return $this->meta;
|
||||
}
|
||||
|
||||
public function getMaxStackSize(){
|
||||
return $this->maxStackSize;
|
||||
}
|
||||
|
||||
public function isPickaxe(){ //Returns false or level of the pickaxe
|
||||
switch($this->id){
|
||||
case IRON_PICKAXE:
|
||||
return 3;
|
||||
case WOODEN_PICKAXE:
|
||||
return 1;
|
||||
case STONE_PICKAXE:
|
||||
return 2;
|
||||
case DIAMOND_PICKAXE:
|
||||
return 4;
|
||||
case GOLD_PICKAXE:
|
||||
return 3;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function isHoe(){
|
||||
switch($this->id){
|
||||
case IRON_HOE:
|
||||
case WOODEN_HOE:
|
||||
case STONE_HOE:
|
||||
case DIAMOND_HOE:
|
||||
case GOLD_HOE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final public function __toString(){
|
||||
return "Item ". $this->name ." (".$this->id.":".$this->meta.")";
|
||||
}
|
||||
|
||||
public function getDestroySpeed(Block $block, Player $player){
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function onActivate(BlockAPI $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
96
src/material/block/DoorBlock.php
Normal file
96
src/material/block/DoorBlock.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class DoorBlock extends TransparentBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true and $face === 1){
|
||||
$blockUp = $level->getBlockFace($block, 1);
|
||||
$blockDown = $level->getBlockFace($block, 0);
|
||||
if($blockUp->isReplaceable === false or $blockDown->isTransparent === true){
|
||||
return false;
|
||||
}
|
||||
$direction = $player->entity->getDirection();
|
||||
$face = array(
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
2 => 2,
|
||||
3 => 5,
|
||||
);
|
||||
$next = $level->getBlockFace($block, $face[(($direction + 2) % 4)]);
|
||||
$next2 = $level->getBlockFace($block, $face[$direction]);
|
||||
$metaUp = 0x08;
|
||||
if($next->getID() === $this->id or ($next2->isTransparent === false and $next->isTransparent === true)){ //Door hinge
|
||||
$metaUp |= 0x01;
|
||||
}
|
||||
$level->setBlock($blockUp, $this->id, $metaUp); //Top
|
||||
|
||||
$this->meta = $direction & 0x03;
|
||||
$level->setBlock($block, $this->id, $this->meta); //Bottom
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(BlockAPI $level, Item $item, Player $player){
|
||||
if($this->inWorld === true){
|
||||
if(($this->meta & 0x08) === 0x08){
|
||||
$down = $level->getBlockFace($this, 0);
|
||||
if($down->getID() === $this->id){
|
||||
$level->setBlock($down, 0, 0);
|
||||
}
|
||||
}else{
|
||||
$up = $level->getBlockFace($this, 1);
|
||||
if($up->getID() === $this->id){
|
||||
$level->setBlock($up, 0, 0);
|
||||
}
|
||||
}
|
||||
$level->setBlock($this, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(BlockAPI $level, Item $item, Player $player){
|
||||
if(($this->meta & 0x08) === 0x08){ //Top
|
||||
$down = $level->getBlockFace($this, 0);
|
||||
if($down->getID() === $this->id){
|
||||
$meta = $down->getMetadata() ^ 0x04;
|
||||
$level->setBlock($down, $this->id, $meta);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}else{
|
||||
$this->meta ^= 0x04;
|
||||
$level->setBlock($this, $this->id, $this->meta);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
33
src/material/block/FallableBlock.php
Normal file
33
src/material/block/FallableBlock.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class FallableBlock extends GenericBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->hasPhysics = true;
|
||||
}
|
||||
}
|
33
src/material/block/FlowableBlock.php
Normal file
33
src/material/block/FlowableBlock.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class FlowableBlock extends TransparentBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->isFlowable = true;
|
||||
}
|
||||
}
|
59
src/material/block/GenericBlock.php
Normal file
59
src/material/block/GenericBlock.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
class GenericBlock extends Block{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
}
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$level->setBlock($block, $this->id, $this->getMetadata());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item, Player $player){
|
||||
return $this->breakable;
|
||||
}
|
||||
|
||||
public function onBreak(BlockAPI $level, Item $item, Player $player){
|
||||
if($this->inWorld === true){
|
||||
$level->setBlock($this, AIR, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(BlockAPI $level, $type){
|
||||
return false;
|
||||
}
|
||||
public function onActivate(BlockAPI $level, Item $item, Player $player){
|
||||
return false;
|
||||
}
|
||||
}
|
35
src/material/block/LiquidBlock.php
Normal file
35
src/material/block/LiquidBlock.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class LiquidBlock extends TransparentBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->isLiquid = true;
|
||||
$this->breakable = false;
|
||||
$this->isReplaceable = true;
|
||||
}
|
||||
}
|
32
src/material/block/SolidBlock.php
Normal file
32
src/material/block/SolidBlock.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class SolidBlock extends GenericBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
}
|
||||
}
|
56
src/material/block/StairBlock.php
Normal file
56
src/material/block/StairBlock.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class StairBlock extends TransparentBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$faces = array(
|
||||
0 => 0,
|
||||
1 => 2,
|
||||
2 => 1,
|
||||
3 => 3,
|
||||
);
|
||||
$this->meta = $faces[$player->entity->getDirection()] & 0x03;
|
||||
if(($fy > 0.5 and $face !== 1) or $face === 0){
|
||||
$this->meta |= 0x04; //Upside-down stairs
|
||||
}
|
||||
$level->setBlock($block, $this->id, $this->meta);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
}
|
||||
}
|
38
src/material/block/TransparentBlock.php
Normal file
38
src/material/block/TransparentBlock.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class TransparentBlock extends GenericBlock{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->isActivable = false;
|
||||
$this->breakable = true;
|
||||
$this->isFlowable = false;
|
||||
$this->isTransparent = true;
|
||||
$this->isReplaceable = false;
|
||||
$this->isPlaceable = true;
|
||||
}
|
||||
}
|
52
src/material/block/attachable/Ladder.php
Normal file
52
src/material/block/attachable/Ladder.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class LadderBlock extends TransparentBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(LADDER, $meta, "Ladder");
|
||||
}
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
if($target->isTransparent === false){
|
||||
$faces = array(
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => 5,
|
||||
);
|
||||
$level->setBlock($block, $this->id, $faces[$face]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
}
|
||||
}
|
68
src/material/block/attachable/SignPost.php
Normal file
68
src/material/block/attachable/SignPost.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class SignPostBlock extends TransparentBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(SIGN_POST, $meta, "Sign Post");
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true and $face !== 0){
|
||||
if($face !== 0){
|
||||
$faces = array(
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => 5,
|
||||
);
|
||||
if(!isset($faces[$face])){
|
||||
$b = floor((($player->entity->yaw + 180) * 16 / 360) + 0.5) & 0x0F;
|
||||
$level->setBlock($block, SIGN_POST, $b);
|
||||
return true;
|
||||
}else{
|
||||
$level->setBlock($block, WALL_SIGN, $faces[$face]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(BlockAPI $level, Item $item, Player $player){
|
||||
if($this->inWorld === true){
|
||||
$level->setBlock($this, 0, 0, true, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array(SIGN, 0, 1),
|
||||
);
|
||||
}
|
||||
}
|
54
src/material/block/attachable/Torch.php
Normal file
54
src/material/block/attachable/Torch.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class TorchBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(TORCH, $meta, "Torch");
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true and $face !== 0){
|
||||
if($target->isTransparent === false){
|
||||
$faces = array(
|
||||
1 => 5,
|
||||
2 => 4,
|
||||
3 => 3,
|
||||
4 => 2,
|
||||
5 => 1,
|
||||
);
|
||||
$level->setBlock($block, $this->id, $faces[$face]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
}
|
||||
}
|
62
src/material/block/attachable/Trapdoor.php
Normal file
62
src/material/block/attachable/Trapdoor.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class TrapdoorBlock extends TransparentBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(TRAPDOOR, $meta, "Trapdoor");
|
||||
$this->isActivable = true;
|
||||
}
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
if($target->isTransparent === false and $face !== 0 and $face !== 1){
|
||||
$faces = array(
|
||||
2 => 0,
|
||||
3 => 1,
|
||||
4 => 2,
|
||||
5 => 3,
|
||||
);
|
||||
$this->meta = $faces[$face] & 0x03;
|
||||
if($fy > 0.5){
|
||||
$this->meta |= 0x08;
|
||||
}
|
||||
$level->setBlock($block, $this->id, $this->meta);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
}
|
||||
public function onActivate(BlockAPI $level, Item $item, Player $player){
|
||||
$this->meta ^= 0x04;
|
||||
$level->setBlock($this, $this->id, $this->meta);
|
||||
return true;
|
||||
}
|
||||
}
|
68
src/material/block/attachable/WallSign.php
Normal file
68
src/material/block/attachable/WallSign.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class WallSignBlock extends TransparentBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(WALL_SIGN, $meta, "Wall Sign");
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true and $face !== 0){
|
||||
if($face !== 0){
|
||||
$faces = array(
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => 5,
|
||||
);
|
||||
if(!isset($faces[$face])){
|
||||
$level->setBlock($block, SIGN_POST, 0);
|
||||
return true;
|
||||
}else{
|
||||
$level->setBlock($block, WALL_SIGN, $faces[$face]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(BlockAPI $level, Item $item, Player $player){
|
||||
if($this->inWorld === true){
|
||||
$level->setBlock($this, AIR, 0, true, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array(SIGN, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
33
src/material/block/liquid/Lava.php
Normal file
33
src/material/block/liquid/Lava.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class LavaBlock extends LiquidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(LAVA, $meta, "Lava");
|
||||
}
|
||||
|
||||
}
|
33
src/material/block/liquid/StillLava.php
Normal file
33
src/material/block/liquid/StillLava.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class StillLavaBlock extends LiquidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(STILL_LAVA, $meta, "Still Lava");
|
||||
}
|
||||
|
||||
}
|
33
src/material/block/liquid/StillWater.php
Normal file
33
src/material/block/liquid/StillWater.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class StillWaterBlock extends LiquidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(STILL_WATER, $meta, "Still Water");
|
||||
}
|
||||
|
||||
}
|
33
src/material/block/liquid/Water.php
Normal file
33
src/material/block/liquid/Water.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class WaterBlock extends LiquidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(WATER, $meta, "Water");
|
||||
}
|
||||
|
||||
}
|
41
src/material/block/misc/Air.php
Normal file
41
src/material/block/misc/Air.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class AirBlock extends TransparentBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(AIR, 0, "Air");
|
||||
$this->isActivable = false;
|
||||
$this->breakable = false;
|
||||
$this->isFlowable = true;
|
||||
$this->isTransparent = true;
|
||||
$this->isReplaceable = true;
|
||||
$this->isPlaceable = false;
|
||||
$this->inWorld = false;
|
||||
$this->hasPhysics = false;
|
||||
}
|
||||
|
||||
}
|
102
src/material/block/misc/Bed.php
Normal file
102
src/material/block/misc/Bed.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class BedBlock extends TransparentBlock{
|
||||
public function __construct($type = 0){
|
||||
parent::__construct(BED_BLOCK, $type, "Bed Block");
|
||||
$this->isActivable = true;
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$down = $level->getBlockFace($block, 0);
|
||||
if($down->isTransparent === false){
|
||||
$faces = array(
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
2 => 2,
|
||||
3 => 5,
|
||||
);
|
||||
$d = $player->entity->getDirection();
|
||||
$next = $level->getBlockFace($block, $faces[(($d + 3) % 4)]);
|
||||
$downNext = $level->getBlockFace($next, 0);
|
||||
if($next->isReplaceable === true and $downNext->isTransparent === false){
|
||||
$meta = (($d + 3) % 4) & 0x03;
|
||||
$level->setBlock($block, $this->id, $meta);
|
||||
$level->setBlock($next, $this->id, $meta | 0x08);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(BlockAPI $level, Item $item, Player $player){
|
||||
if($this->inWorld === true){//Checks if the block was in the world or not. Just in case
|
||||
$blockNorth = $level->getBlockFace($this, 2); //Gets the blocks around them
|
||||
$blockSouth = $level->getBlockFace($this, 3);
|
||||
$blockEast = $level->getBlockFace($this, 5);
|
||||
$blockWest = $level->getBlockFace($this, 4);
|
||||
|
||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||
if($blockNorth->getID() === $this->id and $blockNorth->meta !== 0x08){ //Checks if the block ID and meta are right
|
||||
$level->setBlock($blockNorth, 0, 0);
|
||||
}elseif($blockSouth->getID() === $this->id and $blockSouth->meta !== 0x08){
|
||||
$level->setBlock($blockSouth, 0, 0);
|
||||
}elseif($blockEast->getID() === $this->id and $blockEast->meta !== 0x08){
|
||||
$level->setBlock($blockEast, 0, 0);
|
||||
}elseif($blockWest->getID() === $this->id and $blockWest->meta !== 0x08){
|
||||
$level->setBlock($blockWest, 0, 0);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$level->setBlock($blockNorth, 0, 0);
|
||||
}elseif($blockSouth->getID() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$level->setBlock($blockSouth, 0, 0);
|
||||
}elseif($blockEast->getID() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$level->setBlock($blockEast, 0, 0);
|
||||
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$level->setBlock($blockWest, 0, 0);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array(BED, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
35
src/material/block/misc/Fire.php
Normal file
35
src/material/block/misc/Fire.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class FireBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(FIRE, $meta, "Fire");
|
||||
$this->isReplaceable = true;
|
||||
$this->breakable = false;
|
||||
}
|
||||
|
||||
}
|
34
src/material/block/misc/NetherReactor.php
Normal file
34
src/material/block/misc/NetherReactor.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class NetherReactorBlock extends SolidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(NETHER_REACTOR, $meta, "Nether Reactor");
|
||||
$this->isActivable = true;
|
||||
}
|
||||
|
||||
}
|
46
src/material/block/misc/TNT.php
Normal file
46
src/material/block/misc/TNT.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class TNTBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(TNT, 0, "TNT");
|
||||
}
|
||||
public function getDrops(Item $item, Player $player){
|
||||
if($this->inWorld === true){
|
||||
$player->dataPacket(MC_EXPLOSION, array(
|
||||
"x" => $this->x,
|
||||
"y" => $this->y,
|
||||
"z" => $this->z,
|
||||
"radius" => 2,
|
||||
"records" => array(),
|
||||
));
|
||||
}
|
||||
return array(
|
||||
array(TNT, 0, 1),
|
||||
);
|
||||
}
|
||||
}
|
43
src/material/block/ore/CoalOre.php
Normal file
43
src/material/block/ore/CoalOre.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class CoalOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(COAL_ORE, 0, "Coal Ore");
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(263, 0, 1), //Coal
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
42
src/material/block/ore/DiamondOre.php
Normal file
42
src/material/block/ore/DiamondOre.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class DiamondOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(DIAMOND_ORE, 0, "Diamond Ore");
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
if($item->isPickaxe() >= 3){
|
||||
return array(
|
||||
array(264, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
33
src/material/block/ore/GlowingRedstoneOre.php
Normal file
33
src/material/block/ore/GlowingRedstoneOre.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class GlowingRedstoneOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(GLOWING_REDSTONE_ORE, 0, "Glowing Redstone Ore");
|
||||
}
|
||||
|
||||
}
|
33
src/material/block/ore/GoldOre.php
Normal file
33
src/material/block/ore/GoldOre.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class GoldOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(GOLD_ORE, 0, "Gold Ore");
|
||||
}
|
||||
|
||||
}
|
33
src/material/block/ore/IronOre.php
Normal file
33
src/material/block/ore/IronOre.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class IronOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(IRON_ORE, 0, "Iron Ore");
|
||||
}
|
||||
|
||||
}
|
43
src/material/block/ore/LapisOre.php
Normal file
43
src/material/block/ore/LapisOre.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class LapisOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(LAPIS_ORE, 0, "Lapis Ore");
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
if($item->isPickaxe() >= 2){
|
||||
return array(
|
||||
array(351, 4, mt_rand(4, 8)),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
41
src/material/block/ore/RedstoneOre.php
Normal file
41
src/material/block/ore/RedstoneOre.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class RedstoneOreBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(REDSTONE_ORE, 0, "Redstone Ore");
|
||||
}
|
||||
public function getDrops(Item $item, Player $player){
|
||||
if($item->isPickaxe() >= 2){
|
||||
return array(
|
||||
//array(331, 4, mt_rand(4, 5)),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
44
src/material/block/plant/BrownMushroom.php
Normal file
44
src/material/block/plant/BrownMushroom.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class BrownMushroomBlock extends FlowableBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(BROWN_MUSHROOM, 0, "Brown Mushroom");
|
||||
$this->isFlowable = true;
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$down = $level->getBlockFace($block, 0);
|
||||
if($down->isTransparent === false){
|
||||
$level->setBlock($block, $this->id, $this->getMetadata());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
50
src/material/block/plant/Cactus.php
Normal file
50
src/material/block/plant/Cactus.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class CactusBlock extends TransparentBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(CACTUS, 0, "Cactus");
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$down = $level->getBlockFace($block, 0);
|
||||
if($down->getID() === SAND or $down->getID() === CACTUS){
|
||||
$block0 = $level->getBlockFace($block, 2);
|
||||
$block1 = $level->getBlockFace($block, 3);
|
||||
$block2 = $level->getBlockFace($block, 4);
|
||||
$block3 = $level->getBlockFace($block, 5);
|
||||
if($block0->isFlowable === true and $block1->isFlowable === true and $block2->isFlowable === true and $block3->isFlowable === true){
|
||||
$level->setBlock($block, $this->id, 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
43
src/material/block/plant/CyanFlower.php
Normal file
43
src/material/block/plant/CyanFlower.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class CyanFlowerBlock extends FlowableBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(CYAN_FLOWER, 0, "Cyan Flower");
|
||||
$this->isFlowable = true;
|
||||
}
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$down = $level->getBlockFace($block, 0);
|
||||
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
|
||||
$level->setBlock($block, $this->id, $this->getMetadata());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
43
src/material/block/plant/Dandelion.php
Normal file
43
src/material/block/plant/Dandelion.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class DandelionBlock extends FlowableBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(DANDELION, 0, "Dandelion");
|
||||
$this->isFlowable = true;
|
||||
}
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$down = $level->getBlockFace($block, 0);
|
||||
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
|
||||
$level->setBlock($block, $this->id, $this->getMetadata());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
35
src/material/block/plant/DeadBush.php
Normal file
35
src/material/block/plant/DeadBush.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class DeadBushBlock extends FlowableBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(DEAD_BUSH, 0, "Dead Bush");
|
||||
$this->isFlowable = true;
|
||||
$this->isReplaceable = true;
|
||||
}
|
||||
|
||||
}
|
57
src/material/block/plant/MelonStem.php
Normal file
57
src/material/block/plant/MelonStem.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class MelonStemBlock extends TransparentBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(MELON_STEM, $meta, "Melon Stem");
|
||||
$this->isActivable = true;
|
||||
}
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$down = $level->getBlockFace($block, 0);
|
||||
if($down->getID() === FARMLAND){
|
||||
$level->setBlock($block, $this->id, $this->getMetadata());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(BlockAPI $level, Item $item, Player $player){
|
||||
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
|
||||
$level->setBlock($this, $this->id, 0x07);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array(MELON_SEEDS, 0, mt_rand(0, 2)),
|
||||
);
|
||||
}
|
||||
}
|
44
src/material/block/plant/RedMushroom.php
Normal file
44
src/material/block/plant/RedMushroom.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class RedMushroomBlock extends FlowableBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(RED_MUSHROOM, 0, "Red Mushroom");
|
||||
$this->isFlowable = true;
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$down = $level->getBlockFace($block, 0);
|
||||
if($down->isTransparent === false){
|
||||
$level->setBlock($block, $this->id, $this->getMetadata());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
86
src/material/block/plant/Sapling.php
Normal file
86
src/material/block/plant/Sapling.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class SaplingBlock extends TransparentBlock{
|
||||
const OAK = 0;
|
||||
const SPRUCE = 1;
|
||||
const BIRCH = 2;
|
||||
const BURN_TIME = 5;
|
||||
|
||||
public function __construct($meta = Sapling::OAK){
|
||||
parent::__construct(SAPLING, $meta, "Sapling");
|
||||
$this->isActivable = true;
|
||||
$this->isFlowable = true;
|
||||
$names = array(
|
||||
0 => "Oak Sapling",
|
||||
1 => "Spruce Sapling",
|
||||
2 => "Birch Sapling",
|
||||
);
|
||||
$this->name = $names[$this->meta & 0x03];
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$down = $level->getBlockFace($block, 0);
|
||||
if($down->getID() === GRASS or $down->getID() === DIRT or $down->getID() === FARMLAND){
|
||||
$level->setBlock($block, $this->id, $this->getMetadata());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(BlockAPI $level, Item $item, Player $player){
|
||||
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
|
||||
TreeObject::growTree($level, $this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate(BlockAPI $level, $type){
|
||||
if($this->inWorld !== true){
|
||||
return false;
|
||||
}
|
||||
if($type === BLOCK_UPDATE_RANDOM and mt_rand(0,2) === 0){ //Growth
|
||||
if(($this->meta & 0x08) === 0x08){
|
||||
TreeObject::growTree($level, $this);
|
||||
}else{
|
||||
$this->meta |= 0x08;
|
||||
$this->level->setBlock($this->x, $this->y, $this->z, $this->id, $this->meta);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, $this->meta & 0x03, 1),
|
||||
);
|
||||
}
|
||||
}
|
70
src/material/block/plant/Sugarcane.php
Normal file
70
src/material/block/plant/Sugarcane.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class SugarcaneBlock extends TransparentBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(SUGARCANE_BLOCK, 0, "Sugarcane");
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array(SUGARCANE, 0, 1),
|
||||
);
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$down = $level->getBlockFace($block, 0);
|
||||
if($down->getID() === SUGARCANE_BLOCK){
|
||||
$level->setBlock($block, $this->id, 0);
|
||||
return true;
|
||||
}elseif($down->getID() === GRASS or $down->getID() === DIRT or $down->getID() === SAND){
|
||||
$block0 = $level->getBlockFace($down, 2);
|
||||
$block1 = $level->getBlockFace($down, 3);
|
||||
$block2 = $level->getBlockFace($down, 4);
|
||||
$block3 = $level->getBlockFace($down, 5);
|
||||
/*$block4 = $level->getBlockFace($block, 2);
|
||||
$block5 = $level->getBlockFace($block, 3);
|
||||
$block6 = $level->getBlockFace($block, 4);
|
||||
$block7 = $level->getBlockFace($block, 5);*/
|
||||
if($block0->getID() === WATER or $block0->getID() === STILL_WATER
|
||||
or $block1->getID() === WATER or $block1->getID() === STILL_WATER
|
||||
or $block2->getID() === WATER or $block2->getID() === STILL_WATER
|
||||
or $block3->getID() === WATER or $block3->getID() === STILL_WATER
|
||||
/*or $block4->getID() === WATER or $block4->getID() === STILL_WATER
|
||||
or $block5->getID() === WATER or $block5->getID() === STILL_WATER
|
||||
or $block6->getID() === WATER or $block6->getID() === STILL_WATER
|
||||
or $block7->getID() === WATER or $block7->getID() === STILL_WATER*/){
|
||||
$level->setBlock($block, $this->id, 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
49
src/material/block/plant/TallGrass.php
Normal file
49
src/material/block/plant/TallGrass.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class TallGrassBlock extends FlowableBlock{
|
||||
public function __construct($meta = 1){
|
||||
parent::__construct(TALL_GRASS, $meta, "Tall Grass");
|
||||
$this->isFlowable = true;
|
||||
$this->isReplaceable = true;
|
||||
$names = array(
|
||||
0 => "Dead Shrub",
|
||||
1 => "Tall Grass",
|
||||
2 => "Fern",
|
||||
);
|
||||
$this->name = $names[$this->meta & 0x03];
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
$drops = array();
|
||||
if(mt_rand(1,10) === 1){//Seeds
|
||||
$drops[] = array(295, 0, 1);
|
||||
}
|
||||
return $drops;
|
||||
}
|
||||
|
||||
}
|
63
src/material/block/plant/Wheat.php
Normal file
63
src/material/block/plant/Wheat.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class WheatBlock extends FlowableBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(WHEAT_BLOCK, $meta, "Wheat Block");
|
||||
$this->isActivable = true;
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$down = $level->getBlockFace($block, 0);
|
||||
if($down->getID() === FARMLAND){
|
||||
$level->setBlock($block, $this->id, $this->getMetadata());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(BlockAPI $level, Item $item, Player $player){
|
||||
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
|
||||
$level->setBlock($this, $this->id, 0x07);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
$drops = array();
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = array(WHEAT, 0, 1);
|
||||
$drops[] = array(WHEAT_SEEDS, 0, mt_rand(0, 3));
|
||||
}else{
|
||||
$drops[] = array(WHEAT_SEEDS, 0, 1);
|
||||
}
|
||||
return $drops;
|
||||
}
|
||||
}
|
41
src/material/block/solid/Bedrock.php
Normal file
41
src/material/block/solid/Bedrock.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class BedrockBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(BEDROCK, 0, "Bedrock");
|
||||
$this->breakable = false;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item, Player $player){
|
||||
if($player->gamemode === CREATIVE){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
33
src/material/block/solid/Bookshelf.php
Normal file
33
src/material/block/solid/Bookshelf.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class BookshelfBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(BOOKSHELF, 0, "Bookshelf");
|
||||
}
|
||||
|
||||
}
|
33
src/material/block/solid/Bricks.php
Normal file
33
src/material/block/solid/Bricks.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class BricksBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(BRICKS_BLOCK, 0, "Bricks");
|
||||
}
|
||||
|
||||
}
|
125
src/material/block/solid/BurningFurnace.php
Normal file
125
src/material/block/solid/BurningFurnace.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
class BurningFurnaceBlock extends SolidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(BURNING_FURNACE, $meta, "Burning Furnace");
|
||||
$this->isActivable = true;
|
||||
}
|
||||
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$faces = array(
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
2 => 5,
|
||||
3 => 3,
|
||||
);
|
||||
$level->setBlock($block, $this->id, $faces[$player->entity->getDirection()]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(BlockAPI $level, Item $item, Player $player){
|
||||
if($this->inWorld === true){
|
||||
$server = ServerAPI::request();
|
||||
$t = $server->api->tileentity->get($this);
|
||||
if($t !== false){
|
||||
if(is_array($t)){
|
||||
foreach($t as $ts){
|
||||
if($ts->class === TILE_FURNACE){
|
||||
$server->api->tileentity->remove($ts->id);
|
||||
}
|
||||
}
|
||||
}elseif($t->class === TILE_FURNACE){
|
||||
$server->api->tileentity->remove($t->id);
|
||||
}
|
||||
}
|
||||
$level->setBlock($this, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(BlockAPI $level, Item $item, Player $player){
|
||||
$server = ServerAPI::request();
|
||||
$t = $server->api->tileentity->get($this);
|
||||
$furnace = false;
|
||||
if($t !== false){
|
||||
if(is_array($t)){
|
||||
$furnace = array_shift($t);
|
||||
}else{
|
||||
$furnace = $t;
|
||||
}
|
||||
}else{
|
||||
$furnace = $server->api->tileentity->add(TILE_FURNACE, $this->x, $this->y, $this->z, array(
|
||||
"Items" => array(),
|
||||
"id" => TILE_FURNACE,
|
||||
"x" => $this->x,
|
||||
"y" => $this->y,
|
||||
"z" => $this->z
|
||||
));
|
||||
}
|
||||
|
||||
if($furnace->class !== TILE_FURNACE){
|
||||
return false;
|
||||
}
|
||||
$id = $player->windowCnt = $player->windowCnt++ % 255;
|
||||
$player->windows[$id] = $furnace;
|
||||
$player->dataPacket(MC_CONTAINER_OPEN, array(
|
||||
"windowid" => $id,
|
||||
"type" => WINDOW_FURNACE,
|
||||
"slots" => 3,
|
||||
"title" => "Furnace",
|
||||
));
|
||||
for($s = 0; $s < 3; ++$s){
|
||||
$slot = $furnace->getSlot($s);
|
||||
if($slot->getID() > 0 and $slot->count > 0){
|
||||
$player->dataPacket(MC_CONTAINER_SET_SLOT, array(
|
||||
"windowid" => $id,
|
||||
"slot" => $s,
|
||||
"block" => $slot->getID(),
|
||||
"stack" => $slot->count,
|
||||
"meta" => $slot->getMetadata(),
|
||||
));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(FURNACE, 0, 1),
|
||||
);
|
||||
}else{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
134
src/material/block/solid/Chest.php
Normal file
134
src/material/block/solid/Chest.php
Normal file
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class ChestBlock extends SolidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(CHEST, $meta, "Chest");
|
||||
$this->isActivable = true;
|
||||
}
|
||||
public function place(BlockAPI $level, Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
if($block->inWorld === true){
|
||||
$block0 = $level->getBlockFace($block, 2);
|
||||
$block1 = $level->getBlockFace($block, 3);
|
||||
$block2 = $level->getBlockFace($block, 4);
|
||||
$block3 = $level->getBlockFace($block, 5);
|
||||
if($block0->getID() !== CHEST and $block1->getID() !== CHEST and $block2->getID() !== CHEST and $block3->getID() !== CHEST){
|
||||
$faces = array(
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
2 => 5,
|
||||
3 => 3,
|
||||
);
|
||||
$level->setBlock($block, $this->id, $faces[$player->entity->getDirection()]);
|
||||
$server = ServerAPI::request();
|
||||
$server->api->tileentity->add(TILE_CHEST, $this->x, $this->y, $this->z, array(
|
||||
"Items" => array(),
|
||||
"id" => TILE_CHEST,
|
||||
"x" => $this->x,
|
||||
"y" => $this->y,
|
||||
"z" => $this->z
|
||||
));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(BlockAPI $level, Item $item, Player $player){
|
||||
if($this->inWorld === true){
|
||||
$server = ServerAPI::request();
|
||||
$t = $server->api->tileentity->get($this);
|
||||
if($t !== false){
|
||||
if(is_array($t)){
|
||||
foreach($t as $ts){
|
||||
if($ts->class === TILE_CHEST){
|
||||
$server->api->tileentity->remove($ts->id);
|
||||
}
|
||||
}
|
||||
}elseif($t->class === TILE_CHEST){
|
||||
$server->api->tileentity->remove($t->id);
|
||||
}
|
||||
}
|
||||
$level->setBlock($this, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(BlockAPI $level, Item $item, Player $player){
|
||||
$server = ServerAPI::request();
|
||||
$t = $server->api->tileentity->get($this);
|
||||
$chest = false;
|
||||
if($t !== false){
|
||||
if(is_array($t)){
|
||||
$chest = array_shift($t);
|
||||
}else{
|
||||
$chest = $t;
|
||||
}
|
||||
}else{
|
||||
$chest = $server->api->tileentity->add(TILE_CHEST, $this->x, $this->y, $this->z, array(
|
||||
"Items" => array(),
|
||||
"id" => TILE_CHEST,
|
||||
"x" => $this->x,
|
||||
"y" => $this->y,
|
||||
"z" => $this->z
|
||||
));
|
||||
}
|
||||
|
||||
if($chest->class !== TILE_CHEST){
|
||||
return false;
|
||||
}
|
||||
$id = $player->windowCnt = $player->windowCnt++ % 255;
|
||||
$player->windows[$id] = $chest;
|
||||
$player->dataPacket(MC_CONTAINER_OPEN, array(
|
||||
"windowid" => $id,
|
||||
"type" => WINDOW_CHEST,
|
||||
"slots" => 27,
|
||||
"title" => "Chest",
|
||||
));
|
||||
for($s = 0; $s < 3; ++$s){
|
||||
$slot = $chest->getSlot($s);
|
||||
if($slot->getID() > 0 and $slot->count > 0){
|
||||
$player->dataPacket(MC_CONTAINER_SET_SLOT, array(
|
||||
"windowid" => $id,
|
||||
"slot" => $s,
|
||||
"block" => $slot->getID(),
|
||||
"stack" => $slot->count,
|
||||
"meta" => $slot->getMetadata(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
}
|
||||
}
|
33
src/material/block/solid/Clay.php
Normal file
33
src/material/block/solid/Clay.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class ClayBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(CLAY_BLOCK, 0, "Clay Block");
|
||||
}
|
||||
|
||||
}
|
33
src/material/block/solid/Cobblestone.php
Normal file
33
src/material/block/solid/Cobblestone.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class CobblestoneBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(COBBLESTONE, 0, "Cobblestone");
|
||||
}
|
||||
|
||||
}
|
36
src/material/block/solid/Cobweb.php
Normal file
36
src/material/block/solid/Cobweb.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class CobwebBlock extends FlowableBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(COBWEB, 0, "Cobweb");
|
||||
$this->isFlowable = true;
|
||||
}
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array();
|
||||
}
|
||||
}
|
33
src/material/block/solid/Diamond.php
Normal file
33
src/material/block/solid/Diamond.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class DiamondBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(DIAMOND_BLOCK, 0, "Diamond Block");
|
||||
}
|
||||
|
||||
}
|
41
src/material/block/solid/Dirt.php
Normal file
41
src/material/block/solid/Dirt.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class DirtBlock extends SolidBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(DIRT, 0, "Dirt");
|
||||
$this->isActivable = true;
|
||||
}
|
||||
|
||||
public function onActivate(BlockAPI $level, Item $item, Player $player){
|
||||
if($item->isHoe()){
|
||||
$level->setBlock($this, FARMLAND, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
49
src/material/block/solid/DoubleSlab.php
Normal file
49
src/material/block/solid/DoubleSlab.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class DoubleSlabBlock extends SolidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(DOUBLE_SLAB, $meta, "Double Slab");
|
||||
$names = array(
|
||||
0 => "Stone",
|
||||
1 => "Sandstone",
|
||||
2 => "Wooden",
|
||||
3 => "Cobblestone",
|
||||
4 => "Brick",
|
||||
5 => "Stone Brick",
|
||||
6 => "Nether Brick",
|
||||
7 => "Quartz",
|
||||
);
|
||||
$this->name = "Double " . $names[$this->meta & 0x07] . " Slab";
|
||||
}
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array(SLAB, $this->meta & 0x07, 2),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
37
src/material/block/solid/Farmland.php
Normal file
37
src/material/block/solid/Farmland.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class FarmlandBlock extends SolidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(FARMLAND, $meta, "Farmland");
|
||||
}
|
||||
public function getDrops(Item $item, Player $player){
|
||||
return array(
|
||||
array(DIRT, 0, 1),
|
||||
);
|
||||
}
|
||||
}
|
33
src/material/block/solid/Fence.php
Normal file
33
src/material/block/solid/Fence.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class FenceBlock extends TransparentBlock{
|
||||
public function __construct(){
|
||||
parent::__construct(FENCE, 0, "Fence");
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user