Initial commit
parent
cdf753c912
commit
8623ecc4a0
|
@ -1,27 +1,62 @@
|
|||
<?php
|
||||
$nodes=array();
|
||||
ini_set('memory_limit', '1024M');
|
||||
$nodes[0][0][0]="CONTENT_IGNORE";//Initialize array, overwritten later anyway.
|
||||
require_once 'servercommands.php';
|
||||
require_once 'miscdefines.php';
|
||||
require_once 'hardwiredContentTypes.php';
|
||||
define("CMDTOSERVER", 1); //Otherwise to client
|
||||
define("CMDSENDRELIABLE", 2);
|
||||
define("CMDACKNEEDED", 4);
|
||||
define("CMDACTIONRELIABLE", 8);
|
||||
require_once 'network.php';
|
||||
require_once 'processCommunication.php';
|
||||
require_once 'packet.php';
|
||||
require_once 'serialize.php';
|
||||
require_once 'lowLevelNet.php';
|
||||
require_once 'networkMaintenance.php';
|
||||
require_once 'sendComm.php';
|
||||
var_dump(unpack("n",serializeU16(65500)));
|
||||
var_dump(unpack('n', "\xff\xdc"));
|
||||
|
||||
require_once 'knownMap.php';
|
||||
//define("CMDTOSERVER", 1); //Otherwise to client
|
||||
//define("CMDSENDRELIABLE", 2);
|
||||
//define("CMDACKNEEDED", 4);
|
||||
//define("CMDACTIONRELIABLE", 8);
|
||||
if (PHP_SAPI != "cli") {
|
||||
die("Main [FATAL]:Must be run in CLI mode!");
|
||||
}
|
||||
if ($argc != 3) {
|
||||
die("Main [FATAL]:Improper arguments!\r\n Usage: minetestbot.php host port controlfile");
|
||||
if ($argc != 6) {
|
||||
var_dump($argv);
|
||||
var_dump($argc);
|
||||
die("Main [FATAL]:Improper arguments!\r\n Usage: minetestbot.php <host> <port> <username> <pass> <controlfile>");
|
||||
|
||||
}
|
||||
$serverIp = $argv[1];
|
||||
$serverPort = $argv[2];
|
||||
$controlFile = $argv[3];
|
||||
$username = $argv[3];
|
||||
$password = $argv[4];
|
||||
$controlFile = $argv[5];
|
||||
$serverSocket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
|
||||
if (false == (@socket_connect($serverSocket, $serverIp, $serverPort))) {
|
||||
die("Connect [FATAL]:Connect failed: reason: " . socket_strerror(socket_last_error($serverSocket)) . "\n");
|
||||
|
||||
if (false == (socket_connect($serverSocket, $serverIp, $serverPort))) {
|
||||
die("Connect [FATAL]:Connect failed: reason: " . socket_strerror(socket_last_error($serverSocket)) . "\n");
|
||||
}
|
||||
$controlHandle = fopen($controlFile, "rb");
|
||||
$fileReadBuffer = fread($controlHandle, 8);
|
||||
if (strcasecmp($fileReadBuffer, "mtbotpurephp")!=0){
|
||||
die("File [FATAL]:Impropper file header, perhaps not a MTBot control file?");
|
||||
socket_set_nonblock($serverSocket);
|
||||
//socket_write($serverSocket, "FOOBARFOOBAR");
|
||||
require_once $controlFile;
|
||||
//$controlHandle = fopen($controlFile, "rb");
|
||||
//$fileReadBuffer = fread($controlHandle, 8);
|
||||
//if (strcasecmp($fileReadBuffer, "mtbotpurephp")!=0){
|
||||
// die("File [FATAL]:Impropper file header, perhaps not a MTBot control file?");
|
||||
//}
|
||||
////TODO: Get password from file
|
||||
sendTOSERVER_INIT($username, $password);
|
||||
//$connectSeqNum = sendPacket(FormReliablePacket(FormOriginalPacket("")));
|
||||
//blockingLoopWaitPacketAck($connectSeqNum);
|
||||
//while($ourPeerId==0){
|
||||
// readNetworkPacket($serverSocket);
|
||||
//}
|
||||
|
||||
while(true){
|
||||
usleep(100);
|
||||
readNetworkPacket($serverSocket);
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
?>
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
?>
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
|
||||
$packetBuffer = array();
|
||||
|
||||
//require_once 'index.php';
|
||||
define("BASE_HEADER_SIZE", 7);
|
||||
define("PEER_ID_INEXISTENT", 0);
|
||||
define("PEER_ID_SERVER", 1);
|
||||
define("CHANNEL_COUNT", 3);
|
||||
define("TYPE_CONTROL", 0);
|
||||
define("CONTROLTYPE_ACK", 0);
|
||||
define("CONTROLTYPE_SET_PEER_ID", 1);
|
||||
define("CONTROLTYPE_PING", 2);
|
||||
define("CONTROLTYPE_DISCO", 3);
|
||||
define("TYPE_SPLIT", 2);
|
||||
define("TYPE_RELIABLE", 3);
|
||||
define("RELIABLE_HEADER_SIZE", 3);
|
||||
define("SEQNUM_INITIAL", 65500);
|
||||
$seqnumOut = SEQNUM_INITIAL;
|
||||
$seqnumIn = SEQNUM_INITIAL;
|
||||
$ourPeerId = PEER_ID_INEXISTENT;
|
||||
$serverPeerId = PEER_ID_SERVER;
|
||||
$bufferedPackets = array();
|
||||
|
||||
function readNetworkPacket($socket) {
|
||||
global $seqnumIn;
|
||||
global $seqnumOut;
|
||||
global $ourPeerId;
|
||||
global $serverPeerId;
|
||||
global $bufferedPackets;
|
||||
global $packetsAwaitingSend;
|
||||
$packet = socket_read($socket, 4096, PHP_BINARY_READ);
|
||||
if (strlen($packet) > 0) {
|
||||
echo 'Got packet!';
|
||||
$protocolId = substr($packet, 0, 4);
|
||||
$senderPeerId = deserializeU16(substr($packet, 4, 2));
|
||||
$channel = ord(substr($packet, 6, 1));
|
||||
$packetType = ord(substr($packet, 7, 1));
|
||||
switch ($packetType) {
|
||||
case TYPE_CONTROL:
|
||||
$controlType = ord(substr($packet, 8, 1));
|
||||
switch ($controlType) {
|
||||
case CONTROLTYPE_ACK:
|
||||
$seqnumAckd = deserializeU16(substr($packet, 9, 2));
|
||||
unset($packetsAwaitingSend[$seqnumAckd]);
|
||||
break;
|
||||
case CONTROLTYPE_SET_PEER_ID:
|
||||
$peerId = deserializeU16(substr($packet, 9, 1));
|
||||
$ourPeerId = $peerId;
|
||||
echo "Got our peer id!";
|
||||
return true;
|
||||
break;
|
||||
case CONTROLTYPE_DISCO:
|
||||
exit("Disconnected.");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TYPE_RELIABLE:
|
||||
$incomingSeqnum = deserializeU16(substr($packet, 8, 1));
|
||||
sendAck($incomingSeqnum);
|
||||
$packetPayload = substr($packet, 10);
|
||||
if (isset($bufferedPackets[$seqnumIn])) {
|
||||
$seqnumIn++;
|
||||
$seqnumIn = $seqnumIn % 65536;
|
||||
readNetworkPacket($bufferedPackets[$seqnumIn]);
|
||||
}
|
||||
|
||||
break;
|
||||
case TYPE_ORIGINAL:
|
||||
processCommandToClient(substr($packet, 8));
|
||||
break;
|
||||
case TYPE_SPLIT:
|
||||
//TODO Split packet
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function readNetworkPacketNested($packIn) {
|
||||
global $seqnumIn;
|
||||
global $seqnumOut;
|
||||
global $ourPeerId;
|
||||
global $serverPeerId;
|
||||
global $packetsAwaitingSend;
|
||||
global $bufferedPackets;
|
||||
$packetType = ord(substr($packet, 0, 1));
|
||||
switch ($packetType) {
|
||||
case TYPE_CONTROL:
|
||||
$controlType = ord(substr($packet, 1, 1));
|
||||
switch ($controlType) {
|
||||
case CONTROLTYPE_ACK:
|
||||
$seqnumAckd = deserializeU16(substr($packet, 2, 2));
|
||||
unset($packetsAwaitingSend[$seqnumAckd]);
|
||||
case CONTROLTYPE_SET_PEER_ID:
|
||||
$peerId = deserializeU16(substr($packet, 2, 2));
|
||||
$ourPeerId = $peerId;
|
||||
echo "Got our peer ID!";
|
||||
return true;
|
||||
break;
|
||||
case CONTROLTYPE_DISCO:
|
||||
exit("Disconnected.");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TYPE_RELIABLE:
|
||||
$incomingSeqnum = deserializeU16(substr($packet, 1, 1));
|
||||
sendAck($incomingSeqnum);
|
||||
$packetPayload = substr($packet, 3);
|
||||
if (isset($bufferedPackets[$seqnumIn])) {
|
||||
$seqnumIn++;
|
||||
$seqnumIn = $seqnumIn % 65536;
|
||||
readNetworkPacketNested($bufferedPackets[$seqnumIn]);
|
||||
}
|
||||
|
||||
break;
|
||||
case TYPE_ORIGINAL:
|
||||
processCommandToClient(substr($packet, 1));
|
||||
break;
|
||||
case TYPE_SPLIT:
|
||||
//TODO Split packet
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function sendPacket($packet) {
|
||||
global $serverSocket;
|
||||
socket_write($serverSocket, "\x4f\x45\x74\x03\x00\x01\x00" . $packet);
|
||||
}
|
||||
|
||||
function formReliablePacket($packet) {
|
||||
global $seqnumOut;
|
||||
$packetOut = chr(3) . serializeU16($seqnumOut) . $packet;
|
||||
$seqnumOut++;
|
||||
return $packetOut;
|
||||
}
|
||||
|
||||
function formOriginalPacket($packet) {
|
||||
if(strlen($packet)!=0){
|
||||
return chr(1) . chr(0) . $packet;
|
||||
}
|
||||
else{
|
||||
return chr(1);
|
||||
}
|
||||
}
|
||||
|
||||
function sendPing() {
|
||||
global $serverSocket;
|
||||
$pingPacket = "\x4f\x45\x74\x03\x00\x01\x00" . chr(TYPE_CONTROL) . chr(CONTROLTYPE_PING);
|
||||
socket_write($serverSocket, $pingPacket);
|
||||
}
|
||||
|
||||
function sendAck($seqnumToAck) {
|
||||
global $serverSocket;
|
||||
$ackpacket = "\x4f\x45\x74\x03\x00\x01\x00" . chr(TYPE_CONTROL) . chr(CONTROLTYPE_ACK) . serializeU16($seqnumToAck);
|
||||
socket_write($serverSocket, $ackPacket);
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
$packetsAwaitingSend=array();
|
||||
$lastSend=microtime(true);
|
||||
function FiveSecPoll(){
|
||||
global $lastSend;
|
||||
global $packetsAwaitingSend;
|
||||
foreach ($packetsAwaitingSend as $seqnumToSend => $data) {
|
||||
FormReliablePacketWithSeqnum($seqnum, $data);
|
||||
}
|
||||
if ((microtime(true)-$lastSend)>=4){
|
||||
SendPing();
|
||||
}
|
||||
}
|
||||
//function
|
||||
?>
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
//require_once 'index.php';
|
||||
//require_once 'network.php';
|
||||
//class BufferedPacket{
|
||||
// global $seqnum;
|
||||
// global $ourPeerId;
|
||||
// global $serverPeerId;
|
||||
// public $isControl;
|
||||
// public $isFrag;
|
||||
// public $totalFrags;
|
||||
// public $fragsReady;
|
||||
// function __construct($seqnum, $t){}
|
||||
// function isReady(){
|
||||
// return $totalFrags==$fragsReady;
|
||||
// }
|
||||
//}
|
||||
?>
|
|
@ -1,41 +1,105 @@
|
|||
<?php
|
||||
require_once 'servercommands.php';
|
||||
//$testPacket="\x4f\x45\x74\x03\x00\x00\x00\x01\x00\x10\x19\x72\x61\x72\x6b\x65\x6e\x69\x6e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x62\x2b\x48\x57\x64\x71\x4a\x34\x38\x36\x47\x49\x73\x32\x47\x4e\x74\x6e\x47\x31\x4c\x64\x4a\x48\x4e\x4d\x00\x00\x0d\x00\x10";
|
||||
function processCommandToClient($packet) {
|
||||
$magicNum=substr($packet,0,4);
|
||||
$senderPeerId=substr($packet, 4,2);
|
||||
$packetChannel=substr($packet,6,1);
|
||||
|
||||
$payload=substr($packet, 9);
|
||||
require_once 'servercommands.php';
|
||||
|
||||
$testPacket = "\x4f\x45\x74\x03\x00\x00\x00\x01\x00\x10\x19\x72\x61\x72\x6b\x65\x6e\x69\x6e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x62\x2b\x48\x57\x64\x71\x4a\x34\x38\x36\x47\x49\x73\x32\x47\x4e\x74\x6e\x47\x31\x4c\x64\x4a\x48\x4e\x4d\x00\x00\x0d\x00\x10";
|
||||
|
||||
function processCommandToClient($packet) {
|
||||
global $recommended_send_interval;
|
||||
global $privsarray;
|
||||
global $mapseed;
|
||||
global $playerpos;
|
||||
global $knownMap;
|
||||
$headerByte = ord(substr($payload, 0, 1));
|
||||
$datasize = strlen($payload);
|
||||
print $headerByte;
|
||||
print "\n";
|
||||
$headerByte = ord(substr($packet, 0, 1));
|
||||
$datasize = strlen($packet);
|
||||
//print $headerByte . "\n";
|
||||
//print ord(substr($packet, 0, 1));
|
||||
//print "\n";
|
||||
print CLIENT_INIT;
|
||||
switch ($headerByte) {
|
||||
case CLIENT_INIT:
|
||||
//var_dump(($magicNum),($senderPeerId), ($packetChannel), $payload);
|
||||
// print("DUMMY!");
|
||||
/*sendCmd(SERVER_INIT2); TODO: Implement sending SERVER_INIT2*/
|
||||
switch ($datasize){
|
||||
case 2+1+6+8+4:
|
||||
/*TODO: Unpack codes for data... */
|
||||
var_dump(($magicNum), ($senderPeerId), ($packetChannel), $packet);
|
||||
print("DUMMY!");
|
||||
sendCmd(SERVER_INIT2, array());
|
||||
/* TODO: CRITICAL Implement sending SERVER_INIT2 */
|
||||
switch ($datasize) {
|
||||
case 2 + 1 + 6 + 8 + 4:
|
||||
/* TODO: Unpack codes for data... */
|
||||
}
|
||||
break;
|
||||
case CLIENT_ACCESS_DENIED:
|
||||
die("Connect [FATAL]:Connect failed reason: Access denied");
|
||||
break;
|
||||
case CLIENT_REMOVENODE:
|
||||
$nodepos=deserializeNodePos(substr($payload,2));
|
||||
$nodepos = deserializeNodePos(substr($packet, 1, 6));
|
||||
removeNode($nodepos);
|
||||
break;
|
||||
case CLIENT_ADDNODE:
|
||||
$nodepos = deserializeNodePos(substr($packet, 1, 6));
|
||||
$node = deserializeNode(substr($packet, 7));
|
||||
addNode($nodepos, $node);
|
||||
break;
|
||||
case CLIENT_BLOCKDATA:
|
||||
/* TODO: CRITICAL FIGURE OUT MapNode::deSerialize in mapNode.cpp, as well as deserialize bulk. */
|
||||
print("Packet Handling [TODO]: CLIENT_BLOCKDATA received but not processed.\n");
|
||||
break;
|
||||
case CLIENT_INVENTORY:
|
||||
/* TODO: MEDIUM Figure out Inventory serialization!!!
|
||||
* * void InventoryList::deSerialize(std::istream &is) in inventory.cpp
|
||||
* void Inventory::deSerialize(std::istream &is) in inventory.cpp */
|
||||
print("Packet Handling [TODO]: CLIENT_INVENTORY received but not processed.\n");
|
||||
break;
|
||||
case CLIENT_CHAT_MESSAGE:
|
||||
$length = deserializeU16(substr($packet, 1, 2));
|
||||
$message = minetestWideToNarrow(substr($packet));
|
||||
processChatMsg($message);
|
||||
break;
|
||||
case CLIENT_MOVE_PLAYER:
|
||||
$playerpos = readV3F100(substr($packet, 1, 12));
|
||||
break;
|
||||
case CLIENT_DEATHSCREEN:
|
||||
print("Player [INFO]: Player died at " . $playerpos . toString() . ".\n");
|
||||
sendCmd(SERVER_RESPAWN, array());
|
||||
break;
|
||||
case CLIENT_PRIVILEGES:
|
||||
$numPrivs = deserializeU16(substr($packet, 1, 2));
|
||||
$privsarray = array();
|
||||
$packetPos = 3;
|
||||
for ($i = 1; $i <= numPrivs; $i++) {
|
||||
$thisIterationLength = deserializeU16(substr($packet, $packetPos, 2));
|
||||
$packetPos+=2;
|
||||
array_push($privsarray, substr($packet, $packetpos, $thisIterationLength));
|
||||
$packetPos+=$thisIterationLength;
|
||||
}
|
||||
$privs = implode(", ", $privsarray);
|
||||
print("Player [INFO]: Got privs: $privs\n");
|
||||
break;
|
||||
case CLIENT_INVENTORY_FORMSPEC:
|
||||
$length = deserializeU32(substr($packet, 1, 4));
|
||||
$invSpec = substr($packet, 5, $length);
|
||||
break;
|
||||
case CLIENT_DETACHED_INVENTORY:
|
||||
$nameLength=deserializeU16(substr($packet, 1, 2));
|
||||
$invName=substr($packet,3, $nameLength);
|
||||
$invBody=substr($packet,3+$nameLength);
|
||||
$detachedInvs[$invName]=deserializeInv($invBody); /* TODO: MEDUIM Deserialize Invs. Doesn't look that hard.
|
||||
* void InventoryList::deSerialize(std::istream &is) in inventory.cpp
|
||||
* void Inventory::deSerialize(std::istream &is) in inventory.cpp
|
||||
*/
|
||||
break;
|
||||
case CLIENT_SHOW_FORMSPEC:
|
||||
print("ServerAction [INFO]: Not showing formspec, ignored.");
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
function deserializeNodePos($string){
|
||||
/*TODO: IMPLEMENT*/
|
||||
|
||||
|
||||
|
||||
function processChatMsg($message) {
|
||||
print "received chat message: ".$message . "\n";
|
||||
}
|
||||
|
||||
//processCommandToClient($testPacket);
|
||||
|
||||
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
require_once 'servercommands.php';
|
||||
|
||||
function sendTOSERVER_INIT($username, $passphrase) {
|
||||
|
||||
$packetToSend = chr(SERVER_INIT);
|
||||
$packetToSend.=chr(25);
|
||||
$packetToSend.=str_pad($username, 20, chr(0), STR_PAD_RIGHT);
|
||||
if (preg_match("/^[A-Za-z0-9]{27}$/", $passphrase) != 1) {
|
||||
die("The passphrase must be 27 characters, which may be alphanumeric, with case sensitivity.");
|
||||
}
|
||||
$packetToSend.=$passphrase . chr(0) . serializeU16(13) . serializeU16(25);
|
||||
sendPacket(formReliablePacket(formOriginalPacket("")));
|
||||
sendPacket(formOriginalPacket($packetToSend));
|
||||
|
||||
}
|
||||
|
||||
function sendTOSERVER_PLAYERPOS() {
|
||||
$packet = chr(SERVER_PLAYERPOS);
|
||||
$packet.=$knownmap->player->pos->getAsV3F100();
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
define("POINTEDTHING_NOTHING", 0);
|
||||
define("POINTEDTHING_NODE", 1);
|
||||
define("POINTEDTHING_OBJECT", 2);
|
||||
|
||||
function deserializeNodePos($in) {
|
||||
|
||||
}
|
||||
|
||||
function deserializeNode($in) {
|
||||
global $knownNodes;
|
||||
}
|
||||
|
||||
function deserializeU16($in) {
|
||||
$retval = unpack("nout", $in);
|
||||
return $retval[out];
|
||||
}
|
||||
|
||||
function minetestWideToNarrow($in) {
|
||||
$out = "";
|
||||
$length = strlen($in);
|
||||
for ($i = 1; $i < $length; $i+=2) {
|
||||
$out = $out . $in[$i];
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function serializePointedThing($abovesurface, $undersurface, $type) {
|
||||
/*
|
||||
* Undersurface gets punched
|
||||
* Abovesurface is target for node place
|
||||
*/
|
||||
$out = "";
|
||||
$out = $out . chr(0);
|
||||
$out.=chr($type);
|
||||
if ($type == POINTEDTHING_NODE) {
|
||||
$out = $out . serializeNodePos($undersurface);
|
||||
$out = $out . serializeNodePos($abovesurface);
|
||||
}return $out;
|
||||
}
|
||||
|
||||
function serializeU16($in){
|
||||
$retval=pack("n", $in);
|
||||
//echo("Serialized $in to $retval");
|
||||
return $retval;
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -18,7 +18,7 @@
|
|||
explicitly sent afterwards
|
||||
*/
|
||||
|
||||
define("CLIENT_BLOCKDATA",0x20); //TODO: Multiple blocks
|
||||
define("CLIENT_BLOCKDATA",0x20);
|
||||
define("CLIENT_ADDNODE",0x21);
|
||||
define("CLIENT_REMOVENODE",0x22);
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
<?php
|
||||
$string="\x04\x00\xa0\x00";
|
||||
$array=unpack("cchars/nint/nint2/nint3/nint4/nint5/nint6", $string);
|
||||
var_dump($array);
|
||||
var_dump(preg_match("/^[A-Za-z0-9]{27}$/", "aaaaaaaaaaaaa6!aaaaaaaaaaaa"));
|
||||
?>
|
||||
|
|
Loading…
Reference in New Issue