mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-20 16:00:20 +00:00
First commit
This commit is contained in:
commit
c2de8094b2
22
.gitattributes
vendored
Normal file
22
.gitattributes
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
*.sln merge=union
|
||||
*.csproj merge=union
|
||||
*.vbproj merge=union
|
||||
*.fsproj merge=union
|
||||
*.dbproj merge=union
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
169
.gitignore
vendored
Normal file
169
.gitignore
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
*.log
|
||||
*.ini
|
||||
test.php
|
||||
*.bat
|
||||
raknet/*
|
||||
|
||||
#################
|
||||
## 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
|
||||
|
||||
# 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
|
165
LICENSE
Normal file
165
LICENSE
Normal file
@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
28
README
Normal file
28
README
Normal file
@ -0,0 +1,28 @@
|
||||
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/>.
|
||||
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
115
classes/MinecraftInterface.class.php
Normal file
115
classes/MinecraftInterface.class.php
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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 MinecraftInterface{
|
||||
var $pstruct, $name, $server, $protocol;
|
||||
|
||||
function __construct($server, $protocol = CURRENT_PROTOCOL, $port = 25565, $listen = false){
|
||||
$this->server = new Socket($server, $port, (bool) $listen);
|
||||
$this->protocol = (int) $protocol;
|
||||
require("pstruct/RakNet.php");
|
||||
require("pstruct/packetName.php");
|
||||
$this->pstruct = $pstruct;
|
||||
$this->name = $packetName;
|
||||
}
|
||||
|
||||
public function close(){
|
||||
return $this->server->close();
|
||||
}
|
||||
|
||||
protected function getStruct($pid){
|
||||
if(isset($this->pstruct[$pid])){
|
||||
return $this->pstruct[$pid];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function writeDump($pid, $raw, $data, $origin = "client", $ip = "", $port = 0){
|
||||
if(LOG === true and DEBUG >= 2){
|
||||
$p = "[".microtime(true)."] [".($origin === "client" ? "CLIENT->SERVER":"SERVER->CLIENT")." ".$ip.":".$port."]: ".$this->name[$pid]." (0x".Utils::strTohex(chr($pid)).") [lenght ".strlen($raw)."]".PHP_EOL;
|
||||
$p .= hexdump($raw, false, false, true);
|
||||
if(is_array($data)){
|
||||
foreach($data as $i => $d){
|
||||
$p .= $i ." => ".(!is_array($d) ? $this->pstruct[$pid][$i]."(".(($this->pstruct[$pid][$i] === "magic" or substr($this->pstruct[$pid][$i], 0, 7) === "special") ? Utils::strToHex($d):$d).")":$this->pstruct[$pid][$i]."(***)").PHP_EOL;
|
||||
}
|
||||
}
|
||||
$p .= PHP_EOL;
|
||||
logg($p, "packets", false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function readPacket($port = false){
|
||||
if($this->server->connected === false){
|
||||
//return array("pid" => "ff", "data" => array(0 => 'Connection error'));
|
||||
}
|
||||
$data = $this->server->read();
|
||||
if($data[3] === false){
|
||||
return false;
|
||||
}
|
||||
$pid = $data[0]{0};
|
||||
$pid = ord($pid);
|
||||
$struct = $this->getStruct($pid);
|
||||
if($struct === false){
|
||||
$p = "[".microtime(true)."] [SERVER->CLIENT]: Error, bad packet id 0x".Utils::strToHex(chr($pid)).PHP_EOL;
|
||||
$p .= hexdump($data[0], false, false, true);
|
||||
$p .= PHP_EOL . "--------------- (1024 byte max extract) ----------" .PHP_EOL;
|
||||
logg($p, "packets", true, 3);
|
||||
|
||||
$this->buffer = "";
|
||||
//$this->server->recieve("\xff".Utils::writeString('Bad packet id '.$pid.''));
|
||||
//$this->writePacket("ff", array(0 => 'Bad packet id '.$pid.''));
|
||||
//return array("pid" => "ff", "data" => array(0 => 'Bad packet id '.$pid.''));
|
||||
return false;
|
||||
}
|
||||
|
||||
$packet = new Packet($pid, $struct, $data[0]);
|
||||
$packet->protocol = $this->protocol;
|
||||
$packet->parse();
|
||||
$this->writeDump($pid, $data[0], $packet->data, "server", $data[1], $data[2]);
|
||||
return array("pid" => $pid, "data" => $packet->data, "raw" => $data[0], "ip" => $data[1], "port" => $data[2]);
|
||||
}
|
||||
|
||||
public function writePacket($pid, $data = array(), $raw = false, $dest = false, $port = false){
|
||||
$struct = $this->getStruct($pid);
|
||||
if($raw === false){
|
||||
$packet = new Packet($pid, $struct);
|
||||
$packet->protocol = $this->protocol;
|
||||
$packet->data = $data;
|
||||
$packet->create();
|
||||
$write = $this->server->write($packet->raw, $dest, $port);
|
||||
$this->writeDump($pid, $packet->raw, $data, "client");
|
||||
}else{
|
||||
$write = $this->server->write($data, $dest, $port);
|
||||
$this->writeDump($pid, $data, false, "client", $dest, $port);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
192
classes/Packet.class.php
Normal file
192
classes/Packet.class.php
Normal file
@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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 Packet{
|
||||
private $struct, $sock;
|
||||
protected $pid, $packet;
|
||||
public $data, $raw, $protocol;
|
||||
|
||||
function __construct($pid, $struct, $data = ""){
|
||||
$this->pid = $pid;
|
||||
$this->offset = 1;
|
||||
$this->raw = $data;
|
||||
$this->data = array();
|
||||
if($pid !== false){
|
||||
$this->addRaw(chr($pid));
|
||||
}
|
||||
$this->struct = $struct;
|
||||
$this->sock = $sock;
|
||||
}
|
||||
|
||||
public function create($raw = false){
|
||||
foreach($this->struct as $field => $type){
|
||||
if(!isset($this->data[$field])){
|
||||
$this->data[$field] = "";
|
||||
}
|
||||
if($raw === true){
|
||||
$this->addRaw($this->data[$field]);
|
||||
continue;
|
||||
}
|
||||
if(is_int($type)){
|
||||
$this->addRaw($this->data[$field]);
|
||||
continue;
|
||||
}
|
||||
switch($type){
|
||||
case "special1":
|
||||
switch($this->pid){
|
||||
case 0x05:
|
||||
$this->addRaw($this->data[$field]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "magic":
|
||||
$this->addRaw(MAGIC);
|
||||
break;
|
||||
case "float":
|
||||
$this->addRaw(Utils::writeFloat($this->data[$field]));
|
||||
break;
|
||||
case "int":
|
||||
$this->addRaw(Utils::writeInt($this->data[$field]));
|
||||
break;
|
||||
case "double":
|
||||
$this->addRaw(Utils::writeDouble($this->data[$field]));
|
||||
break;
|
||||
case "long":
|
||||
$this->addRaw(Utils::writeLong($this->data[$field]));
|
||||
break;
|
||||
case "bool":
|
||||
case "boolean":
|
||||
$this->addRaw(Utils::writeBool($this->data[$field]));
|
||||
break;
|
||||
case "ubyte":
|
||||
case "byte":
|
||||
$this->addRaw(Utils::writeByte($this->data[$field]));
|
||||
break;
|
||||
case "short":
|
||||
$this->addRaw(Utils::writeShort($this->data[$field]));
|
||||
break;
|
||||
case "byteArray":
|
||||
$this->addRaw($this->data[$field]);
|
||||
break;
|
||||
case "string":
|
||||
$this->addRaw(Utils::writeShort(strlen($this->data[$field])));
|
||||
$this->addRaw($this->data[$field]);
|
||||
break;
|
||||
case "slotData":
|
||||
$this->addRaw(Utils::writeShort($this->data[$field][0]));
|
||||
if($this->data[$field][0]!=-1){
|
||||
$this->addRaw(Utils::writeByte($this->data[$field][1]));
|
||||
$this->addRaw(Utils::writeShort($this->data[$field][2]));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$this->addRaw(Utils::writeByte($this->data[$field]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function get($len = true){
|
||||
if($len === true){
|
||||
$data = substr($this->raw, $this->offset);
|
||||
$this->offset = strlen($this->raw);
|
||||
return $data;
|
||||
}
|
||||
$data = substr($this->raw, $this->offset, $len);
|
||||
$this->offset += $len;
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function addRaw($str){
|
||||
$this->raw .= $str;
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function parse(){
|
||||
$continue = true;
|
||||
foreach($this->struct as $field => $type){
|
||||
if(is_int($type)){
|
||||
$this->data[] = $this->get($type);
|
||||
continue;
|
||||
}
|
||||
switch($type){
|
||||
case "special1":
|
||||
switch($this->pid){
|
||||
case 0x05:
|
||||
$this->data[] = $this->get(true);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "magic":
|
||||
$this->data[] = $this->get(16);
|
||||
break;
|
||||
case "int":
|
||||
$this->data[] = Utils::readInt($this->get(4));
|
||||
if($field === 5 and $this->pid === "17" and $this->data[$field] === 0){
|
||||
$continue = false;
|
||||
}
|
||||
break;
|
||||
case "string":
|
||||
$this->data[] = $this->get(Utils::readShort($this->get(2)) << 1);
|
||||
break;
|
||||
case "long":
|
||||
$this->data[] = Utils::readLong($this->get(8));
|
||||
break;
|
||||
case "byte":
|
||||
$this->data[] = Utils::readByte($this->get(1));
|
||||
break;
|
||||
case "ubyte":
|
||||
$this->data[] = ord($this->get(1));
|
||||
break;
|
||||
case "float":
|
||||
$this->data[] = Utils::readFloat($this->get(4));
|
||||
break;
|
||||
case "double":
|
||||
$this->data[] = Utils::readDouble($this->get(8));
|
||||
break;
|
||||
case "ushort":
|
||||
$this->data[] = Utils::readShort($this->get(2), false);
|
||||
break;
|
||||
case "short":
|
||||
$this->data[] = Utils::readShort($this->get(2));
|
||||
break;
|
||||
case "bool":
|
||||
case "boolean":
|
||||
$this->data[] = Utils::readBool($this->get(1));
|
||||
break;
|
||||
}
|
||||
if($continue === false){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
33
classes/PocketMinecraftClient.class.php
Normal file
33
classes/PocketMinecraftClient.class.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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 PocketMinecraftClient{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
153
classes/PocketMinecraftServer.class.php
Normal file
153
classes/PocketMinecraftServer.class.php
Normal file
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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{
|
||||
protected $interface, $protocol, $entities, $player, $cnt, $events, $username, $version;
|
||||
function __construct($username, $protocol = CURRENT_PROTOCOL, $version = CURRENT_VERSION){
|
||||
//$this->player = new Player($username);
|
||||
$this->version = (int) $version;
|
||||
$this->username = $username;
|
||||
$this->cnt = 1;
|
||||
$this->serverID = Utils::readDouble(substr(Utils::generateKey(), 0, 8));
|
||||
$this->events = array("disabled" => array());
|
||||
$this->protocol = (int) $protocol;
|
||||
$this->interface = new MinecraftInterface("255.255.255.255", $this->protocol, 19132, true);
|
||||
console("[INFO] Creating Minecraft Server");
|
||||
console("[INFO] Username: ".$this->username);
|
||||
console("[INFO] Protocol: ".$this->protocol);
|
||||
$this->stop = false;
|
||||
}
|
||||
|
||||
public function start(){
|
||||
$this->event("onReceivedPacket", "packetHandler", true);
|
||||
$this->process();
|
||||
}
|
||||
|
||||
public function packetHandler($packet, $event){
|
||||
$data =& $packet["data"];
|
||||
switch($packet["pid"]){
|
||||
case 0x02:
|
||||
$this->send(0x1c, array(
|
||||
$data[0],
|
||||
$this->serverID,
|
||||
MAGIC,
|
||||
"MCCPP;Demo;". $this->username,
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
break;
|
||||
case 0x05:
|
||||
$version = $data[1];
|
||||
$size = strlen($data[2]);
|
||||
console("[DEBUG] ".$packet["ip"].":".$packet["port"]." v".$version." handshake (".$size.")", true, true, 2);
|
||||
$this->send(0x06, array(
|
||||
MAGIC,
|
||||
$this->serverID,
|
||||
$this->version,
|
||||
$size,
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
break;
|
||||
case 0x07:
|
||||
$bytes = $data[1];
|
||||
$port = $data[2];
|
||||
$size = $data[3];
|
||||
$x = $data[4];
|
||||
$sess = $data[5];
|
||||
//console("[DEBUG] ".$packet["ip"].":".$packet["port"]." v".$version." response (".$size.")", true, true, 2);
|
||||
$sess2 = Utils::readInt(substr(Utils::generateKey(), 0, 4));
|
||||
$this->send(0x08, array(
|
||||
MAGIC,
|
||||
$x,
|
||||
$sess2,
|
||||
$bytes,
|
||||
$packet["port"],
|
||||
$size,
|
||||
0x00
|
||||
), false, $packet["ip"], $packet["port"]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function send($pid, $data = array(), $raw = false, $dest = false, $port = false){
|
||||
$this->trigger($pid, $data);
|
||||
$this->trigger("onSentPacket", $data);
|
||||
$this->interface->writePacket($pid, $data, $raw, $dest, $port);
|
||||
}
|
||||
|
||||
public function process(){
|
||||
while($this->stop === false){
|
||||
$packet = $this->interface->readPacket();
|
||||
if($packet !== false){
|
||||
$this->trigger("onReceivedPacket", $packet);
|
||||
$this->trigger($packet["pid"], $packet);
|
||||
}
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
public function trigger($event, $data = ""){
|
||||
console("[INTERNAL] Event ". $event, true, true, 3);
|
||||
if(isset($this->events[$event]) and !isset($this->events["disabled"][$event])){
|
||||
foreach($this->events[$event] as $eid => $ev){
|
||||
if(isset($ev[1]) and ($ev[1] === true or is_object($ev[1]))){
|
||||
$this->responses[$eid] = call_user_func(array(($ev[1] === true ? $this:$ev[1]), $ev[0]), $data, $event, $this);
|
||||
}else{
|
||||
$this->responses[$eid] = call_user_func($ev[0], $data, $event, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public function toggleEvent($event){
|
||||
if(isset($this->events["disabled"][$event])){
|
||||
unset($this->events["disabled"][$event]);
|
||||
console("[INTERNAL] Enabled event ".$event, true, true, 3);
|
||||
}else{
|
||||
$this->events["disabled"][$event] = false;
|
||||
console("[INTERNAL] Disabled event ".$event, true, true, 3);
|
||||
}
|
||||
}
|
||||
|
||||
public function event($event, $func, $in = false){
|
||||
++$this->cnt;
|
||||
if(!isset($this->events[$event])){
|
||||
$this->events[$event] = array();
|
||||
}
|
||||
$this->events[$event][$this->cnt] = array($func, $in);
|
||||
console("[INTERNAL] Attached to event ".$event, true, true, 3);
|
||||
return $this->cnt;
|
||||
}
|
||||
|
||||
public function deleteEvent($event, $id = -1){
|
||||
if($id === -1){
|
||||
unset($this->events[$event]);
|
||||
}else{
|
||||
unset($this->events[$event][$id]);
|
||||
if(isset($this->events[$event]) and count($this->events[$event]) === 0){
|
||||
unset($this->events[$event]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
33
classes/Session.class.php
Normal file
33
classes/Session.class.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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 Session{
|
||||
|
||||
|
||||
|
||||
}
|
98
classes/Socket.class.php
Normal file
98
classes/Socket.class.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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 Socket{
|
||||
private $encrypt;
|
||||
var $buffer, $connected, $errors, $sock, $server;
|
||||
|
||||
function __construct($server, $port, $listen = false, $socket = false){
|
||||
$this->errors = array_fill(88,(125 - 88) + 1, true);
|
||||
$this->server = $server;
|
||||
$this->port = $port;
|
||||
if($socket !== false){
|
||||
$this->sock = $socket;
|
||||
$this->connected = true;
|
||||
$this->buffer = array();
|
||||
$this->unblock();
|
||||
}else{
|
||||
$this->sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
|
||||
socket_set_option($this->sock, SOL_SOCKET, SO_BROADCAST, 1);
|
||||
if($listen !== true){
|
||||
$this->connected = true;
|
||||
$this->buffer = array();
|
||||
$this->unblock();
|
||||
}else{
|
||||
socket_bind($this->sock, "0.0.0.0", $port);
|
||||
$this->unblock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function listenSocket(){
|
||||
$sock = @socket_accept($this->sock);
|
||||
if($sock !== false){
|
||||
$sock = new Socket(false, false, false, $sock);
|
||||
$sock->unblock();
|
||||
return $sock;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function close($error = 125){
|
||||
$this->connected = false;
|
||||
if($error === false){
|
||||
console("[ERROR] [Socket] Socket closed, Error: End of Stream");
|
||||
}else{
|
||||
console("[ERROR] [Socket] Socket closed, Error $error: ".socket_strerror($error));
|
||||
}
|
||||
return @socket_close($this->sock);
|
||||
}
|
||||
|
||||
public function block(){
|
||||
socket_set_block($this->sock);
|
||||
}
|
||||
|
||||
public function unblock(){
|
||||
socket_set_nonblock($this->sock);
|
||||
}
|
||||
|
||||
public function read(){
|
||||
$source = false;
|
||||
$port = 1;
|
||||
$len = @socket_recvfrom($this->sock, $buf, 65536, 0, $source, $port);
|
||||
return array($buf, $source, $port, $len);
|
||||
}
|
||||
|
||||
public function write($data, $dest = false, $port = false){
|
||||
return @socket_sendto($this->sock, $data, strlen($data), 0, ($dest === false ? $this->server:$dest), ($port === false ? $this->port:$port));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
314
classes/Utils.class.php
Normal file
314
classes/Utils.class.php
Normal file
@ -0,0 +1,314 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
if(!defined("GMPEXT")){
|
||||
@define("GMPEXT", false);
|
||||
}
|
||||
if(!defined("HEX2BIN")){
|
||||
@define("HEX2BIN", false);
|
||||
}
|
||||
|
||||
define("BIG_ENDIAN", 0x00);
|
||||
define("LITTLE_ENDIAN", 0x01);
|
||||
define("ENDIANNESS", (pack('d', 1) === "\77\360\0\0\0\0\0\0" ? BIG_ENDIAN:LITTLE_ENDIAN));
|
||||
console("[DEBUG] Endianness: ".(ENDIANNESS === LITTLE_ENDIAN ? "Little Endian":"Big Endian"), true, true, 2);
|
||||
|
||||
class Utils{
|
||||
public static $hexToBin = array(
|
||||
"0" => "0000",
|
||||
"1" => "0001",
|
||||
"2" => "0010",
|
||||
"3" => "0011",
|
||||
"4" => "0100",
|
||||
"5" => "0101",
|
||||
"6" => "0110",
|
||||
"7" => "0111",
|
||||
"8" => "1000",
|
||||
"9" => "1001",
|
||||
"a" => "1010",
|
||||
"b" => "1011",
|
||||
"c" => "1100",
|
||||
"d" => "1101",
|
||||
"e" => "1110",
|
||||
"f" => "1111",
|
||||
);
|
||||
|
||||
public static function round($number){
|
||||
return round($number, 0, PHP_ROUND_HALF_DOWN);
|
||||
}
|
||||
|
||||
public static function generateKey($startEntropy = ""){
|
||||
//not much entropy, but works ^^
|
||||
$entropy = array(
|
||||
implode(stat(__FILE__)),
|
||||
lcg_value(),
|
||||
print_r($_SERVER, true),
|
||||
implode(mt_rand(0,394),get_defined_constants()),
|
||||
get_current_user(),
|
||||
print_r(ini_get_all(),true),
|
||||
(string) memory_get_usage(),
|
||||
php_uname(),
|
||||
phpversion(),
|
||||
zend_version(),
|
||||
getmypid(),
|
||||
mt_rand(),
|
||||
rand(),
|
||||
implode(get_loaded_extensions()),
|
||||
sys_get_temp_dir(),
|
||||
disk_free_space("."),
|
||||
disk_total_space("."),
|
||||
(function_exists("openssl_random_pseudo_bytes") and version_compare(PHP_VERSION, "5.3.4", ">=")) ? openssl_random_pseudo_bytes(16):microtime(true),
|
||||
function_exists("mcrypt_create_iv") ? mcrypt_create_iv(16, MCRYPT_DEV_URANDOM):microtime(true),
|
||||
uniqid(microtime(true),true),
|
||||
file_exists("/dev/urandom") ? fread(fopen("/dev/urandom", "rb"),16):microtime(true),
|
||||
);
|
||||
shuffle($entropy);
|
||||
$value = Utils::hexToStr(md5((string) $startEntropy));
|
||||
unset($startEntropy);
|
||||
foreach($entropy as $c){
|
||||
$c = (string) $c;
|
||||
for($i = 0; $i < 4; ++$i){
|
||||
$value ^= md5($i . $c . microtime(true), true);
|
||||
$value ^= substr(sha1($i . $c . microtime(true), true),$i,16);
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function sha1($input){
|
||||
$binary = Utils::hexToBin(sha1($input));
|
||||
$negative = false;
|
||||
$len = strlen($binary);
|
||||
if($binary{0} === "1"){
|
||||
$negative = true;
|
||||
for($i = 0; $i < $len; ++$i){
|
||||
$binary{$i} = $binary{$i} === "1" ? "0":"1";
|
||||
}
|
||||
for($i = $len - 1; $i >= 0; --$i){
|
||||
if($binary{$i} === "1"){
|
||||
$binary{$i} = "0";
|
||||
}else{
|
||||
$binary{$i} = "1";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$hash = Utils::binToHex($binary);
|
||||
$len = strlen($hash);
|
||||
for($i = 0; $i < $len; ++$i){
|
||||
if($hash{$i} === "0"){
|
||||
$hash{$i} = "x";
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ($negative === true ? "-":"").str_replace("x", "", $hash);
|
||||
}
|
||||
|
||||
public static function microtime(){
|
||||
return microtime(true);
|
||||
}
|
||||
|
||||
public static function curl_get($page){
|
||||
$ch = curl_init($page);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent: Minecraft PHP Client 2'));
|
||||
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
|
||||
$ret = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function curl_post($page, $args, $timeout = 10){
|
||||
$ch = curl_init($page);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $args);
|
||||
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent: Minecraft PHP Client 2'));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, (int) $timeout);
|
||||
$ret = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function strToBin($str){
|
||||
return Utils::hexToBin(Utils::strToHex($str));
|
||||
}
|
||||
|
||||
public static function hexToBin($hex){
|
||||
$bin = "";
|
||||
$len = strlen($hex);
|
||||
for($i = 0; $i < $len; ++$i){
|
||||
$bin .= Utils::$hexToBin[$hex{$i}];
|
||||
}
|
||||
return $bin;
|
||||
}
|
||||
|
||||
public static function binToStr($bin){
|
||||
$len = strlen($bin);
|
||||
if(($len % 8) != 0){
|
||||
$bin = substr($bin, 0, -($len % 8));
|
||||
}
|
||||
$str = "";
|
||||
for($i = 0; $i < $len; $i += 8){
|
||||
$str .= chr(bindec(substr($bin, $i, 8)));
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
public static function binToHex($bin){
|
||||
$len = strlen($bin);
|
||||
if(($len % 8) != 0){
|
||||
$bin = substr($bin, 0, -($len % 8));
|
||||
}
|
||||
$hex = "";
|
||||
for($i = 0; $i < $len; $i += 4){
|
||||
$hex .= dechex(bindec(substr($bin, $i, 4)));
|
||||
}
|
||||
return $hex;
|
||||
}
|
||||
|
||||
public static function strToHex($str){
|
||||
return bin2hex($str);
|
||||
}
|
||||
|
||||
public static function hexToStr($hex){
|
||||
if(HEX2BIN === true){
|
||||
return hex2bin($hex);
|
||||
}
|
||||
return pack("H*" , $hex);
|
||||
}
|
||||
|
||||
public static function readString($str){
|
||||
return preg_replace('/\x00(.)/s', '$1', $str);
|
||||
}
|
||||
|
||||
public static function writeString($str){
|
||||
return preg_replace('/(.)/s', "\x00$1", $str);
|
||||
}
|
||||
|
||||
public static function readBool($b){
|
||||
return Utils::readByte($b, false) === 0 ? false:true;
|
||||
}
|
||||
|
||||
public static function writeBool($b){
|
||||
return Utils::writeByte($b === true ? 1:0);
|
||||
}
|
||||
|
||||
public static function readByte($c, $signed = true){
|
||||
$b = ord($c{0});
|
||||
if($signed === true and ($b & 0x80) === 0x80){ //calculate Two's complement
|
||||
$b = -0x80 + ($b & 0x7f);
|
||||
}
|
||||
return $b;
|
||||
}
|
||||
|
||||
public static function writeByte($c){
|
||||
if($c > 0xff){
|
||||
return false;
|
||||
}
|
||||
if($c < 0 and $c >= -0x80){
|
||||
$c = 0xff + $c + 1;
|
||||
}
|
||||
return chr($c);
|
||||
}
|
||||
|
||||
public static function readShort($str, $signed = true){
|
||||
list(,$unpacked) = unpack("n", $str);
|
||||
if($unpacked > 0x7fff and $signed === true){
|
||||
$unpacked -= 0x10000; // Convert unsigned short to signed short
|
||||
}
|
||||
return $unpacked;
|
||||
}
|
||||
|
||||
public static function writeShort($value){
|
||||
if($value < 0){
|
||||
$value += 0x10000;
|
||||
}
|
||||
return pack("n", $value);
|
||||
}
|
||||
|
||||
public static function readInt($str){
|
||||
list(,$unpacked) = unpack("N", $str);
|
||||
return (int) $unpacked;
|
||||
}
|
||||
|
||||
public static function writeInt($value){
|
||||
if($value < 0){
|
||||
$value += 0x100000000;
|
||||
}
|
||||
return pack("N", $value);
|
||||
}
|
||||
|
||||
public static function readFloat($str){
|
||||
list(,$value) = ENDIANNESS === BIG_ENDIAN?unpack('f', $str):unpack('f', strrev($str));
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function writeFloat($value){
|
||||
return ENDIANNESS === BIG_ENDIAN?pack('f', $value):strrev(pack('f', $value));
|
||||
}
|
||||
|
||||
public static function readDouble($str){
|
||||
list(,$value) = ENDIANNESS === BIG_ENDIAN?unpack('d', $str):unpack('d', strrev($str));
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function writeDouble($value){
|
||||
return ENDIANNESS === BIG_ENDIAN?pack('d', $value):strrev(pack('d', $value));
|
||||
}
|
||||
|
||||
public static function readLong($str){
|
||||
list(,$firstHalf,$secondHalf) = unpack("N*", $str);
|
||||
if(GMPEXT === true){
|
||||
$value = gmp_add($secondHalf, gmp_mul($firstHalf, "0x100000000"));
|
||||
if(gmp_cmp($value, "0x8000000000000000") >= 0){
|
||||
$value = gmp_sub($value, "0x10000000000000000");
|
||||
}
|
||||
return gmp_strval($value);
|
||||
}else{
|
||||
$value = bcadd($secondHalf, bcmul($firstHalf, "4294967296"));
|
||||
if(bccomp($value, "9223372036854775808") >= 0){
|
||||
$value = bcsub($value, "18446744073709551616");
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
public static function writeLong($value){
|
||||
return ENDIANNESS === BIG_ENDIAN?pack('d', $value):strrev(pack('d', $value));
|
||||
}
|
||||
|
||||
}
|
39
common/config.php
Normal file
39
common/config.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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);
|
||||
error_reporting(E_ALL ^ E_NOTICE);
|
||||
ini_set("display_errors", 1);
|
||||
ini_set('default_charset', 'utf-8');
|
||||
define("FILE_PATH", dirname(__FILE__)."/../");
|
||||
set_include_path(get_include_path() . PATH_SEPARATOR . FILE_PATH . PATH_SEPARATOR . FILE_PATH . "/classes/");
|
||||
ini_set("memory_limit", "512M");
|
||||
define("CURRENT_PROTOCOL", 1);
|
||||
define("CURRENT_VERSION", 5);
|
||||
define("DEBUG", 3);
|
||||
define("LOG", true);
|
||||
define("MAGIC", "\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78");
|
77
common/dependencies.php
Normal file
77
common/dependencies.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
require_once(dirname(__FILE__)."/config.php");
|
||||
require_once("common/functions.php");
|
||||
|
||||
$errors = 0;
|
||||
|
||||
if(version_compare("5.3.3", PHP_VERSION) > 0){
|
||||
console("[ERROR] Use PHP >= 5.3.3", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(version_compare("5.4.0", PHP_VERSION) > 0){
|
||||
console("[NOTICE] Use PHP >= 5.4.0 to increase performance", true, true, 0);
|
||||
define("HEX2BIN", false);
|
||||
}else{
|
||||
define("HEX2BIN", true);
|
||||
}
|
||||
|
||||
if(php_sapi_name()!=="cli"){
|
||||
console("[ERROR] Use PHP-CLI to execute the client or create your own", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("gmp")){
|
||||
console("[NOTICE] Enable GMP extension to increase performance", true, true, 0);
|
||||
define("GMPEXT", false);
|
||||
}else{
|
||||
define("GMPEXT", true);
|
||||
}
|
||||
|
||||
if(!function_exists("gzinflate")){
|
||||
console("[ERROR] Unable to find Zlib extension", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!function_exists("socket_create")){
|
||||
console("[ERROR] Unable to find Socket functions", true, true, 0);
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if($errors > 0){
|
||||
die();
|
||||
}
|
||||
|
||||
require_once("classes/Utils.class.php");
|
||||
require_once("classes/Socket.class.php");
|
||||
require_once("classes/Packet.class.php");
|
||||
require_once("classes/MinecraftInterface.class.php");
|
||||
|
||||
?>
|
180
common/functions.php
Normal file
180
common/functions.php
Normal file
@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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 arg($name, $default){
|
||||
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){
|
||||
//global $path;
|
||||
if(!defined("DEBUG") or DEBUG >= $level){
|
||||
$message .= $EOL === true ? PHP_EOL:"";
|
||||
$message = date("H:i:s"). " ". $message;
|
||||
if($log === true and (!defined("LOG") or LOG === true)){
|
||||
logg($message, "console", false, $level);
|
||||
}
|
||||
echo $message;
|
||||
}
|
||||
}
|
||||
|
||||
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])){
|
||||
$fpointers[$name] = fopen(FILE_PATH."/".$name.".log", "ab");
|
||||
}
|
||||
fwrite($fpointers[$name], $message);
|
||||
if($close === true){
|
||||
fclose($fpointers[$name]);
|
||||
unset($fpointers[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hexdump($data, $htmloutput = true, $uppercase = false, $return = false)
|
||||
{
|
||||
// Init
|
||||
$hexi = '';
|
||||
$ascii = '';
|
||||
$dump = ($htmloutput === true) ? '<pre>' : '';
|
||||
$offset = 0;
|
||||
$len = strlen($data);
|
||||
|
||||
// Upper or lower case hexadecimal
|
||||
$x = ($uppercase === false) ? 'x' : 'X';
|
||||
|
||||
// Iterate string
|
||||
for ($i = $j = 0; $i < $len; $i++)
|
||||
{
|
||||
// Convert to hexidecimal
|
||||
$hexi .= Utils::strToHex($data[$i]);
|
||||
|
||||
// Replace non-viewable bytes with '.'
|
||||
if (ord($data[$i]) >= 0x20 and ord($data[$i]) < 0x80) {
|
||||
$ascii .= ($htmloutput === true) ?
|
||||
htmlentities($data[$i]) :
|
||||
$data[$i];
|
||||
} else {
|
||||
$ascii .= '.';
|
||||
}
|
||||
|
||||
// Add extra column spacing
|
||||
if ($j === 7) {
|
||||
$hexi .= ' ';
|
||||
$ascii .= ' ';
|
||||
}
|
||||
|
||||
// Add row
|
||||
if (++$j === 16 || $i === $len - 1) {
|
||||
// Join the hexi / ascii output
|
||||
$dump .= sprintf("%04$x %-49s %s", $offset, $hexi, $ascii);
|
||||
|
||||
// Reset vars
|
||||
$hexi = $ascii = '';
|
||||
$offset += 16;
|
||||
$j = 0;
|
||||
|
||||
// Add newline
|
||||
if ($i !== $len - 1) {
|
||||
$dump .= "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finish dump
|
||||
$dump .= $htmloutput === true ?
|
||||
'</pre>' :
|
||||
'';
|
||||
$dump .= "\n";
|
||||
|
||||
$dump = preg_replace("/[^[:print:]\\r\\n]/", ".", $dump);
|
||||
|
||||
// Output method
|
||||
if ($return === false) {
|
||||
echo $dump;
|
||||
} else {
|
||||
return $dump;
|
||||
}
|
||||
}
|
90
pstruct/RakNet.php
Normal file
90
pstruct/RakNet.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
$pstruct = array(
|
||||
0x02 => array(
|
||||
"double",
|
||||
"magic",
|
||||
),
|
||||
|
||||
0x05 => array(
|
||||
"magic",
|
||||
"byte",
|
||||
"special1",
|
||||
),
|
||||
|
||||
0x06 => array(
|
||||
"magic",
|
||||
"double",
|
||||
"byte",
|
||||
"short",
|
||||
),
|
||||
|
||||
0x07 => array(
|
||||
"magic",
|
||||
5,
|
||||
"short",
|
||||
"short",
|
||||
"int",
|
||||
"int",
|
||||
),
|
||||
|
||||
0x08 => array(
|
||||
"magic",
|
||||
"int",
|
||||
"int",
|
||||
5,
|
||||
"short",
|
||||
"short",
|
||||
"byte",
|
||||
),
|
||||
|
||||
0x1c => array(
|
||||
"double",
|
||||
"double",
|
||||
"magic",
|
||||
"string",
|
||||
),
|
||||
|
||||
0x1d => array(
|
||||
"double",
|
||||
"double",
|
||||
"magic",
|
||||
"string",
|
||||
),
|
||||
|
||||
0x84 => array(
|
||||
"byte",
|
||||
9,
|
||||
"int",
|
||||
"int",
|
||||
5,
|
||||
3,
|
||||
"byte",
|
||||
),
|
||||
|
||||
);
|
37
pstruct/packetName.php
Normal file
37
pstruct/packetName.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
$packetName = array(
|
||||
0x02 => "ID_UNCONNECTED_PING_OPEN_CONNECTIONS",
|
||||
0x05 => "ID_OPEN_CONNECTION_REQUEST_1",
|
||||
0x06 => "ID_OPEN_CONNECTION_REPLY_1",
|
||||
0x07 => "ID_OPEN_CONNECTION_REQUEST_2",
|
||||
0x08 => "ID_OPEN_CONNECTION_REPLY_2",
|
||||
0x1c => "ID_UNCONNECTED_PONG",
|
||||
0x1d => "ID_ADVERTISE_SYSTEM",
|
||||
|
||||
);
|
33
server.php
Normal file
33
server.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
require_once("common/dependencies.php");
|
||||
require_once("classes/PocketMinecraftServer.class.php");
|
||||
file_put_contents("packets.log", "");
|
||||
|
||||
$server = new PocketMinecraftServer("shoghicp");
|
||||
$server->start();
|
Loading…
x
Reference in New Issue
Block a user