├── LICENSE
├── README
├── chat.bat
├── chat.php
├── chat_help.php
├── chunk.php
├── client.php
├── command.php
├── dynmap.php
├── forking.php
├── functions.php
├── materials.php
├── nbt.class.php
├── packets.php
├── packets
└── 03Chat.php
├── pstruct.php
└── pstruct_modifier.php
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | This program is free software: you can redistribute it and/or modify
2 | it under the terms of the GNU Lesser General Public License as published by
3 | the Free Software Foundation, either version 3 of the License, or
4 | (at your option) any later version.
5 |
6 | This program is distributed in the hope that it will be useful,
7 | but WITHOUT ANY WARRANTY; without even the implied warranty of
8 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 | GNU Lesser General Public License for more details.
10 |
11 | You should have received a copy of the GNU Lesser General Public License
12 | along with this program. If not, see .
13 |
14 |
15 | / \
16 | / \
17 | / MINECRAFT \
18 | / PHP \
19 | |\ CLIENT /|
20 | |. \ / .|
21 | | ´. \ / .´ |
22 | | ´. | .´ |
23 | | ´. | .´ |
24 | \ | /
25 | \ | /
26 | \ | /
27 | \ | /
28 |
29 | by @shoghicp
30 |
31 |
32 |
33 | WARNONG: This program is superseded by Minecraft PHP Client 2
34 |
35 |
36 | Run client.php with PHP-CLI
37 |
38 | Example:
39 |
40 | php client.php --help
41 |
--------------------------------------------------------------------------------
/chat.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | php chat.php
3 | exit
--------------------------------------------------------------------------------
/chat.php:
--------------------------------------------------------------------------------
1 | $say";
13 | file_put_contents("chat.input",$say,FILE_APPEND);
14 | }
15 | ?>
--------------------------------------------------------------------------------
/chat_help.php:
--------------------------------------------------------------------------------
1 | Pregunta detectada de '.$sender);
7 | if(/*(stripos($value,'comando') or stripos($value,'era') or stripos($value,'puedo') or stripos($value,'hago') or stripos($value,'voy') or stripos($value,'podr') or stripos($value,'es')) and */(stripos($value,'cuando') or stripos($value,'cual') or stripos($value,'que') or stripos($value,'para') or stripos($value,'algu') or stripos($value,'como') or stripos($value,'quien') or (stripos($value,'donde') and (stripos($value,'pued') or stripos($value,'podr'))) or stripos($value,'pued')) and !stripos($value,'porque') and !stripos($value,'por que')){
8 | if(!stripos($value,' tu ') and !stripos($value,'te ') and !stripos($value,' me ')){
9 | if((stripos($value,'admin') or stripos($value,' mod') or stripos($value,' op') or stripos($value,'staff')) and (stripos($value,'quien') or stripos($value,'cual'))){
10 | /* Admins */
11 | privateMessage('los moderadores de este servidor son Duendek86, Zaden, Kreador, susoboiro, creik, LoscoJones, Xerri92, milodescorpio. Dirigete a ellos si tienes problemas.',$sender);
12 | }
13 | if(stripos($value,'mcmmo') or stripos($value,'stats') or stripos($value,'abil') or stripos($value,'skill') or stripos($value,'drill') or stripos($value,'berserk')){
14 | /* McMMO */
15 | privateMessage('McMMO sirve para dar habilidades especiales tipicas de juegos MMO a Minecraft. Mas info con "/mcc"',$sender);
16 | }
17 | if(stripos($value,'curar') or stripos($value,'sanar')){
18 | /* curacion */
19 | privateMessage('puedes curarte en una Residence que pueda curar o comiendo comida. Puedes poner en tu Residence "/res set healing true" para autocurarte',$sender);
20 | }
21 | if(stripos($value,'cartel') and stripos($value,'color')){
22 | /* Colores de carteles */
23 | privateMessage('puedes poner colores al texto poniendo "&" mas un caracter del 1 a F antes del texto',$sender);
24 | }
25 | if(stripos($value,'veteran') and (stripos($value,'como') or stripos($value,'cuando') or stripos($value,'cuanto'))){
26 | /* Veterano */
27 | $text = curl_get('http://mespduendedreams.com/test.php');
28 | $vetearray = explode('',$text);
29 | foreach($vetearray as $text){
30 | if(stripos($text,$sender)){
31 | $days = str_replace(array($sender,' ','
','',' | ','
',"\r","\n"),array('','','','','','','',''),$text);
32 | break;
33 | }
34 | }
35 | if($days>=30){
36 | privateMessage('ya eres veterano. Actualmente has pasado '.$days.' dias en el servidor',$sender);
37 | }else{
38 | privateMessage('seras veterano cuando hayas pasado 30 dias diferentes en el servidor. Actualmente has pasado '.$days.' dias en el servidor',$sender);
39 | }
40 | }
41 | if(stripos($value,'vip')){
42 | /* Vips */
43 | privateMessage('los VIPs tienen acceso a mas comandos, y una atencion mas personalizada. Puedes ser VIP donando al servidor. Mas info en el foro',$sender);
44 | }
45 | if(stripos($value,'comando')){
46 | /* Comandos */
47 | privateMessage('los comandos que puedes utilizar son (con una barra "/" delante): spawn, home, list, lwc, money, sell, buy, mail, msg, helpop, stats',$sender);
48 | }
49 | if(stripos($value,'materia')){
50 | /* Materiales */
51 | privateMessage('lo mejor que puedes hacer es ir a una zona algo alejada y talar arboles. Luego replantalos. Tambien puedes comprar.',$sender);
52 | }
53 | if(stripos($value,'/res') or stripos($value,'residen') or (stripos($value,'terren') or (stripos($value,'prote') and stripos($value,'casa')))){
54 | /* Residence */
55 | privateMessage('marca con el hacha de madera la zona. Luego pon "/res create nombre". Mas info con el comando "/res ?"',$sender);
56 | }
57 | if((stripos($value,'prote') or stripos($value,'bloque') or (stripos($value,'magical') and stripos($value,'spell')) or stripos($value,'lwc') or (stripos($value,' no ') and stripos($value,'rob'))) and !stripos($value,' bloque')){
58 | /* LWC */
59 | privateMessage('puedes proteger cofres, puertas, dispensadores, hornos y carteles con LWC. Pon primero "/cremove" y luego "/cprivate". Mas info con "/lwc"',$sender);
60 | }
61 | if(stripos($value,' ts') or stripos($value,'turnstile') or (stripos($value,'boton') and (stripos($value,'pag') or stripos($value,'cobr') or stripos($value,'cost') or stripos($value,'cueste')))){
62 | /* TurnStile*/
63 | privateMessage('apunta a una valla y pon "/ts make nombre". Luego apunta el boton y pon "/ts link nombre". Mas info con "/ts"',$sender);
64 | }
65 | if(stripos($value,'pay') and stripos($value,'day')){
66 | /* PayDay */
67 | privateMessage('el Pay Day te da dinero al inicio de cada hora que estes conectado. Puedes ver la cantidad de Mesps que te da con "/pd"',$sender);
68 | }
69 | if(stripos($value,'lobo') and (stripos($value,'hay') or stripos($value,'enc') or stripos($value,'sale'))){
70 | /* Lobos */
71 | privateMessage('los lobos se encuentran en la Taiga y los Bosques. Para mayor seguridad, ves a una zona con nieve.',$sender);
72 | }
73 | if(stripos($value,'diner') or (stripos($value,'mesp') and !stripos($value,'algu') and !stripos($value,'city') and !stripos($value,'3') and !stripos($value,'stack') and !stripos($value,'unidad') and !stripos($value,'ciud') and !stripos($value,'nuev')) or stripos($value,'credit') or stripos($value,'money')){
74 | /* Dinero */
75 | if(stripos($value,'gan') or stripos($value,'cons') or stripos($value,'rico') or stripos($value,'mas')){
76 | privateMessage('puedes ganar dinero vendiendo bloques en tiendas, o con el Pay Day. Al inicio de cada hora te daran mesps',$sender);
77 | }else{
78 | privateMessage('para saber cuantos Mesps tienes pon "/money". Mas info con "/money ?"',$sender);
79 | }
80 | }
81 | if(stripos($value,' spawn') or stripos($value,' inicio')){
82 | /* Spawn */
83 | privateMessage('para ir al Spawn pon el comando "/spawn" y espera 5 segundos sin moverte',$sender);
84 | }
85 | if(stripos($value,'pued') and (stripos($value,'constr') or stripos($value,'terreno') or stripos($value,'parce') or stripos($value,'casa'))){
86 | /* Construir casa */
87 | privateMessage('puedes construir donde no molestes a nadie. Tambien puedes alquilar una parcela en una ciudad',$sender);
88 | }
89 | if(((stripos($value,'hay') and stripos($value,'tienda')) or stripos($value,'compr')) and !stripos($value,'terren') and !stripos($value,'casa') and !stripos($value,'parcel') and !stripos($value,'compras')){
90 | /* Tiendas */
91 | privateMessage('puedes comprar en las tiendas. Para ver la lista, pon "bot tiendas"',$sender);
92 | }
93 | if(stripos($value,'casa') or stripos($value,'home')){
94 | /* Home */
95 | /*if(stripos($value,'invit') or stripos($value,'otr')){
96 | //invitar
97 | privateMessage('para invitar a otra persona a tu casa, pon "/home invite nombre"',$sender);
98 | }else*/if(stripos($value,'poner') or stripos($value,'volver') or stripos($value,'voy') or stripos($value,'ir') or stripos($value,'vuelvo')){
99 | /* poner la casa, volver */
100 | privateMessage('puedes establecer tu casa donde estas con "/sethome". Luego puedes volver con "/home"',$sender);
101 | }
102 | }
103 | if(stripos($value,'lava') and stripos($value,'infin') and !stripos($value,'obsi')){
104 | privateMessage('no se puede hacer lava infinita.',$sender);
105 | }
106 | if(stripos($value,'afk')){
107 | privateMessage('AFK significa Away From Keyboard, es decir, lejos del teclado.',$sender);
108 | }
109 | if(stripos($value,'foro')){
110 | privateMessage('el foro de este servidor es http://minecraft-esp.com/',$sender);
111 | }
112 | if((stripos($value,'podria') or stripos($value,'puedo')) and stripos($value,'robar')){
113 | privateMessage('NO',$sender);
114 | }
115 | }
116 | if((stripos($value,'progra') or stripos($value,'cre') or stripos($value,'hizo'))){
117 | privateMessage('me creo shoghicp. Estoy programado en PHP',$sender);
118 | }
119 | if((stripos($value,'llama') or stripos($value,'nombre') or stripos($value,'cread') or stripos($value,'eres'))){
120 | privateMessage('me llamo Bot Ayuda, y estoy aqui para ayudarte en tu inicio.',$sender);
121 | }
122 | if((stripos($value,' dia') or stripos($value,'noche') or stripos($value,'hora') or stripos($value,'tiempo'))){
123 | privateMessage('son las '.((intval($ginfo["time"]/1000+6) % 24)).':'.str_pad(intval(($ginfo["time"]/1000-floor($ginfo["time"]/1000))*60),2,"0",STR_PAD_LEFT).' y es de '.(($ginfo["time"] > 23100 or $ginfo["time"] < 12900) ? "dia":"noche"),$sender);
124 | }
125 | }
126 | }
127 | if(stripos($value,'gay')){
128 | privateMessage('soy un robot. No se que opinaras tu sobre ti.',$sender);
129 | }
130 |
131 | ?>
--------------------------------------------------------------------------------
/chunk.php:
--------------------------------------------------------------------------------
1 | array(),
10 | "meta" => array(),
11 | "blight" => array(),
12 | "slight" => array(),
13 | );
14 | //Loop over 16x16x16 chunks in the 16x256x16 column
15 | $offset = 0;
16 | $read = 4096;
17 | for ($i=0;$i<16;$i++) {
18 | //If the bitmask indicates this chunk has been sent...
19 | if ($bitmask & 1 << $i) {
20 | //Read data...
21 | $cubic_chunk_data = substr($data, $offset, $read); //2048 for the other arrays, where you'll need to split the data
22 | $offset += $read;
23 | $read = 2048;
24 | $len = strlen($cubic_chunk_data);
25 | for($j=0; $j<$len; $j++) {
26 | //Retrieve x,y,z and data from each element in cubic_chunk_array
27 |
28 | //Byte arrays
29 | $x = $chunk_x*16 + $j & 0x0F;
30 | $y = $i*16 + $j >> 8;
31 | $z = $chunk_z*16 + ($j & 0xF0) >> 4;
32 | $data = $cubic_chunk_data[$j];
33 |
34 | //Nibble arrays
35 | $data1 = $cubic_chunk_data[$j] & 0x0F;
36 | $data2 = $cubic_chunk_data[$j] >> 4;
37 |
38 | $k = 2*$j;
39 | $x1 = $chunk_x*16 + $k & 0x0F;
40 | $y1 = $i*16 + $k >> 8;
41 | $z1 = $chunk_z*16 + ($k & 0xF0) >> 4;
42 |
43 | $k++;
44 | $x2 = $chunk_x*16 + $k & 0x0F;
45 | $y2 = $i*16 + $k >> 8;
46 | $z2 = $chunk_z*16 + ($k & 0xF0) >> 4;
47 | }
48 | }
49 | }
50 |
51 | }
52 |
53 | function old_chunk_read($data, $X, $Z, $onlyBlocks = false){
54 | $totalOffset = 0;
55 | $size = strlen($data);
56 | $chunkBlocks = 16 * 16 * 128; //32768
57 | $chunk = array(
58 | "block" => array(),
59 | "meta" => array(),
60 | "blight" => array(),
61 | "slight" => array(),
62 | );
63 | $byte = "";
64 | $half = false;
65 | foreach($chunk as $type => $arr){
66 | if($onlyBlocks == true and $type != "block"){
67 | break;
68 | }
69 | for($offset=0;$offset<$chunkBlocks;++$offset){
70 | if($type=="block"){
71 | /*$x = $X + ($offset >> 11);
72 | $y = $offset & 0x7F;
73 | $z = $Z + (($offset & 0x780) >> 7 );*/
74 | $chunk[$type][] = read_byte($data{$totalOffset+$offset},false);
75 | }else{
76 | /*$x = $X + (($offset/2) >> 11);
77 | $y = ($offset/2) & 0x7F;
78 | $z = $Z + ((($offset/2) & 0x780) >> 7 );*/
79 | $byte = $data{$totalOffset+($offset/2)};
80 | $chunk[$type][] = read_byte($byte & 0x0F,false);
81 | $chunk[$type][] = read_byte(($byte >> 4) & 0x0F,false);
82 | ++$offset;
83 | }
84 | }
85 | $totalOffset += $offset;
86 | }
87 | return $onlyBlocks == true ? $chunk["block"]:$chunk;
88 | }
89 |
90 | function chunk_add($data, $x, $z){
91 | global $chunks;
92 | $x /= 16;
93 | $z /= 16;
94 | $chunks[$x."|".$z] = gzinflate(substr($data,2));
95 | return true;
96 | }
97 |
98 | function chunk_clean($x, $z){
99 | global $chunks;
100 | $x /= 16;
101 | $z /= 16;
102 | if(!isset($chunks[$X."|".$Z])){
103 | return false;
104 | }
105 | $chunks[$x."|".$z] = substr($chunks[$x."|".$z],0,16 + 16 * 128);
106 | return true;
107 | }
108 |
109 | function chunk_load($x, $z){
110 | global $chunks, $tchunk;
111 | if(!isset($tchunk[$x."|".$z]) and isset($chunks[$x."|".$z])){
112 |
113 | $tchunk[$x."|".$z] = chunk_read($chunks[$x."|".$z],$x,$z,true);
114 | return true;
115 | }elseif(isset($tchunk[$x."|".$z])){
116 | return true;
117 | }else{
118 | return false;
119 | }
120 | }
121 |
122 | function chunk_get_radius($x,$y,$z,$r=4){
123 | $r = abs($r);
124 | return chunk_get_zone($x-$r,$y-$r,$z-$r,$x+$r,$y+$r,$z+$r);
125 | }
126 |
127 | function chunk_get_zone($x1,$z1,$y1, $x2,$z2,$y2){
128 | if($x1>$x2 or $y1>$y2 or $z1>$z2){
129 | return false;
130 | }
131 | $blocks = array();
132 | for($x=$x1;$x<=$x2;++$x){
133 | for($y=$y1;$y<=$y2;++$y){
134 | for($z=$z1;$z<=$z2;++$z){
135 | $blocks[$x][$y][$z] = chunk_get_block($x,$y,$z);
136 | }
137 | }
138 | }
139 | return $blocks;
140 | }
141 |
142 | function chunk_get_block($x,$y,$z){
143 | global $chunks, $protocol;
144 | if($protocol <= 23){
145 | return old_chunk_get_block($x,$y,$z);
146 | }
147 | $x = intval($x);
148 | $y = intval($y);
149 | $z = intval($z);
150 | $X = intval($x / 16);
151 | $Z = intval($z / 16);
152 |
153 | $x %= 16;
154 | $y %= 128;
155 | $z %= 16;
156 |
157 | if(!isset($chunks[$X."|".$Z])){
158 | return 0x00; //AIR
159 | }
160 | $index = $y + ($z * 128) + ($x * 128 * 16);
161 | return read_byte($chunks[$X."|".$Z]{$index},false);
162 | }
163 |
164 | function old_chunk_get_block($x,$y,$z){
165 | global $chunks;
166 | $x = intval($x);
167 | $y = intval($y);
168 | $z = intval($z);
169 | $X = intval($x / 16);
170 | $Z = intval($z / 16);
171 |
172 | $x %= 16;
173 | $y %= 128;
174 | $z %= 16;
175 |
176 | if(!isset($chunks[$X."|".$Z])){
177 | return 0x00; //AIR
178 | }
179 | $index = $y + ($z * 128) + ($x * 128 * 16);
180 | return read_byte($chunks[$X."|".$Z]{$index},false);
181 | }
182 |
183 | function chunk_edit_block($x,$y,$z,$value){
184 | global $chunks;
185 | $x = intval($x);
186 | $y = intval($y);
187 | $z = intval($z);
188 | $X = intval($x / 16);
189 | $Z = intval($z / 16);
190 | $x %= 16;
191 | $y %= 128;
192 | $z %= 16;
193 |
194 | if(!isset($chunks[$X."|".$Z])){
195 | return false;
196 | }
197 | $index = $y + ($z * 128) + ($x * 128 * 16);
198 | $chunks[$X."|".$Z]{$index} = write_byte($value,false);
199 | return true;
200 | }
201 |
202 | ?>
203 |
--------------------------------------------------------------------------------
/client.php:
--------------------------------------------------------------------------------
1 | 29,
26 | "1.2.4" => 29,
27 | "1.2.3" => 28,
28 | "1.2.2" => 28,
29 | "1.2.1" => 28,
30 | "1.2.0" => 28,
31 | "1.1.0" => 23,
32 | "1.0.1" => 22,
33 | "1.0.0" => 22,
34 | "b1.8.1" => 17,
35 | "b1.8" => 17,
36 | "b1.7.3" => 14,
37 | "b1.7.2" => 14,
38 | "b1.7_01" => 14,
39 | "b1.7" => 14,
40 | "b1.6.6" => 12,
41 | "b1.6" => 12,
42 | );
43 |
44 | $lastver = "1.2.5";
45 |
46 |
47 | echo << Server to connect, default "127.0.0.1"
82 | \tport => Port to connect, default "25565"
83 | \tversion => Version of server, default "$lastver"
84 | \tprotocol
85 | \tusername => username to use in server and minecraft.net (if PREMIUM), default "Player"
86 | \tpassword => password to use in minecraft.net, if PREMIUM
87 | \tsecure => use HTTPS to connect to minecraft.net
88 | \tdump => dump map chunks (experimental! [no crash])
89 | \tlog => write a log in packets.log, console.log and raw.log, or if you specify an option, only one
90 | \tping => ping (packet 0xFE) a server, and returns info
91 | \thide => hides elements here from console, separated by a comma (sign, chat, nspawn, state, position)
92 | \tcrazyness => moves around doing things (moves head) (values: mad, normal)
93 | \towner => set owner (follow, commands)
94 | \tonly-food => only accept food as inventory items (default false)
95 | \tdynmap => enables dynmap if a port is given (default false)
96 | \tthreading => enables threading, only on linux BETA (default false)
97 |
98 | Example:
99 | php {$argv[0]} --server=127.0.0.1 --username=Player --version=b1.8.1 --hide=sign,chat
100 |
101 | USAGE;
102 | die();
103 | }
104 | $server = arg("server", "127.0.0.1");
105 | $port = arg("port", "25565");
106 | $username = arg("username", "Player");
107 | $password = arg("password", "");
108 | $secure = arg("secure", false);
109 | $version = arg("version", $lastver);
110 | $protocol = intval(arg("protocol", $versions[$lastver]));
111 |
112 | if(arg("log", false) != false){
113 | if(arg("log", false) == "raw"){
114 | file_put_contents($path."raw_recv.log", "");
115 | file_put_contents($path."raw_sent.log", "");
116 | }
117 | file_put_contents($path."packets.log", "");
118 | file_put_contents($path."console.log", "");
119 | }
120 | if($version != $lastver){
121 | $protocol = $versions[$version];
122 | }
123 |
124 | $colorchar = "\xa7";
125 |
126 | }
127 | include("materials.php");
128 | include("pstruct.php");
129 | include("pstruct_modifier.php");
130 |
131 | if(!defined("CLIENT_LOADED")){
132 |
133 | $logged_in = false;
134 | $connected = true;
135 |
136 | $login = array("last_version" => "", "download_ticket" => "", "username" => $username, "session_id" => "");
137 |
138 | }
139 |
140 | $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
141 |
142 | if(@socket_connect($sock, $server, $port) === false){
143 | console("[-] Couldn't connect to server");
144 | die();
145 | }
146 | socket_set_block($sock);
147 |
148 | socket_set_option($sock, SOL_SOCKET, SO_KEEPALIVE, 1);
149 | socket_set_option($sock, SOL_TCP, TCP_NODELAY, 1);
150 |
151 | if(FORKING && arg("threading", false) != false){
152 | console("[+] Threading enabled");
153 | include_once("forking.php");
154 | }else{
155 | define("THREADED", false);
156 | }
157 |
158 | if(arg("ping", false) != false){
159 | console("[+] Pinging ".$server.":".$port." ...");
160 | write_packet("fe");
161 | buffer();
162 | $packet = parse_packet();
163 | if($packet["pid"] == "ff"){
164 | $info = explode($colorchar,$packet["message"]);
165 | console("[*] Name: ".$info[0]);
166 | console("[*] Online players: ".$info[1]);
167 | console("[*] Max players: ".$info[2]);
168 | }
169 | die();
170 | }
171 |
172 |
173 | $hide = explode(",", arg("hide", ""));
174 |
175 | /*
176 |
177 | ------------------ AUTH START -----------------
178 |
179 | */
180 |
181 | console("[*] Sending Handshake");
182 | write_packet("02", array(
183 | "username" => $username,
184 | "server" => $server.":".$port,
185 | ));
186 |
187 | buffer();
188 | $packet = parse_packet(); //Wait for Server Handshake
189 |
190 | if($packet["server_id"] != "-" and $packet["server_id"] != "+"){
191 | console("[*] Server is Premium (SID: ".$packet["server_id"].")");
192 | if($packet["server_id"] == "" or strpos($packet["server_id"], "&") !== false){
193 | console("[!] NAME SPOOF DETECTED");
194 | }
195 | if(!defined("CLIENT_LOADED")){
196 | if($secure !== false){
197 | $proto = "https";
198 | console("[+] Using secure HTTPS connection");
199 | }else{
200 | $proto = "http";
201 | }
202 |
203 | $response = curl_get($proto."://login.minecraft.net/?user=".$username."&password=".$password."&version=12");
204 | switch($response){
205 | case 'Bad Login':
206 | console("[-] Bad login");
207 | die();
208 | break;
209 | case "Old Version":
210 | console("[-] Old Version");
211 | die();
212 | break;
213 | default:
214 | $content = explode(":",$response);
215 | if(!is_array($content)){
216 | console("[-] Unknown Login Error: \"".$response."\"");
217 | die();
218 | }
219 | $login["last_version"] = $content[0];
220 | $login["download_ticket"] = $content[1];
221 | $login["username"] = $content[2];
222 | $username = $content[2];
223 | $login["session_id"] = $content[3];
224 | console("[+] Logged into minecraft.net");
225 | break;
226 | }
227 | }
228 | $res = curl_get("http://session.minecraft.net/game/joinserver.jsp?user=".$username."&sessionId=".$login["session_id"]."&serverId=".$packet["server_id"]); //User check
229 | if($res != "OK"){
230 | console("[-] Error in User Check: \"".$res."\"");
231 | die();
232 | }
233 | }else{
234 | console("[*] Server is not Premium");
235 | }
236 | console("[*] Sending Login Request");
237 |
238 | write_packet("01",array(
239 | "version" => $protocol,
240 | "username" => $username,
241 | ));
242 |
243 | socket_set_nonblock($sock);
244 | define('CLIENT_LOADED', true);
245 | /*
246 | ---------- AUTH FINALIZED --------------
247 | */
248 |
249 | $position_packet = false;
250 | $next = 0;
251 | $start = $next;
252 | $moving = 0;
253 | $chunks = array();
254 | $tchunk = array();
255 | $ginfo = array(
256 | "eid" => 0,
257 | "seed" => 0,
258 | "dimension" => 0,
259 | "difficulty" => 0,
260 | "level_type" => "DEFAULT",
261 | "mode" => 0,
262 | "height" => 128,
263 | "crouch" => 0,
264 | "jump" => 0,
265 | "health" => 20,
266 | "food" => 20,
267 | "timer" => array(
268 | "restart" => time() + RESTART_TIME,
269 | ),
270 | "state" => array(),
271 | "time" => 0,
272 | "follow" => 0,
273 | "fly" => false,
274 | "inventory" => array(),
275 | "attack" => false,
276 | "aura" => false,
277 | "owner" => array(
278 | "name" => arg("owner", "shoghicp"),
279 | ),
280 | );
281 | $entities = array();
282 | $players = array();
283 | $permissions = array(
284 | $ginfo["owner"]["name"] => 3,
285 | /*
286 | If you want some mods for the bot, add usernames here
287 | */
288 | $username => 3,
289 | "susoboiro" => 2,
290 | "LoscoJones" => 2,
291 | "milodescorpio" => 2,
292 | "Duendek86" => 2,
293 | "kopron" => 2,
294 | "creik" => 2,
295 | "Sir_Pinkata" => 2,
296 | );
297 | $recorder = array("mode" => "", "name" => "", "positions" => "");
298 | $restart = false;
299 |
300 |
301 | while($sock and $restart == false){
302 | $time = microtime(true);
303 | if(strlen($buffer) > 0){
304 | $packet = parse_packet();
305 | switch($packet["pid"]){
306 | case "00":
307 | write_packet("00",$packet);
308 | break;
309 | case "01":
310 | console("[+] Login Request accepted");
311 | console("[*] EID: ".$packet["eid"]);
312 | console("[*] Seed: ".$packet["seed"]);
313 | $ginfo["eid"] = $packet["eid"];
314 | $ginfo["seed"] = $packet["seed"];
315 | $ginfo["level_type"] = $packet["level_type"];
316 | $ginfo["dimension"] = $packet["dimension"];
317 | $ginfo["difficulty"] = $packet["difficulty"];
318 | $ginfo["mode"] = $packet["mode"];
319 | $ginfo["height"] = $packet["height"];
320 | if($protocol>=17){
321 | console("[*] Gamemode: ".($packet["mode"]==0 ? "survival":"creative"));
322 | console("[*] Max players: ".$packet["max_players"]);
323 | }
324 | $logged_in = true;
325 | break;
326 | case "03":
327 | $res = Packet03Chat($packet);
328 | if(!in_array("chat",$hide) and $res != false){
329 | console($res);
330 | }
331 | break;
332 |
333 | case "04":
334 | $packet['time'] %= 24000;
335 | $ginfo["time"] = $packet['time'];
336 | if(!in_array("time",$hide)){
337 | console("[*] Time: ".((intval($packet['time']/1000+6) % 24)).':'.str_pad(intval(($packet['time']/1000-floor($packet['time']/1000))*60),2,"0",STR_PAD_LEFT).', '.(($packet['time'] > 23100 or $packet['time'] < 12900) ? "day":"night")." \r", false, false);
338 | }
339 | break;
340 | case "08":
341 | if($ginfo["health"] != $packet["health"] or $ginfo["food"] != $packet["food"]){
342 | console("[*] Health: ".$packet["health"].", Food: ". $packet["food"]);
343 | }
344 | $ginfo["health"] = $packet["health"];
345 | $ginfo["food"] = $protocol <= 14 ? $packet["health"]:$packet["food"];
346 | if($ginfo["health"]<=0){
347 | write_packet("09", $ginfo);
348 | $messages = array(
349 | "Nooo!!!",
350 | "Por que??",
351 | "Solo hice lo que me pedian!",
352 | "Noooouuu!",
353 | );
354 | Message($messages[count($messages)-1]);
355 | console("[-] Death and respawn");
356 | }
357 | break;
358 | case "0d":
359 | if(!in_array("position",$hide)){
360 | console("[+] Got position: (".$packet["x"].",".$packet["y"].",".$packet["z"].")");
361 | }
362 | /*if(!$position_packet and arg("spout", false) != false){
363 | write_packet("12", array(
364 | "eid" => -42,
365 | "animation" => 1,
366 | ));
367 | }*/
368 | if($moving == 0 or $moving >= 2){
369 | write_packet("0d",$packet);
370 | $position_packet = $packet;
371 | $moving = 0;
372 | }
373 |
374 |
375 | break;
376 | case "14":
377 | if(!in_array("nspawn",$hide)){
378 | console("[+] Player \"".$packet["name"]."\" (EID: ".$packet["eid"].") spawned at (".$packet["x"].",".$packet["y"].",".$packet["z"].")");
379 | }
380 | if(isset($permissions[$packet["name"]]) and $permissions[$packet["name"]] > 1){
381 | if($ginfo["owner"]["name"] == $packet["name"]){
382 | $ginfo["owner"]["eid"] = $packet["eid"];
383 | }
384 | privateMessage("Hola ".$packet["name"].". Eres ".($permissions[$packet["name"]] == 2 ? "moderador":"administrador")." de ".$username, $packet["name"]);
385 | }
386 | $players[$packet["name"]] = $packet["eid"];
387 | case "17":
388 | case "18":
389 | $entities[$packet["eid"]]["type"] = $packet["type"];
390 | $entities[$packet["eid"]]["x"] = $packet["x"];
391 | $entities[$packet["eid"]]["y"] = $packet["y"];
392 | $entities[$packet["eid"]]["z"] = $packet["z"];
393 | break;
394 | case "1d":
395 | unset($entities[$packet["eid"]]);
396 | if(in_array($packet["eid"], $players)){
397 | foreach($players as $name => $eid){
398 | if($eid == $packet["eid"]){
399 | unset($players[$name]);
400 | break;
401 | }
402 | }
403 | }
404 | break;
405 | case "1f":
406 | case "21":
407 | $entities[$packet["eid"]]["x"] += $packet["dX"];
408 | $entities[$packet["eid"]]["y"] += $packet["dY"];
409 | $entities[$packet["eid"]]["z"] += $packet["dZ"];
410 |
411 | break;
412 | case "22":
413 | $entities[$packet["eid"]]["x"] = $packet["x"];
414 | $entities[$packet["eid"]]["y"] = $packet["y"];
415 | $entities[$packet["eid"]]["z"] = $packet["z"];
416 | break;
417 | case "33":
418 | if($protocol <= 23){
419 | if($packet["xS"] == 15 and $packet["yS"] == 127 and $packet["zS"] == 15){
420 | if(THREADED){
421 | fork_chunk($packet, 33);
422 | }else{
423 | chunk_add($packet["chunk"], $packet["x"], $packet["z"]);
424 | chunk_clean($packet["x"], $packet["z"]);
425 | }
426 | }
427 | }
428 | break;
429 | case "35":
430 | if($protocol <= 23){
431 | if(THREADED){
432 | fork_chunk($packet, 35);
433 | }else{
434 | chunk_edit_block($packet["x"],$packet["y"],$packet["z"],$packet["type"]);
435 | }
436 | }
437 | break;
438 | case "46";
439 | if(!in_array("state",$hide)){
440 | switch($packet["reason"]){
441 | case 0:
442 | $m = "Invalid bed";
443 | break;
444 | case 1:
445 | $m = "Started raining";
446 | break;
447 | case 2:
448 | $m = "Ended raining";
449 | break;
450 | case 3:
451 | $m = "Gamemode changed: ".($packet["mode"]==0 ? "survival":"creative");
452 | break;
453 | case 4:
454 | $m = "Entered credits";
455 | break;
456 | }
457 | console("[*] ".$m);
458 | }
459 | break;
460 | case "67":
461 | if($packet["wid"] == 0){
462 | $ginfo["inventory"][$packet["slot"]] = $packet["sdata"][0];
463 | }
464 | break;
465 |
466 | case "68":
467 | if($packet["wid"] == 0){
468 | foreach($packet["sdata"] as $i => $slot){
469 | $ginfo["inventory"][$i] = $slot;
470 | }
471 | }
472 | break;
473 | case "82":
474 | if(!in_array("sign",$hide)){
475 | console("[*] Sign at (".$packet["x"].",".$packet["y"].",".$packet["z"].")".PHP_EOL.implode(PHP_EOL,$packet["text"]));
476 | }
477 | break;
478 | case "ff":
479 | console("[-] Kicked from server, \"".$packet["message"]."\"");
480 | socket_close($sock);
481 | die();
482 | break;
483 | }
484 | }else{
485 | buffer();
486 | }
487 |
488 | $do = false;
489 | /*if($next <= $time and $position_packet !== false){
490 | write_packet("0a", array(
491 | "ground" => true,
492 | ));
493 | $do = true;
494 | }*/
495 |
496 | if($next <= $time and $time%32==0 and intval(arg("dynmap", false)) > 0){
497 | foreach(DynMapCoords() as $player){
498 | if(!isset($players[$player["name"]]) or $players[$player["name"]] == md5($player["name"])){
499 | $players[$player["name"]] = md5($player["name"]);
500 | $entities[md5($player["name"])] = $player;
501 | }
502 | }
503 | }
504 | if($next <= $time){
505 | $input = file_get_contents("chat.input");file_put_contents("chat.input", "");
506 | foreach(explode("\n", $input) as $in){
507 | $in = trim($in);
508 | if($in == ""){
509 | continue;
510 | }
511 | Message($in);
512 | console("[+] INPUT: ".$in);
513 | }
514 | }
515 | if($ginfo["aura"] == true and $position_packet !== false){
516 | $att = false;
517 | foreach($entities as $eid => $ent){
518 | $xD = abs($position_packet["x"] - $ent["x"]);
519 | $yD = abs($position_packet["y"] - $ent["y"]);
520 | $zD = abs($position_packet["z"] - $ent["z"]);
521 | if(pow(pow($xD,2) + pow($yD,2) + pow($zD,2),1/3) <= 7){
522 | write_packet("07", array(
523 | "eid" => $ginfo["eid"],
524 | "target" => $eid,
525 | "left" => true,
526 | ));
527 | $att = true;
528 | }
529 | }
530 | if($att == true){
531 | write_packet("12", array(
532 | "eid" => $ginfo["eid"],
533 | "animation" => 1,
534 | ));
535 | }
536 | }
537 |
538 | if($next <= $time and $position_packet !== false){
539 | if($recorder["mode"] == "record"){
540 | $recorder["positions"][] = $entities[$ginfo["follow"]];
541 | }
542 | if($recorder["mode"] == "play"){
543 | if(isset($recorder["positions"][$recorder["name"]])){
544 | $recorder["positions"][$recorder["name"]]["stance"] = $recorder["positions"][$recorder["name"]]["y"] + 1.6;
545 | $recorder["positions"][$recorder["name"]]["ground"] = true;
546 | write_packet("0b", $recorder["positions"][$recorder["name"]]);
547 | ++$recorder["name"];
548 | }else{
549 | $recorder["mode"] = "";
550 | }
551 | }else{
552 | if($ginfo["follow"] > 0){
553 | $xD = abs($position_packet["x"] - $entities[$ginfo["follow"]]["x"]);
554 | $yD = abs($position_packet["y"] - $entities[$ginfo["follow"]]["y"]);
555 | $zD = abs($position_packet["z"] - $entities[$ginfo["follow"]]["z"]);
556 | if($ginfo["attack"] == true and pow(pow($xD,2) + pow($yD,2) + pow($zD,2),1/3) <= 7){
557 | write_packet("07", array(
558 | "eid" => $ginfo["eid"],
559 | "target" => $ginfo["follow"],
560 | "left" => true,
561 | ));
562 | write_packet("12", array(
563 | "eid" => $ginfo["eid"],
564 | "animation" => 1,
565 | ));
566 | }
567 | if(sqrt(pow($xD,2) + pow($zD,2)) <= 32 and sqrt(pow($xD,2) + pow($zD,2)) >= 2 and $moving <= 2){
568 | if($ginfo["jump"] > 0){
569 | $ginfo["jump"] = -1;
570 | }else{
571 | $ginfo["jump"] = 1;
572 | }
573 | $position_packet["x"] += ($position_packet["x"] - $entities[$ginfo["follow"]]["x"]>0 ? -0.25:0.25);
574 | if($ginfo["fly"] == false){
575 | $position_packet["y"] = $position_packet["y"] + $ginfo["jump"];
576 | }else{
577 | $position_packet["y"] += ($position_packet["y"] - $entities[$ginfo["follow"]]["y"]>0 ? -0.25:0.25);
578 | }
579 | $position_packet["stance"] = $position_packet["y"] + 1.6;
580 | $position_packet["yaw"] = -rad2deg(atan(($position_packet["x"] - $entities[$ginfo["follow"]]["x"])/($position_packet["z"] - $entities[$ginfo["follow"]]["z"])));
581 | $position_packet["pitch"] = mt_rand(-10,10);
582 | $position_packet["z"] += ($position_packet["z"] - $entities[$ginfo["follow"]]["z"]>0 ? -0.25:0.25);
583 | $position_packet["ground"] = ($ginfo["jump"] > 0 and $ginfo["fly"] == false) ? false:true;
584 | write_packet("0d", $position_packet);
585 | }else{
586 | $moving = 0;
587 | }
588 | /*if(sqrt(pow($xD,2) + pow($zD,2)) <= 4){
589 | write_packet("07", array(
590 | "eid" => $ginfo["eid"],
591 | "target" => $ginfo["owner"]["eid"],
592 | "left" => true,
593 | ));
594 | }*/
595 | }
596 | if($moving == 0){
597 | if(arg("crazyness","normal") == "mad"){
598 | if(mt_rand(0,100)<=80){
599 | if(mt_rand(0,100)<=40){
600 | $position_packet["x"] += mt_rand(-30,30)/210;
601 | $position_packet["z"] += mt_rand(-30,30)/210;
602 | }
603 | $position_packet["yaw"] = mt_rand(-360,360);
604 | $position_packet["pitch"] = mt_rand(-360,360);
605 | write_packet("0d", $position_packet);
606 | write_packet("12", array(
607 | "eid" => $ginfo["eid"],
608 | "animation" => 1,
609 | ));
610 | }else{
611 | write_packet("13", array(
612 | "eid" => $ginfo["eid"],
613 | "action" => ($crouch == false ? 1:2),
614 | ));
615 | $crouch = $crouch == true ? false:true;
616 | }
617 | }elseif(arg("crazyness","normal") == "exorcist"){
618 | $position_packet["yaw"] = 0;
619 | $position_packet["pitch"] += 6;
620 | $position_packet["pitch"] %= 360;
621 | write_packet("0d", $position_packet);
622 | }else{
623 | if(mt_rand(0,100)<=20){
624 | $position_packet["x"] += mt_rand(-30,30)/210;
625 | $position_packet["z"] += mt_rand(-30,30)/210;
626 | }
627 | $position_packet["yaw"] += mt_rand(-25,25);
628 | $position_packet["yaw"] %= 360;
629 | $position_packet["pitch"] += mt_rand(-10,10);
630 | $position_packet["pitch"] %= 55;
631 | write_packet("0d", $position_packet);
632 | }
633 | }
634 | }
635 | $do = true;
636 | }
637 | /*if($start+120<=$time){
638 | write_packet("ff", array("message" => "Bot auto-disconnect"));
639 | console("[-] Kicked from server, \"Bot auto-disconnect\"");
640 | socket_close($sock);
641 | die();
642 | }*/
643 | if($ginfo["timer"]["food"]<=$time and $position_packet !== false){
644 | $ginfo["timer"]["food"] = $time+4;
645 | $eat = false;
646 | for($i=36;$i<=44;++$i){
647 | $slot = $ginfo["inventory"][$i];
648 | if(isset($food[$slot[0]]) == true and ($ginfo["food"] + $food[$slot[0]]) <= 20){
649 | write_packet("10",array("slot" => $i-36));
650 | write_packet("0f", array("x" => -1, "y" => -1, "z" => -1, "direction" => -1, "slot" => array(-1)));
651 | $ginfo["food"] = 20;
652 | $eat = true;
653 | break;
654 | }elseif(!isset($food[$slot[0]]) and arg("only-food", false) == true){
655 | for($a=0;$a $i-36));
657 | write_packet("0e", array("status" => 4, "x" => 0, "y" => 0, "z" => 0, "face" => 0));
658 | }
659 | }
660 | }
661 | if($ginfo["timer"]["sayfood"]<=$time and $eat == false and $ginfo["food"] <= 12){
662 | $ginfo["timer"]["sayfood"] = $time+60;
663 | $messages = array(
664 | "Necesito comida!",
665 | "Comida!!!",
666 | "Me muero de hambre!",
667 | "No tengo comida!",
668 | );
669 | Message($messages[count($messages)-1]);
670 | }
671 | }
672 | if($do){
673 | $next = $time+0.05;
674 | }
675 | usleep(10);
676 | }
677 | socket_close($sock);
678 | if($restart == true){
679 | console("[+] Restarting...");
680 | $buffer = "";
681 | sleep(8);
682 | include("client.php");
683 | }
684 | die();
685 | ?>
686 |
--------------------------------------------------------------------------------
/command.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shoghicp/Minecraft-PHP-Client/58641b0674480be1e2c086f0998c088ae31284ac/command.php
--------------------------------------------------------------------------------
/dynmap.php:
--------------------------------------------------------------------------------
1 | 'up/world/{world}/', 'send' => 'up/sendmessage');
5 | $worlds = array(
6 | "mesp",
7 | /*"Celestia",
8 | "Reach",
9 | "Raccon",
10 | "Splash",
11 | "mesp2_the_end",
12 | "Laisla",
13 | "nether",*/
14 | );
15 | $players = array();
16 | foreach($worlds as $world){
17 | $update = json_decode(curl_get("http://mespduendedreams.com:".intval(arg("dynmap", false))."/".str_replace('{world}',$world,$config['get']).time()),true);
18 | foreach($update['players'] as $player){
19 | $players[$player['name']] = $player;
20 | }
21 | }
22 | return $players;
23 | }
24 |
25 | ?>
26 |
--------------------------------------------------------------------------------
/forking.php:
--------------------------------------------------------------------------------
1 | 4096 ? 4096:strlen($buffer);
45 | socket_write($IOsock, urlencode(substr($buffer,0,$len))."\n");
46 | $buffer = substr($buffer,$len);
47 | break;
48 | case "chunk":
49 | $last = time();
50 | $packet = unserialize(urldecode(trim(socket_read($IOsock,4096*16,PHP_NORMAL_READ))));
51 | chunk_add($packet["chunk"], $packet["x"], $packet["z"]);
52 | chunk_clean($packet["x"], $packet["z"]);
53 | socket_write($IOsock, urlencode(serialize($chunks))."\n");
54 | break;
55 | case "chunk2":
56 | $last = time();
57 | $packet = unserialize(urldecode(trim(socket_read($IOsock,4096*16,PHP_NORMAL_READ))));
58 | chunk_edit_block($packet["x"],$packet["y"],$packet["z"],$packet["type"]);
59 | socket_write($IOsock, urlencode(serialize($chunks))."\n");
60 | break;
61 | case "die":
62 | return;
63 | break;
64 | }
65 | }
66 |
67 | }
68 |
69 | function fork_chunk($packet, $pid){
70 | global $parent_sock, $chunks;
71 | socket_write($parent_sock,"chunk".($pid == 33 ? "":"2")."\n".urlencode(serialize($packet))."\n");
72 | $chunks = unserialize(urldecode(trim(socket_read($parent_sock,4096,PHP_NORMAL_READ))));
73 | }
74 |
75 | function fork_buffer(){
76 | global $parent_sock, $buffer, $connected;
77 |
78 | socket_write($parent_sock,"buffer\n");
79 | if(strlen($buffer) < 128 and $connected){
80 | socket_set_block($parent_sock);
81 | }else{
82 | socket_set_nonblock($parent_sock);
83 | }
84 | return urldecode(trim(socket_read($parent_sock,4096,PHP_NORMAL_READ)));
85 | }
86 |
87 | ?>
88 |
--------------------------------------------------------------------------------
/functions.php:
--------------------------------------------------------------------------------
1 | 127 ? -(256-$b+1):$b;
24 | }
25 | return $b;
26 | }
27 | function write_byte($value, $signed = true){
28 | if($signed == true){
29 | $value = ($value <= -1) ? (256+$value):$value;
30 | }
31 | return pack("c", $value);
32 | }
33 |
34 | function read_short($str){
35 | list(,$unpacked) = unpack("n", substr($str, 0, 2));
36 | if($unpacked >= pow(2, 15)) $unpacked -= pow(2, 16); // Convert unsigned short to signed short.
37 | return $unpacked;
38 | }
39 | function write_short($value){
40 | if($value < 0){
41 | $value += pow(2, 16);
42 | }
43 | return pack("n", $value);
44 | }
45 |
46 | function read_int($str){
47 | list(,$unpacked) = unpack("N", substr($str, 0, 4));
48 | if($unpacked >= pow(2, 31)) $unpacked -= pow(2, 32); // Convert unsigned int to signed int
49 | return $unpacked;
50 | }
51 | function write_int($value){
52 | if($value < 0){
53 | $value += pow(2, 32);
54 | }
55 | return pack("N", $value);
56 | }
57 |
58 |
59 | function read_float($str){
60 | list(,$value) = (pack('d', 1) == "\77\360\0\0\0\0\0\0")?unpack('f', substr($str,0, 4)):unpack('f', strrev(substr($str,0, 4)));
61 | return $value;
62 | }
63 | function write_float($value){
64 | return (pack('d', 1) == "\77\360\0\0\0\0\0\0")?pack('f', $value):strrev(pack('f', $value));
65 | }
66 |
67 | function read_double($str, $signed = true){
68 | list(,$value) = (pack('d', 1) == "\77\360\0\0\0\0\0\0")?unpack('d', substr($str,0, 8)):unpack('d', strrev(substr($str,0, 8)));
69 | return $value;
70 | }
71 | function write_double($value){
72 | return (pack('d', 1) == "\77\360\0\0\0\0\0\0")?pack('d', $value):strrev(pack('d', $value));
73 | }
74 |
75 | function read_long($str, $signed = true){
76 | $n = "";
77 | for($i=0;$i<8;++$i){
78 | $n .= bin2hex($str{$i});
79 | }
80 | $n = hexdec($n);
81 | if($signed == true){
82 | $n = $n>9223372036854775807 ? -(18446744073709551614-$n+1):$n;
83 | }
84 | return sprintf("%.0F", $n);
85 | }
86 | function write_long($value){
87 | return (pack('d', 1) == "\77\360\0\0\0\0\0\0")?pack('d', $value):strrev(pack('d', $value));
88 | }
89 |
90 | function convert($format, $str){
91 | $ret = unpack($format, $str);
92 | if(is_array($ret)){
93 | $ret = implode($ret);
94 | }
95 | return $ret;
96 | }
97 |
98 | function arg($name, $default){
99 | global $arguments, $argv;
100 | if(!isset($arguments)){
101 | $arguments = arguments($argv);
102 | }
103 |
104 | if(isset($arguments["commands"][$name])){
105 | return $arguments["commands"][$name];
106 | }else{
107 | return $default;
108 | }
109 | }
110 |
111 | function arguments ( $args ){
112 | if(!is_array($args)){
113 | $args = array();
114 | }
115 | array_shift( $args );
116 | $args = join( $args, ' ' );
117 |
118 | preg_match_all('/ (--\w+ (?:[= ] [^-]+ [^\s-] )? ) | (-\w+) | (\w+) /x', $args, $match );
119 | $args = array_shift( $match );
120 |
121 | /*
122 | Array
123 | (
124 | [0] => asdf
125 | [1] => asdf
126 | [2] => --help
127 | [3] => --dest=/var/
128 | [4] => -asd
129 | [5] => -h
130 | [6] => --option mew arf moo
131 | [7] => -z
132 | )
133 | */
134 |
135 | $ret = array(
136 | 'input' => array(),
137 | 'commands' => array(),
138 | 'flags' => array()
139 | );
140 |
141 | foreach ( $args as $arg ) {
142 |
143 | // Is it a command? (prefixed with --)
144 | if ( substr( $arg, 0, 2 ) === '--' ) {
145 |
146 | $value = preg_split( '/[= ]/', $arg, 2 );
147 | $com = substr( array_shift($value), 2 );
148 | $value = join($value);
149 |
150 | $ret['commands'][$com] = !empty($value) ? $value : true;
151 | continue;
152 |
153 | }
154 |
155 | // Is it a flag? (prefixed with -)
156 | if ( substr( $arg, 0, 1 ) === '-' ) {
157 | $ret['flags'][] = substr( $arg, 1 );
158 | continue;
159 | }
160 |
161 | $ret['input'][] = $arg;
162 | continue;
163 |
164 | }
165 |
166 | return $ret;
167 | }
168 |
169 | function min_struct($array){
170 | $offset = 0;
171 | foreach($array as $type){
172 | switch($type){
173 | case "float":
174 | case "int":
175 | $offset += 4;
176 | break;
177 | case "double":
178 | case "long":
179 | $offset += 8;
180 | break;
181 | case "bool":
182 | case "boolean":
183 | case "byte":
184 | $offset += 1;
185 | $offset += 1;
186 | break;
187 | case "short":
188 | $offset += 2;
189 | break;
190 | }
191 | }
192 | return $offset;
193 | }
194 |
195 | function wait_buffer($to){
196 | global $buffer, $connected;
197 | while(!isset($buffer{$to}) and $connected){
198 | buffer(); //FIXES SLOW-CONNECTION ERROR
199 | }
200 | }
201 |
202 | function parse_packet(){
203 | global $buffer, $pstruct, $path, $connected;
204 | $pid = bin2hex($buffer{0});
205 | $data = array();
206 | $pdata = array();
207 | $raw = array();
208 | $offset = 1;
209 |
210 | if(!isset($pstruct[$pid])){
211 | write_packet("ff", array("message" => "Bad packet id ".$pid));
212 | if(arg("log", false) === true or (arg("log", false) != false and arg("log", false) == "packets")){
213 | $p = "==".time()."==> ERROR Bad packet id $pid :".PHP_EOL;
214 | $p .= hexdump(substr($buffer,0,512), false, false, true);
215 | $p .= PHP_EOL . "--------------- (512 byte extract) ----------" .PHP_EOL .PHP_EOL;
216 | file_put_contents($path."packets.log", $p, FILE_APPEND);
217 | }
218 | return array("pid" => "ff", "message" => "Bad packet id ".$pid);
219 | }
220 | wait_buffer(min_struct($pstruct[$pid]));
221 | $field = 0;
222 | $continue = true;
223 | foreach($pstruct[$pid] as $type){
224 | if($continue == false){
225 | break;
226 | }
227 | switch($type){
228 | case "int":
229 | $raw[] = $r = substr($buffer,$offset, 4);
230 | $pdata[] = read_int($r);
231 | if($field == 5 and $pid == "17" and $pdata[count($pdata)-1] == 0){
232 | $continue = false;
233 | }
234 | $offset += 4;
235 | break;
236 | case "string":
237 | $len = read_short(substr($buffer,$offset,2));
238 | $offset += 2;
239 | wait_buffer($offset+$len*2-1);
240 | $raw[] = $r = substr($buffer,$offset,$len * 2);
241 | $pdata[] = utf16_decode($r);
242 | $offset += $len * 2;
243 | break;
244 | case "long":
245 | $raw[] = $r = substr($buffer,$offset, 8);
246 | $pdata[] = read_long($r);
247 | $offset += 8;
248 | break;
249 | case "byte":
250 | $raw[] = $r = $buffer{$offset};
251 | $pdata[] = read_byte($r);
252 | $offset += 1;
253 | break;
254 | case "ubyte":
255 | $raw[] = $r = $buffer{$offset};
256 | $pdata[] = read_byte($r, false);
257 | $offset += 1;
258 | break;
259 | case "float":
260 | $raw[] = $r = substr($buffer,$offset, 4);
261 | $pdata[] = convert("f", $r);
262 | $offset += 4;
263 | break;
264 | case "double":
265 | $raw[] = $r = substr($buffer,$offset, 8);
266 | $pdata[] = read_double($r);
267 | $offset += 8;
268 | break;
269 | case "short":
270 | $raw[] = $r = substr($buffer,$offset,2);
271 | $pdata[] = read_short($r);
272 | $offset += 2;
273 | break;
274 | case "bool":
275 | case "boolean":
276 | $raw[] = $r = $buffer{$offset};
277 | $pdata[] = read_byte($r, false) == 0 ? false:true;
278 | $offset += 1;
279 | break;
280 | case "explosionRecord":
281 | $r = array();
282 | for($i=$pdata[4];$i>0;--$i){
283 | $r[] = array(read_byte($buffer{$offset}),read_byte($buffer{$offset+1}),read_byte($buffer{$offset+2}));
284 | $offset += 3;
285 | }
286 | $pdata[] = $r;
287 | break;
288 | case "byteArray":
289 | $len = $pdata[count($pdata)-1];
290 | $pdata[] = substr($buffer,$offset,$len);
291 | $offset += $len;
292 | break;
293 | case "chunkArray":
294 | $len = max(0,$pdata[6]);
295 | $first = false;
296 | $r = "";
297 | while(strlen($r)<$len){ //Sometimes low-bandwidth servers made client a crash
298 | if($first == true){
299 | buffer();
300 | global $buffer;
301 | }
302 | $first = true;
303 | $r = substr($buffer, $offset, $len);
304 | }
305 | $pdata[] = $r;
306 | $offset += $len;
307 | break;
308 | case "multiblockArray":
309 | $count = $pdata[count($pdata)-1];
310 | for($i=0;$i<$count;++$i){
311 | //read_short(substr($buffer,$offset,2));
312 | $offset += 2;
313 | }
314 | for($i=0;$i<$count;++$i){
315 | //read_byte($buffer{$offset});
316 | $offset += 1;
317 | }
318 | for($i=0;$i<$count;++$i){
319 | //read_byte($buffer{$offset});
320 | $offset += 1;
321 | }
322 | $pdata[] = "";
323 | break;
324 | case "newChunkArray":
325 | $len = max(0,$pdata[5]);
326 | $first = false;
327 | $r = "";
328 | while(strlen($r)<$len){ //Sometimes low-bandwidth servers made client a crash
329 | if($first == true){
330 | buffer();
331 | global $buffer;
332 | }
333 | $first = true;
334 | $r = substr($buffer, $offset, $len);
335 | }
336 | $pdata[] = $r;
337 | $offset += $len;
338 | break;
339 | case "newMultiblockArray":
340 | $count = $pdata[3];
341 | $pdata[] = substr($buffer, $offset, $count);
342 | $offset += $count;
343 | break;
344 | case "slotArray":
345 | case "slotData":
346 | $scount = $type == "slotData" ? 1:$pdata[count($pdata)-1];
347 | $d = array();
348 | for($i=0;$i<$scount;++$i){
349 | $id = read_short(substr($buffer,$offset,2));
350 | $offset += 2;
351 | if($id != -1){
352 | $count = read_byte($buffer{$offset});
353 | $offset += 1;
354 | $meta = read_short(substr($buffer,$offset,2));
355 | $offset += 2;
356 | $d[$i] = array($id,$count,$meta);
357 | $enchantable_items = array(
358 | 0x103, #Flint and steel
359 | 0x105, #Bow
360 | 0x15A, #Fishing rod
361 | 0x167, #Shears
362 |
363 | #TOOLS
364 | #sword, shovel, pickaxe, axe, hoe
365 | 0x10C, 0x10D, 0x10E, 0x10F, 0x122, #WOOD
366 | 0x110, 0x111, 0x112, 0x113, 0x123, #STONE
367 | 0x10B, 0x100, 0x101, 0x102, 0x124, #IRON
368 | 0x114, 0x115, 0x116, 0x117, 0x125, #DIAMOND
369 | 0x11B, 0x11C, 0x11D, 0x11E, 0x126, #GOLD
370 |
371 | #ARMOUR
372 | #helmet, chestplate, leggings, boots
373 | 0x12A, 0x12B, 0x12C, 0x12D, #LEATHER
374 | 0x12E, 0x12F, 0x130, 0x131, #CHAIN
375 | 0x132, 0x133, 0x134, 0x135, #IRON
376 | 0x136, 0x137, 0x138, 0x139, #DIAMOND
377 | 0x13A, 0x13B, 0x13C, 0x13D, #GOLD
378 | );
379 | if(in_array($id, $enchantable_items)){
380 | $len = read_short(substr($buffer,$offset,2));
381 | $offset += 2;
382 | if($len > -1){
383 | $arr = substr($buffer, $offset, $len);
384 | $offset += $len;
385 | }
386 | }
387 | }
388 | }
389 | $pdata[] = $d;
390 | break;
391 | case "entityMetadata":
392 | $m = array();
393 | $b = read_byte($buffer{$offset}, false);
394 | while($b != 127){
395 | $offset += 1;
396 | $bottom = $b & 0x1F;
397 | $type = $b >> 5;
398 | switch($type){
399 | case 0:
400 | $r = read_byte($buffer{$offset});
401 | $offset += 1;
402 | break;
403 | case 1:
404 | $r = read_short(substr($buffer,$offset,2));
405 | $offset += 2;
406 | break;
407 | case 2:
408 | $r = read_int(substr($buffer,$offset, 4));
409 | $offset += 4;
410 | break;
411 | case 3:
412 | $r = convert("f", substr($buffer,$offset, 4));
413 | $offset += 4;
414 | break;
415 | case 4:
416 | $len = read_short(substr($buffer,$offset,2));
417 | $offset += 2;
418 | $r = no_endian(substr($buffer,$offset,$len * 2));
419 | $offset += $len * 2;
420 | break;
421 | case 5:
422 | $r = array("id" => read_short(substr($buffer,$offset,2)), "count" => read_byte($buffer{$offset+2}), "damage" => read_short($buffer{$offset+3}.$buffer{$offset+4}));
423 | $offset += 5;
424 | break;
425 |
426 | case 6:
427 | $r = array();
428 | for($i=0;$i<3;++$i){
429 | $r[] = convert("I", substr($buffer,$offset, 4));
430 | $offset += 4;
431 | }
432 | break;
433 |
434 | }
435 | $m[] = $r;
436 | $b = read_byte($buffer{$offset}, false);
437 | }
438 | $offset += 1;
439 | $pdata[] = $m;
440 | break;
441 |
442 |
443 | }
444 | ++$field;
445 | }
446 |
447 |
448 | if(arg("log", false) === true or (arg("log", false) != false and arg("log", false) == "packets")){
449 | $p = "==".time()."==> RECEIVED Packet $pid, lenght $offset :".PHP_EOL;
450 | $p .= hexdump(substr($buffer,0,$offset), false, false, true);
451 | $p .= PHP_EOL .PHP_EOL;
452 | file_put_contents($path."packets.log", $p, FILE_APPEND);
453 | }elseif(arg("log", false) != false and arg("log", false) == "raw"){
454 | file_put_contents($path."raw_recv.log", substr($buffer,0,$offset), FILE_APPEND);
455 | }
456 |
457 | $buffer = substr($buffer, $offset); // Clear packet
458 |
459 | switch($pid){
460 | case "00":
461 | $data["ka_id"] = $pdata[0];
462 | break;
463 | case "01": //Login
464 | $data["eid"] = $pdata[0];
465 | $data["seed"] = $pdata[2];
466 | if($protocol >= 23){
467 | $data["level_type"] = $pdata[3];
468 | $data["mode"] = $pdata[4];
469 | $data["dimension"] = $pdata[5];
470 | $data["difficulty"] = $pdata[6];
471 | $data["height"] = $pdata[7];
472 | $data["max_players"] = $pdata[8];
473 | }else{
474 | $data["mode"] = $pdata[3];
475 | $data["dimension"] = $pdata[4];
476 | $data["difficulty"] = $pdata[5];
477 | $data["height"] = $pdata[6];
478 | $data["max_players"] = $pdata[7];
479 | }
480 | break;
481 | case "02": //Handshake
482 | $data["server_id"] = $pdata[0];
483 | break;
484 | case "03": //Chat
485 | $data["message"] = $pdata[0];
486 | break;
487 | case "04": //Time update
488 | $data["time"] = $pdata[0];//unpack("L*",substr($buffer,0,8));
489 | break;
490 | case "06": //Spawn pos
491 | $data["x"] = $pdata[0];
492 | $data["y"] = $pdata[1];
493 | $data["z"] = $pdata[2];
494 | break;
495 | case "08":
496 | $data["health"] = $pdata[0];
497 | $data["food"] = $pdata[1];
498 | $data["saturation"] = $pdata[1];
499 | break;
500 | case "0d":
501 | $data["x"] = $pdata[0];
502 | $data["stance"] = $pdata[1];
503 | $data["y"] = $pdata[2];
504 | $data["z"] = $pdata[3];
505 | $data["yaw"] = $pdata[4];
506 | $data["pitch"] = $pdata[5];
507 | $data["ground"] = $pdata[6];
508 | break;
509 | case "14": //named entity spawn
510 | $data["eid"] = $pdata[0];
511 | $data["name"] = $pdata[1];
512 | $data["type"] = 100;
513 | $data["x"] = $pdata[2] / 32;
514 | $data["y"] = $pdata[3] / 32;
515 | $data["z"] = $pdata[4] / 32;
516 | break;
517 | case "17":
518 | $data["eid"] = $pdata[0];
519 | $data["type"] = $pdata[1];
520 | $data["x"] = $pdata[2] / 32;
521 | $data["y"] = $pdata[3] / 32;
522 | $data["z"] = $pdata[4] / 32;
523 | break;
524 | case "18":
525 | $data["eid"] = $pdata[0];
526 | $data["type"] = $pdata[1];
527 | $data["x"] = $pdata[2] / 32;
528 | $data["y"] = $pdata[3] / 32;
529 | $data["z"] = $pdata[4] / 32;
530 | break;
531 | case "1d":
532 | $data["eid"] = $pdata[0];
533 | break;
534 | case "1f":
535 | $data["eid"] = $pdata[0];
536 | $data["dX"] = $pdata[1] / 32;
537 | $data["dY"] = $pdata[2] / 32;
538 | $data["dZ"] = $pdata[3] / 32;
539 | break;
540 | case "20":
541 | $data["eid"] = $pdata[0];
542 | $data["yaw"] = $pdata[1];
543 | $data["pitch"] = $pdata[2];
544 | break;
545 | case "21":
546 | $data["eid"] = $pdata[0];
547 | $data["dX"] = $pdata[1] / 32;
548 | $data["dY"] = $pdata[2] / 32;
549 | $data["dZ"] = $pdata[3] / 32;
550 | $data["yaw"] = $pdata[4];
551 | $data["pitch"] = $pdata[5];
552 | break;
553 | case "22":
554 | $data["eid"] = $pdata[0];
555 | $data["x"] = $pdata[1] / 32;
556 | $data["y"] = $pdata[2] / 32;
557 | $data["z"] = $pdata[3] / 32;
558 | $data["yaw"] = $pdata[4];
559 | $data["pitch"] = $pdata[5];
560 | break;
561 | case "33":
562 | if($protocol <= 23){
563 | $data["x"] = $pdata[0];
564 | $data["y"] = $pdata[1];
565 | $data["z"] = $pdata[2];
566 | $data["xS"] = $pdata[3];
567 | $data["yS"] = $pdata[4];
568 | $data["zS"] = $pdata[5];
569 | $data["lenght"] = $pdata[6];
570 | $data["chunk"] = $pdata[7];
571 | }else{
572 | $data["x"] = $pdata[0];
573 | $data["z"] = $pdata[1];
574 | $data["continuous"] = $pdata[2];
575 | $data["pbm"] = $pdata[3];
576 | $data["abm"] = $pdata[4];
577 | $data["lenght"] = $pdata[5];
578 | $data["chunk"] = $pdata[7];
579 | }
580 | break;
581 | case "34":
582 | if($protocol <= 23){
583 | $data["x"] = $pdata[0];
584 | $data["z"] = $pdata[1];
585 | $data["size"] = $pdata[2];
586 | $data["carray"] = $pdata[3];
587 | $data["tarray"] = $pdata[4];
588 | $data["marray"] = $pdata[5];
589 | }else{
590 | $data["x"] = $pdata[0];
591 | $data["z"] = $pdata[1];
592 | $data["count"] = $pdata[2];
593 | $data["size"] = $pdata[3];
594 | /*$data["carray"] = $pdata[4];
595 | $data["tarray"] = $pdata[5];
596 | $data["marray"] = $pdata[6];*/
597 | }
598 | break;
599 | case "35":
600 | $data["x"] = $pdata[0];
601 | $data["y"] = $pdata[1];
602 | $data["z"] = $pdata[2];
603 | $data["type"] = $pdata[3];
604 | $data["meta"] = $pdata[4];
605 | break;
606 | case "46":
607 | $data["reason"] = $pdata[0];
608 | if($protocol <= 14){
609 | $data["mode"] = $pdata[1];
610 | }
611 | break;
612 | case "67":
613 | $data["wid"] = $pdata[0];
614 | $data["slot"] = $pdata[1];
615 | $data["sdata"] = $pdata[2];
616 | break;
617 | case "68":
618 | $data["wid"] = $pdata[0];
619 | $data["count"] = $pdata[1];
620 | $data["sdata"] = $pdata[2];
621 | break;
622 | case "82":
623 | $data["x"] = $pdata[0];
624 | $data["y"] = $pdata[1];
625 | $data["z"] = $pdata[2];
626 | $data["text"] = array($pdata[3], $pdata[4], $pdata[5], $pdata[6]);
627 | break;
628 | case "fa":
629 | $data["channel"] = $pdata[0];
630 | $data["lenght"] = $pdata[1];
631 | $data["data"] = $pdata[2];
632 | break;
633 | case "ff":
634 | $data["message"] = $pdata[0];
635 | break;
636 | }
637 | $data["pid"] = $pid;
638 | $data["raw"] = $raw;
639 | return $data;
640 | }
641 |
642 | function write_packet($pid,$data = array(), $raw = false){
643 | global $sock, $path, $protocol, $connected;
644 | if($raw == false){
645 | switch($pid){
646 | case "00":
647 | $packet = "\x00".
648 | ($protocol <= 14 ? "":$data["raw"][0]);
649 | break;
650 | case "01": //Login
651 | $packet = "\x01".
652 | write_int($data["version"]).
653 | write_string($data["username"]);
654 | if($protocol<=23){
655 | $packet .= write_long(0);
656 | }
657 | if($protocol >= 23){
658 | $packet .= write_string("");
659 | }
660 | if($protocol > 14){
661 | $packet .= write_int(0);
662 | if($protocol >= 23){
663 | $packet .= write_int(0);
664 | }else{
665 | $packet .= write_byte(0);
666 | }
667 | $packet .= write_byte(0).
668 | write_byte(0);
669 | }
670 | $packet .= write_byte(0);
671 | break;
672 |
673 | case "02": //Handshake
674 | $packet = "\x02";
675 | if($protocol > 23 ){
676 | $packet .= write_string($data["username"].";".$data["server"]);
677 | }else{
678 | $packet .= write_string($data["username"]);
679 | }
680 | break;
681 | case "03":
682 | $packet = "\x03".
683 | write_string($data["message"]);
684 | break;
685 | case "07":
686 | $packet = "\x07".
687 | write_int($data["eid"]).
688 | write_int($data["target"]).
689 | ($data["left"] == true ? "\x01":"\x00");
690 | break;
691 | case "09":
692 | $packet = "\x09".
693 | write_byte($data["dimension"]).
694 | write_byte($data["difficulty"]).
695 | write_byte($data["mode"]).
696 | write_short($data["height"]).
697 | write_long($data["seed"]).
698 | ($protocol >= 23 ? write_string($data["level_type"]):"");
699 | break;
700 | case "0a":
701 | $packet = "\x0a".
702 | ($data["ground"] == true ? "\x01":"\x00");
703 | break;
704 | case "0b":
705 | $packet = "\x0b".
706 | write_double($data["x"]).
707 | write_double($data["y"]).
708 | write_double($data["stance"]).
709 | write_double($data["z"]).
710 | ($data["ground"] == true ? "\x01":"\x00");
711 | break;
712 | case "0c":
713 | $packet = "\x0c".
714 | write_float($data["yaw"]).
715 | write_float($data["pitch"]).
716 | ($data["ground"] == true ? "\x01":"\x00");
717 | break;
718 | case "0d":
719 | $packet = "\x0d".
720 | write_double($data["x"]).
721 | write_double($data["y"]).
722 | write_double($data["stance"]).
723 | write_double($data["z"]).
724 | write_float($data["yaw"]).
725 | write_float($data["pitch"]).
726 | ($data["ground"] == true ? "\x01":"\x00");
727 | break;
728 | case "0e":
729 | $packet = "\x0e".
730 | write_byte($data["status"]).
731 | write_int($data["x"]).
732 | write_byte($data["y"]).
733 | write_int($data["z"]).
734 | write_byte($data["face"]);
735 | break;
736 | case "0f":
737 | $packet = "\x0f".
738 | write_int($data["x"]).
739 | write_byte($data["y"]).
740 | write_int($data["z"]).
741 | write_byte($data["direction"]).
742 |
743 | write_short($data["slot"][0]);
744 | if($data["slot"][0]!=-1){
745 | $packet .= write_byte($data["slot"][1]).
746 | write_short($data["slot"][2]);
747 | }
748 | break;
749 | case "10":
750 | $packet = "\x10".
751 | write_short($data["slot"]);
752 | break;
753 | case "12":
754 | $packet = "\x12".
755 | write_int($data["eid"]).
756 | write_byte($data["animation"]);
757 | break;
758 | case "13":
759 | $packet = "\x13".
760 | write_int($data["eid"]).
761 | write_byte($data["action"]);
762 | break;
763 | case "1b":
764 | /*$packet = "\x1b".
765 | write_float($data["x"]).
766 | write_float($data["y"]).
767 | write_float($data["stance"]).
768 | write_float($data["z"]).
769 | write_float($data["yaw"]).
770 | write_float($data["pitch"]).
771 | ($data["ground"] == true ? "\x01":"\x00"); */
772 | break;
773 | case "27":
774 | $packet = "\x27".
775 | write_int($data["eid"]).
776 | write_int($data["vid"]);
777 | break;
778 | case "fe":
779 | $packet = "\xfe";
780 | break;
781 | case "ff":
782 | $packet = "\xff".
783 | write_string($data["message"]);
784 | break;
785 | }
786 | }else{
787 | $packet = pack("H*" , $pid);
788 | foreach($data["raw"] as $field){
789 | $packet .= $field;
790 | }
791 | }
792 | if(!$connected){
793 | return false;
794 | }
795 |
796 | if(arg("log", false) === true and (arg("log", false) != false and arg("log", false) == "packets")){
797 | $len = strlen($packet);
798 | $p = "==".time()."==> SENT Packet $pid, lenght $len:".PHP_EOL;
799 | $p .= hexdump($packet, false, false, true);
800 | $p .= PHP_EOL .PHP_EOL;
801 | file_put_contents($path."packets.log", $p, FILE_APPEND);
802 | }elseif(arg("log", false) != false and arg("log", false) == "raw"){
803 | file_put_contents($path."raw_sent.log", $packet, FILE_APPEND);
804 | }
805 |
806 | return @socket_write($sock, $packet);
807 | }
808 |
809 | function endian($str){
810 | $new = '';
811 | $len = strlen($str);
812 | for($i=0;$i<$len;++$i){
813 | $new .= "\00".$str{$i};
814 | }
815 | return $new;
816 | }
817 | function no_endian($str){
818 | $len = strlen($str);
819 | $f="";
820 | for($i=0;$i<$len;++$i){
821 | if($i%2==1 and $i > 0){
822 | $f .= $str{$i};
823 | }
824 | }
825 | return $f;
826 | }
827 |
828 | function curl_get($page){
829 | $ch = curl_init ($page);
830 | curl_setopt ($ch, CURLOPT_HTTPHEADER, array('User-Agent: Minecraft PHP Client'));
831 | curl_setopt ($ch, CURLOPT_AUTOREFERER, true);
832 | curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
833 | curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 2);
834 | curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
835 | curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
836 | return curl_exec ($ch);
837 | }
838 | function curl_post($page, $args){
839 | $ch = curl_init($page);
840 | curl_setopt ($ch, CURLOPT_POST, 1);
841 | curl_setopt ($ch, CURLOPT_POSTFIELDS, $args);
842 | curl_setopt ($ch, CURLOPT_AUTOREFERER, true);
843 | curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
844 | curl_setopt ($ch, CURLOPT_HTTPHEADER, array('User-Agent: Minecraft PHP Client'));
845 | curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
846 | return curl_exec($ch);
847 | }
848 |
849 | function buffer(){
850 | global $buffer, $sock, $connected;
851 | if(!isset($buffer)){
852 | $buffer = "";
853 | }
854 | $len = strlen($buffer);
855 | if(THREADED and !CHILD){
856 | if($len < (MAX_BUFFER_BYTES / 8)){
857 | $buffer .= fork_buffer();
858 | }
859 | return;
860 | }
861 |
862 | if($len < (MAX_BUFFER_BYTES / 8)){
863 | if(strlen($buffer) < 128 and $connected){
864 | socket_set_block($sock);
865 | }else{
866 | socket_set_nonblock($sock);
867 | }
868 | $read = @socket_read($sock,MAX_BUFFER_BYTES-$len, PHP_BINARY_READ);
869 | if($read != false and $read != ""){
870 | $buffer .= $read;
871 | }elseif(socket_last_error($sock) == 104){
872 | $connected = false;
873 | }
874 | }
875 |
876 | }
877 |
878 |
879 | /**
880 | * View any string as a hexdump.
881 | *
882 | * This is most commonly used to view binary data from streams
883 | * or sockets while debugging, but can be used to view any string
884 | * with non-viewable characters.
885 | *
886 | * @version 1.3.2
887 | * @author Aidan Lister
888 | * @author Peter Waller
889 | * @link http://aidanlister.com/2004/04/viewing-binary-data-as-a-hexdump-in-php/
890 | * @param string $data The string to be dumped
891 | * @param bool $htmloutput Set to false for non-HTML output
892 | * @param bool $uppercase Set to true for uppercase hex
893 | * @param bool $return Set to true to return the dump
894 | */
895 | function hexdump ($data, $htmloutput = true, $uppercase = false, $return = false)
896 | {
897 | // Init
898 | $hexi = '';
899 | $ascii = '';
900 | $dump = ($htmloutput === true) ? '' : '';
901 | $offset = 0;
902 | $len = strlen($data);
903 |
904 | // Upper or lower case hexadecimal
905 | $x = ($uppercase === false) ? 'x' : 'X';
906 |
907 | // Iterate string
908 | for ($i = $j = 0; $i < $len; $i++)
909 | {
910 | // Convert to hexidecimal
911 | $hexi .= sprintf("%02$x ", ord($data[$i]));
912 |
913 | // Replace non-viewable bytes with '.'
914 | if (ord($data[$i]) >= 32) {
915 | $ascii .= ($htmloutput === true) ?
916 | htmlentities($data[$i]) :
917 | $data[$i];
918 | } else {
919 | $ascii .= '.';
920 | }
921 |
922 | // Add extra column spacing
923 | if ($j === 7) {
924 | $hexi .= ' ';
925 | $ascii .= ' ';
926 | }
927 |
928 | // Add row
929 | if (++$j === 16 || $i === $len - 1) {
930 | // Join the hexi / ascii output
931 | $dump .= sprintf("%04$x %-49s %s", $offset, $hexi, $ascii);
932 |
933 | // Reset vars
934 | $hexi = $ascii = '';
935 | $offset += 16;
936 | $j = 0;
937 |
938 | // Add newline
939 | if ($i !== $len - 1) {
940 | $dump .= "\n";
941 | }
942 | }
943 | }
944 |
945 | // Finish dump
946 | $dump .= $htmloutput === true ?
947 | '
' :
948 | '';
949 | $dump .= "\n";
950 |
951 | $dump = preg_replace("/[^[:print:]\\r\\n]/", ".", $dump);
952 |
953 | // Output method
954 | if ($return === false) {
955 | echo $dump;
956 | } else {
957 | return $dump;
958 | }
959 | }
960 |
961 | function utf16_decode( $str ) {
962 | if( strlen($str) < 2 ) return $str;
963 | $bom_be = true;
964 | $c0 = ord($str{0});
965 | $c1 = ord($str{1});
966 | if( $c0 == 0xfe && $c1 == 0xff ) { $str = substr($str,2); }
967 | elseif( $c0 == 0xff && $c1 == 0xfe ) { $str = substr($str,2); $bom_be = false; }
968 | $len = strlen($str);
969 | $newstr = '';
970 | for($i=0;$i<$len;$i+=2) {
971 | if( $bom_be ) { $val = ord($str{$i}) << 4; $val += ord($str{$i+1}); }
972 | else { $val = ord($str{$i+1}) << 4; $val += ord($str{$i}); }
973 | $newstr .= ($val == 0x228) ? "\n" : chr($val);
974 | }
975 | return $newstr;
976 | }
977 | ?>
978 |
--------------------------------------------------------------------------------
/materials.php:
--------------------------------------------------------------------------------
1 | "Air",
5 | 1 => "Stone",
6 | 2 => "Grass",
7 | 3 => "Dirt",
8 | 4 => "Cobblestone",
9 | 5 => "Plank",
10 | 6 => "Sapling",
11 | 7 => "Bedrock",
12 | 8 => "Water",
13 | 9 => "Water",
14 | 10 => "Lava",
15 | 11 => "Lava",
16 | 12 => "Sand",
17 | 13 => "Gravel",
18 | 14 => "Gold Ore",
19 | 15 => "Iron Ore",
20 | 16 => "Coal Ore",
21 | 17 => "Wood",
22 | 18 => "Leave",
23 | 19 => "Sponge",
24 | 20 => "Glass",
25 | 21 => "Lapis Lazuli Ore",
26 | 22 => "Lapis Lazuli Block",
27 | 23 => "Dispenser",
28 | 24 => "Sandstone",
29 | 25 => "Note Block",
30 |
31 | 35 => "Wool",
32 |
33 | 43 => "Double Slab",
34 | 44 => "Slab",
35 | 45 => "Brick",
36 | 46 => "TNT",
37 |
38 | 49 => "Obsidian",
39 |
40 | 53 => "Wood Stair",
41 | 54 => "Chest",
42 |
43 | 61 => "Furnace",
44 |
45 | 67 => "Cobblestone Stair",
46 |
47 | 79 => "Ice",
48 |
49 | 89 => "Glowstone",
50 |
51 | );
52 |
53 | $food = array(
54 | 282 => 8, //Stew
55 | 364 => 8, //Steak
56 | 320 => 8, //Porkchop
57 | 366 => 6, //Chicken
58 | 297 => 5, //Bread
59 | 350 => 5, //Fish
60 | 260 => 4, //R Apple
61 | 322 => 4, //G Apple
62 | 363 => 3, //Raw Beef
63 | 319 => 3, //Raw Porkchop
64 | 360 => 2, //Melon
65 | 349 => 2, //Raw fish
66 | 265 => 2, //Raw Chicken
67 | 357 => 1, //Cookie
68 | 367 => 4, //Flesh
69 | 375 => 2, //Spider eye,
70 | );
71 |
72 |
73 | ?>
--------------------------------------------------------------------------------
/nbt.class.php:
--------------------------------------------------------------------------------
1 |
6 | * @version 1.0
7 | *
8 | * Dependencies:
9 | * PHP 4.3+ (5.3+ recommended)
10 | * GMP Extension
11 | */
12 |
13 | extension_loaded("gmp") or trigger_error (
14 | "The NBT class requires the GMP extension for 64-bit number handling. ".
15 | "Excecution will continue, but will halt if a 64-bit number is handled.", E_USER_NOTICE
16 | );
17 |
18 | class NBT {
19 | public $root = array();
20 |
21 | public $verbose = false;
22 |
23 | const TAG_END = 0;
24 | const TAG_BYTE = 1;
25 | const TAG_SHORT = 2;
26 | const TAG_INT = 3;
27 | const TAG_LONG = 4;
28 | const TAG_FLOAT = 5;
29 | const TAG_DOUBLE = 6;
30 | const TAG_BYTE_ARRAY = 7;
31 | const TAG_STRING = 8;
32 | const TAG_LIST = 9;
33 | const TAG_COMPOUND = 10;
34 |
35 | public function loadFile($filename, $wrapper = "compress.zlib://") {
36 | if(is_string($wrapper) && is_file($filename)) {
37 | if($this->verbose) trigger_error("Loading file \"{$filename}\" with stream wrapper \"{$wrapper}\".", E_USER_NOTICE);
38 | $fp = fopen("{$wrapper}{$filename}", "rb");
39 | } elseif(is_null($wrapper) && is_resource($filename)) {
40 | if($this->verbose) trigger_error("Loading file from existing resource.", E_USER_NOTICE);
41 | $fp = $filename;
42 | } else {
43 | trigger_error("First parameter must be a filename or a resource.", E_USER_WARNING);
44 | return false;
45 | }
46 | if($this->verbose) trigger_error("Traversing first tag in file.", E_USER_NOTICE);
47 | $this->traverseTag($fp, $this->root);
48 | if($this->verbose) trigger_error("Encountered end tag for first tag; finished.", E_USER_NOTICE);
49 | return end($this->root);
50 | }
51 |
52 | public function writeFile($filename, $wrapper = "compress.zlib://") {
53 | if(is_string($wrapper)) {
54 | if($this->verbose) trigger_error("Writing file \"{$filename}\" with stream wrapper \"{$wrapper}\".", E_USER_NOTICE);
55 | $fp = fopen("{$wrapper}{$filename}", "wb");
56 | } elseif(is_null($wrapper) && is_resource($fp)) {
57 | if($this->verbose) trigger_error("Writing file to existing resource.", E_USER_NOTICE);
58 | $fp = $filename;
59 | } else {
60 | trigger_error("First parameter must be a filename or a resource.", E_USER_WARNING);
61 | return false;
62 | }
63 | if($this->verbose) trigger_error("Writing ".count($this->root)." root tag(s) to file/resource.", E_USER_NOTICE);
64 | foreach($this->root as $rootNum => $rootTag) if(!$this->writeTag($fp, $rootTag)) trigger_error("Failed to write root tag #{$rootNum} to file/resource.", E_USER_WARNING);
65 | return true;
66 | }
67 |
68 | public function purge() {
69 | if($this->verbose) trigger_error("Purging all loaded data", E_USER_ERROR);
70 | $this->root = array();
71 | }
72 |
73 | public function traverseTag($fp, &$tree) {
74 | if(feof($fp)) {
75 | if($this->verbose) trigger_error("Reached end of file/resource.", E_USER_NOTICE);
76 | return false;
77 | }
78 | $tagType = $this->readType($fp, self::TAG_BYTE); // Read type byte.
79 | if($tagType == self::TAG_END) {
80 | return false;
81 | } else {
82 | if($this->verbose) $position = ftell($fp);
83 | $tagName = $this->readType($fp, self::TAG_STRING);
84 | if($this->verbose) trigger_error("Reading tag \"{$tagName}\" at offset {$position}.", E_USER_NOTICE);
85 | $tagData = $this->readType($fp, $tagType);
86 | $tree[] = array("type"=>$tagType, "name"=>$tagName, "value"=>$tagData);
87 | return true;
88 | }
89 | }
90 |
91 | public function writeTag($fp, $tag) {
92 | if($this->verbose) {
93 | $position = ftell($fp);
94 | trigger_error("Writing tag \"{$tag["name"]}\" of type {$tag["type"]} at offset {$position}.", E_USER_NOTICE);
95 | }
96 | return $this->writeType($fp, self::TAG_BYTE, $tag["type"]) && $this->writeType($fp, self::TAG_STRING, $tag["name"]) && $this->writeType($fp, $tag["type"], $tag["value"]);
97 | }
98 |
99 | public function readType($fp, $tagType) {
100 | switch($tagType) {
101 | case self::TAG_BYTE: // Signed byte (8 bit)
102 | list(,$unpacked) = unpack("c", fread($fp, 1));
103 | return $unpacked;
104 | case self::TAG_SHORT: // Signed short (16 bit, big endian)
105 | list(,$unpacked) = unpack("n", fread($fp, 2));
106 | if($unpacked >= pow(2, 15)) $unpacked -= pow(2, 16); // Convert unsigned short to signed short.
107 | return $unpacked;
108 | case self::TAG_INT: // Signed integer (32 bit, big endian)
109 | list(,$unpacked) = unpack("N", fread($fp, 4));
110 | if($unpacked >= pow(2, 31)) $unpacked -= pow(2, 32); // Convert unsigned int to signed int
111 | return $unpacked;
112 | case self::TAG_LONG: // Signed long (64 bit, big endian)
113 | extension_loaded("gmp") or trigger_error (
114 | "This file contains a 64-bit number and execution cannot continue. ".
115 | "Please install the GMP extension for 64-bit number handling.", E_USER_ERROR
116 | );
117 | list(,$firstHalf) = unpack("N", fread($fp, 4));
118 | list(,$secondHalf) = unpack("N", fread($fp, 4));
119 | $value = gmp_add($secondHalf, gmp_mul($firstHalf, "4294967296"));
120 | if(gmp_cmp($value, gmp_pow(2, 63)) >= 0) $value = gmp_sub($value, gmp_pow(2, 64));
121 | return gmp_strval($value);
122 | case self::TAG_FLOAT: // Floating point value (32 bit, big endian, IEEE 754-2008)
123 | list(,$value) = (pack('d', 1) == "\77\360\0\0\0\0\0\0")?unpack('f', fread($fp, 4)):unpack('f', strrev(fread($fp, 4)));
124 | return $value;
125 | case self::TAG_DOUBLE: // Double value (64 bit, big endian, IEEE 754-2008)
126 | list(,$value) = (pack('d', 1) == "\77\360\0\0\0\0\0\0")?unpack('d', fread($fp, 8)):unpack('d', strrev(fread($fp, 8)));
127 | return $value;
128 | case self::TAG_BYTE_ARRAY: // Byte array
129 | $arrayLength = $this->readType($fp, self::TAG_INT);
130 | $array = array();
131 | for($i = 0; $i < $arrayLength; $i++) $array[] = $this->readType($fp, self::TAG_BYTE);
132 | return $array;
133 | case self::TAG_STRING: // String
134 | if(!$stringLength = $this->readType($fp, self::TAG_SHORT)) return "";
135 | $string = utf8_decode(fread($fp, $stringLength)); // Read in number of bytes specified by string length, and decode from utf8.
136 | return $string;
137 | case self::TAG_LIST: // List
138 | $tagID = $this->readType($fp, self::TAG_BYTE);
139 | $listLength = $this->readType($fp, self::TAG_INT);
140 | if($this->verbose) trigger_error("Reading in list of {$listLength} tags of type {$tagID}.", E_USER_NOTICE);
141 | $list = array("type"=>$tagID, "value"=>array());
142 | for($i = 0; $i < $listLength; $i++) {
143 | if(feof($fp)) break;
144 | $list["value"][] = $this->readType($fp, $tagID);
145 | }
146 | return $list;
147 | case self::TAG_COMPOUND: // Compound
148 | $tree = array();
149 | while($this->traverseTag($fp, $tree));
150 | return $tree;
151 | }
152 | }
153 |
154 | public function writeType($fp, $tagType, $value) {
155 | switch($tagType) {
156 | case self::TAG_BYTE: // Signed byte (8 bit)
157 | return is_int(fwrite($fp, pack("c", $value)));
158 | case self::TAG_SHORT: // Signed short (16 bit, big endian)
159 | if($value < 0) $value += pow(2, 16); // Convert signed short to unsigned short
160 | return is_int(fwrite($fp, pack("n", $value)));
161 | case self::TAG_INT: // Signed integer (32 bit, big endian)
162 | if($value < 0) $value += pow(2, 32); // Convert signed int to unsigned int
163 | return is_int(fwrite($fp, pack("N", $value)));
164 | case self::TAG_LONG: // Signed long (64 bit, big endian)
165 | extension_loaded("gmp") or trigger_error (
166 | "This file contains a 64-bit number and execution cannot continue. ".
167 | "Please install the GMP extension for 64-bit number handling.", E_USER_ERROR
168 | );
169 | $secondHalf = gmp_mod($value, 2147483647);
170 | $firstHalf = gmp_sub($value, $secondHalf);
171 | return is_int(fwrite($fp, pack("N", gmp_intval($firstHalf)))) && is_int(fwrite($fp, pack("N", gmp_intval($secondHalf))));
172 | case self::TAG_FLOAT: // Floating point value (32 bit, big endian, IEEE 754-2008)
173 | return is_int(fwrite($fp, (pack('d', 1) == "\77\360\0\0\0\0\0\0")?pack('f', $value):strrev(pack('f', $value))));
174 | case self::TAG_DOUBLE: // Double value (64 bit, big endian, IEEE 754-2008)
175 | return is_int(fwrite($fp, (pack('d', 1) == "\77\360\0\0\0\0\0\0")?pack('d', $value):strrev(pack('d', $value))));
176 | case self::TAG_BYTE_ARRAY: // Byte array
177 | return $this->writeType($fp, self::TAG_INT, count($value)) && is_int(fwrite($fp, call_user_func_array("pack", array_merge(array("c".count($value)), $value))));
178 | case self::TAG_STRING: // String
179 | $value = utf8_encode($value);
180 | return $this->writeType($fp, self::TAG_SHORT, strlen($value)) && is_int(fwrite($fp, $value));
181 | case self::TAG_LIST: // List
182 | if($this->verbose) trigger_error("Writing list of ".count($value["value"])." tags of type {$value["type"]}.", E_USER_NOTICE);
183 | if(!($this->writeType($fp, self::TAG_BYTE, $value["type"]) && $this->writeType($fp, self::TAG_INT, count($value["value"])))) return false;
184 | foreach($value["value"] as $listItem) if(!$this->writeType($fp, $value["type"], $listItem)) return false;
185 | return true;
186 | case self::TAG_COMPOUND: // Compound
187 | foreach($value as $listItem) if(!$this->writeTag($fp, $listItem)) return false;
188 | if(!is_int(fwrite($fp, "\0"))) return false;
189 | return true;
190 | }
191 | }
192 | }
193 | ?>
--------------------------------------------------------------------------------
/packets.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packets/03Chat.php:
--------------------------------------------------------------------------------
1 | "), $packet["message"]);
13 | $channel = "";
14 | if(strpos($packet["message"], "]<") !== false){
15 | $packet["message"] = explode("]<", substr($packet["message"],1));
16 | $channel = $packet["message"][0];
17 | $packet["message"] = "<".$packet["message"][1];
18 | }
19 | $sender = false;
20 | $me = false;
21 | if($packet["message"]{0} == "["){
22 | $sender = explode(".", substr($packet["message"],1,strpos($packet["message"], "->")-2));
23 | $sender = isset($sender[1]) ? $sender[1]:$sender[0];
24 | $packet["message"] = substr($packet["message"],strpos($packet["message"], "]")+2);
25 | if(strpos($packet["message"],": ")!==false){
26 | $packet["message"] = explode("] ",$packet["message"]);
27 | $packet["message"] = trim($packet["message"][count($packet["message"])-1]);
28 | $sender = false;
29 | }
30 | }elseif(strpos($packet["message"], " whispers ") !== false){
31 | $sender = substr($packet["message"],0,strpos($packet["message"], " "));
32 | $packet["message"] = substr($packet["message"],strpos($packet["message"], " whispers ")+10);
33 | }
34 | if(stripos($packet["message"], "bot") !== false and $sender == false){
35 |
36 |
37 |
38 | if($packet["message"]{0} == "<"){
39 | $mess = substr($packet["message"],strpos($packet["message"], "> ")+2);
40 | $sender = explode(".", substr($packet["message"],1,strpos($packet["message"], "> ")-1));
41 | }else{
42 | $sender = explode(".", substr($packet["message"],0,strpos($packet["message"], ": ")));
43 | $mess = substr($packet["message"],strpos($packet["message"], ": ")+2);
44 | }
45 | $sender = isset($sender[1]) ? $sender[1]:$sender[0];
46 |
47 | if(strtolower(substr($mess,0,3)) != "bot"){
48 | $sender = false;
49 | }else{
50 | $me = true;
51 | $packet["message"] = substr($mess, ($mess{4} == " " ? 5:4));
52 | }
53 | }
54 |
55 | $mp = false;
56 | if(($sender !== false and $sender != "me" and $sender != "yo") or $me == true){
57 | $mp = true;
58 | $value = explode(" ", $packet["message"]);
59 | $command = strtolower($value[0]);
60 | unset($value[0]);
61 | $value = implode(" ",$value);
62 | if(!command($command, $value, $sender)){
63 | include("chat_help.php");
64 | }
65 | return "[$sender --> me] ".$packet["message"];
66 | }else{
67 | if($packet["message"]{0} == "<"){
68 | $sender = explode(".", substr($packet["message"],1,strpos($packet["message"], "> ")-1));
69 | }else{
70 | $sender = explode(".", substr($packet["message"],0,strpos($packet["message"], ": ")-1));
71 | }
72 | $sender = isset($sender[1]) ? $sender[1]:$sender[0];
73 | include("chat_help.php");
74 | return $packet["message"];
75 | }
76 | }
77 |
78 | function privateMessage($message, $target){
79 | foreach(explode("\n", wordwrap($message,100-strlen("/tell $target "), "\n")) as $mess){
80 | write_packet("03", array(
81 | "message" => "/tell $target $mess",
82 | ));
83 | }
84 | console("[me --> $target] ".$message);
85 | }
86 |
87 | function Message($message){
88 | foreach(explode("\n", wordwrap($message,100, "\n")) as $mess){
89 | write_packet("03", array(
90 | "message" => $mess,
91 | ));
92 | }
93 | }
94 | ?>
--------------------------------------------------------------------------------
/pstruct.php:
--------------------------------------------------------------------------------
1 | array(
11 | "int",
12 | ),
13 |
14 | "01" => array(
15 | "int",
16 | "string",
17 | "string",
18 | "int",
19 | "int",
20 | "byte",
21 | "ubyte",
22 | "ubyte",
23 | ),
24 |
25 | "02" => array(
26 | "string",
27 | ),
28 |
29 | "03" => array(
30 | "string",
31 | ),
32 |
33 | "04" => array(
34 | "long",
35 | ),
36 |
37 | "05" => array(
38 | "int",
39 | "short",
40 | "short",
41 | "short",
42 | ),
43 |
44 | "06" => array(
45 | "int",
46 | "int",
47 | "int",
48 | ),
49 |
50 | "08" => array(
51 | "short",
52 | "short",
53 | "float",
54 | ),
55 |
56 | "09" => array(
57 | "int",
58 | "byte",
59 | "byte",
60 | "short",
61 | "string",
62 | ),
63 |
64 | "0d" => array(
65 | "double",
66 | "double",
67 | "double",
68 | "double",
69 | "float",
70 | "float",
71 | "bool",
72 | ),
73 |
74 | "10" => array(
75 | "short",
76 | ),
77 |
78 | "11" => array(
79 | "int",
80 | "byte",
81 | "int",
82 | "byte",
83 | "int",
84 | ),
85 |
86 | "12" => array(
87 | "int",
88 | "byte",
89 | ),
90 |
91 | "14" => array(
92 | "int",
93 | "string",
94 | "int",
95 | "int",
96 | "int",
97 | "byte",
98 | "byte",
99 | "short",
100 | ),
101 |
102 | "15" => array(
103 | "int",
104 | "short",
105 | "byte",
106 | "short",
107 | "int",
108 | "int",
109 | "int",
110 | "byte",
111 | "byte",
112 | "byte",
113 | ),
114 |
115 | "16" => array(
116 | "int",
117 | "int",
118 | ),
119 |
120 | "17" => array(
121 | "int",
122 | "byte",
123 | "int",
124 | "int",
125 | "int",
126 | "int", //if >0, fireball
127 | "short",
128 | "short",
129 | "short",
130 | ),
131 |
132 | "18" => array(
133 | "int",
134 | "byte",
135 | "int",
136 | "int",
137 | "int",
138 | "byte",
139 | "byte",
140 | "byte",
141 | "entityMetadata",
142 | ),
143 |
144 | "19" => array(
145 | "int",
146 | "string",
147 | "int",
148 | "int",
149 | "int",
150 | "int",
151 | ),
152 |
153 | "1a" => array(
154 | "int",
155 | "int",
156 | "int",
157 | "int",
158 | "short",
159 | ),
160 |
161 | "1b" => array(
162 | "float",
163 | "float",
164 | "float",
165 | "float",
166 | "bool",
167 | "bool",
168 | ),
169 |
170 | "1c" => array(
171 | "int",
172 | "short",
173 | "short",
174 | "short",
175 | ),
176 |
177 | "1d" => array(
178 | "int",
179 | ),
180 |
181 | "1e" => array(
182 | "int",
183 | ),
184 |
185 | "1f" => array(
186 | "int",
187 | "byte",
188 | "byte",
189 | "byte",
190 | ),
191 |
192 | "20" => array(
193 | "int",
194 | "byte",
195 | "byte",
196 | ),
197 |
198 | "21" => array(
199 | "int",
200 | "byte",
201 | "byte",
202 | "byte",
203 | "byte",
204 | "byte",
205 | ),
206 |
207 | "22" => array(
208 | "int",
209 | "int",
210 | "int",
211 | "int",
212 | "byte",
213 | "byte",
214 | ),
215 |
216 | "23" => array(
217 | "int",
218 | "byte",
219 | ),
220 |
221 | "26" => array(
222 | "int",
223 | "byte",
224 | ),
225 |
226 | "27" => array(
227 | "int",
228 | "int",
229 | ),
230 |
231 | "28" => array(
232 | "int",
233 | "entityMetadata",
234 | ),
235 |
236 | "29" => array(
237 | "int",
238 | "byte",
239 | "byte",
240 | "short",
241 | ),
242 |
243 | "2a" => array(
244 | "int",
245 | "byte",
246 | ),
247 |
248 | "2b" => array(
249 | "float",
250 | "short",
251 | "short",
252 | ),
253 |
254 | "32" => array(
255 | "int",
256 | "int",
257 | "bool",
258 | ),
259 |
260 | "33" => array(
261 | "int",
262 | "int",
263 | "bool",
264 | "short",
265 | "short",
266 | "int",
267 | "int",
268 | "newChunkArray",
269 | ),
270 |
271 | "34" => array(
272 | "int",
273 | "int",
274 | "short",
275 | "int",
276 | "newMultiblockArray",
277 | ),
278 |
279 | "35" => array(
280 | "int",
281 | "byte",
282 | "int",
283 | "byte",
284 | "byte",
285 | ),
286 |
287 | "36" => array(
288 | "int",
289 | "short",
290 | "int",
291 | "byte",
292 | "byte",
293 | ),
294 |
295 | "3c" => array(
296 | "double",
297 | "double",
298 | "double",
299 | "float",
300 | "int",
301 | "explosionRecord"
302 | ),
303 |
304 | "3d" => array(
305 | "int",
306 | "int",
307 | "byte",
308 | "int",
309 | "int",
310 | ),
311 |
312 | "46" => array(
313 | "byte",
314 | "byte",
315 | ),
316 |
317 | "47" => array(
318 | "int",
319 | "bool",
320 | "int",
321 | "int",
322 | "int",
323 | ),
324 |
325 | "64" => array(
326 | "byte",
327 | "byte",
328 | "string",
329 | "byte",
330 | ),
331 |
332 | "65" => array(
333 | "byte",
334 | ),
335 |
336 | "67" => array(
337 | "byte",
338 | "short",
339 | "slotData",
340 | ),
341 |
342 | "68" => array(
343 | "byte",
344 | "short",
345 | "slotArray",
346 | ),
347 |
348 | "69" => array(
349 | "byte",
350 | "short",
351 | "short",
352 | ),
353 |
354 | "6a" => array(
355 | "byte",
356 | "short",
357 | "bool",
358 | ),
359 |
360 | "6b" => array(
361 | "short",
362 | "slotData",
363 | ),
364 |
365 | "6c" => array(
366 | "byte",
367 |
368 | ),
369 |
370 | "82" => array(
371 | "int",
372 | "short",
373 | "int",
374 | "string",
375 | "string",
376 | "string",
377 | "string",
378 | ),
379 |
380 | "83" => array(
381 | "short",
382 | "short",
383 | "ubyte",
384 | "byteArray",
385 | ),
386 |
387 | "84" => array(
388 | "int",
389 | "short",
390 | "int",
391 | "byte",
392 | "int",
393 | "int",
394 | "int",
395 | ),
396 |
397 | "c8" => array(
398 | "int",
399 | "byte",
400 | ),
401 |
402 | "c9" => array(
403 | "string",
404 | "byte",
405 | "short",
406 | ),
407 |
408 | "ca" => array(
409 | "bool",
410 | "bool",
411 | "bool",
412 | "bool",
413 | ),
414 |
415 | "cb" => array(
416 | "string",
417 | ),
418 |
419 | "fa" => array(
420 | "string",
421 | "short",
422 | "byteArray",
423 | ),
424 |
425 | "fe" => array(
426 | "string",
427 | ),
428 |
429 | "ff" => array(
430 | "string",
431 | ),
432 | );
433 |
434 |
435 | ?>
436 |
--------------------------------------------------------------------------------
/pstruct_modifier.php:
--------------------------------------------------------------------------------
1 | = 23){
7 | unset($pstruct["1b"]);
8 | }
9 |
10 | if($protocol <= 23){
11 | $pstruct["01"] = array(
12 | "int",
13 | "string",
14 | "long",
15 | "string",
16 | "int",
17 | "byte",
18 | "byte",
19 | "ubyte",
20 | "ubyte",
21 | );
22 | $pstruct["09"] = array(
23 | "byte",
24 | "byte",
25 | "byte",
26 | "short",
27 | "long",
28 | "string",
29 | );
30 | $pstruct["18"] = array(
31 | "int",
32 | "byte",
33 | "int",
34 | "int",
35 | "int",
36 | "byte",
37 | "byte",
38 | "entityMetadata",
39 | );
40 | $pstruct["33"] = array(
41 | "int",
42 | "short",
43 | "int",
44 | "byte",
45 | "byte",
46 | "byte",
47 | "int",
48 | "chunkArray",
49 | );
50 |
51 | $pstruct["34"] = array(
52 | "int",
53 | "int",
54 | "short",
55 | "multiblockArray",
56 | );
57 | }
58 |
59 | if($protocol <= 22){
60 | $pstruct["09"] = array(
61 | "byte",
62 | "byte",
63 | "byte",
64 | "short",
65 | "long",
66 | );
67 | $pstruct["01"] = array(
68 | "int",
69 | "string",
70 | "long",
71 | "int",
72 | "byte",
73 | "byte",
74 | "ubyte",
75 | "ubyte",
76 | );
77 | }
78 |
79 | if($protocol <= 17){
80 | $pstruct["2b"] = array(
81 | "byte",
82 | "byte",
83 | "short",
84 | );
85 | }
86 | if($protocol <= 14){
87 | $pstruct["00"] = array();
88 | $pstruct["01"] = array(
89 | "int",
90 | "string",
91 | "long",
92 | "byte",
93 | );
94 | $pstruct["46"] = array(
95 | "int",
96 | );
97 | }
98 |
99 | ?>
100 |
--------------------------------------------------------------------------------