Код класса PHP для работы с пакетами — различия между версиями

Материал из Perfect World Develop Wiki
Перейти к: навигация, поиск
Строка 1: Строка 1:
<syntaxhighlight lang="php"><?
+
<syntaxhighlight lang="php">><?
// Herzlich Willkommen. Das ist "Packet Class PW".
+
// "Packet Class PW".
// Bei Desmond Hume
+
// By JonMagon (Desmond Hume)
class ReadPacket
+
class ReadPacket {
{
+
 
public $data, $pos;
 
public $data, $pos;
 
 
function __construct($obj = null)
+
function __construct($obj = null){
{
+
$this->data = $obj->response;
$this -> data = $obj -> response;
+
 
}
 
}
 
 
public function ReadBytes($length)
+
public function ReadBytes($length){
{
+
$value = substr($this->data, $this->pos, $length);
$value = substr($this -> data, $this -> pos, $length);
+
$this->pos += $length;
$this -> pos += $length;
+
 
 
 
return $value;
 
return $value;
 
}
 
}
 
 
public function ReadUByte()
+
public function ReadUByte(){
{
+
$value = unpack("C", substr($this->data, $this->pos, 1));
$value = unpack("C", substr($this -> data, $this -> pos, 1));
+
$this->pos++;
$this -> pos++;
+
 
 
 
return $value[1];
 
return $value[1];
 
}
 
}
 
+
public function ReadFloat()
+
public function ReadFloat(){
{
+
$value = unpack("f", strrev(substr($this->data, $this->pos, 4)));
$value = unpack("f", strrev(substr($this -> data, $this -> pos, 4)));
+
$this->pos += 4;
$this -> pos += 4;
+
 
 
 
return $value[1];
 
return $value[1];
 
}
 
}
 
 
public function ReadUInt32()
+
public function ReadUInt32(){
{
+
$value = unpack("N", substr($this->data, $this->pos, 4));
$value = unpack("N", substr($this -> data, $this -> pos, 4));
+
$this->pos += 4;
$this -> pos += 4;
+
 
 
 
return $value[1];
 
return $value[1];
 
}
 
}
 
 
public function ReadUInt16()
+
public function ReadUInt16(){
{
+
$value = unpack("n", substr($this->data, $this->pos, 2));
$value = unpack("n", substr($this -> data, $this -> pos, 2));
+
$this->pos += 2;
$this -> pos += 2;
+
 
 
 
return $value[1];
 
return $value[1];
 
}
 
}
 
 
+
public function ReadOctets(){
public function ReadOctets()
+
$length = $this->ReadCUInt32();
{
+
$value = unpack("H*", substr($this->data, $this->pos, $length));
$length = $this -> ReadCUInt32();
+
$this->pos += $length;
+
$value = unpack("H*", substr($this -> data, $this -> pos, $length));
+
$this -> pos += $length;
+
 
 
 
return $value[1];
 
return $value[1];
 
}
 
}
 
 
public function ReadUString()
+
public function ReadUString(){
{
+
$length = $this->ReadCUInt32();
$length = $this -> ReadCUInt32();
+
+
$value = iconv("UTF-16", "UTF-8", substr($this->data, $this->pos, $length)); // LE?
$value = iconv("UTF-16", "UTF-8", substr($this -> data, $this -> pos, $length)); // LE?
+
$this->pos += $length;
$this -> pos += $length;
+
 
 
 
return $value;
 
return $value;
 
}
 
}
 
 
public function ReadPacketInfo()
+
public function ReadPacketInfo(){
{
+
$packetinfo['Opcode'] = $this->ReadCUInt32();
$packetinfo['Opcode'] = $this -> ReadCUInt32();
+
$packetinfo['Length'] = $this->ReadCUInt32();
$packetinfo['Length'] = $this -> ReadCUInt32();
+
 
return $packetinfo;
 
return $packetinfo;
 
}
 
}
 
 
public function Seek($value)
+
public function Seek($value){
{
+
$this->pos += $value;
$this -> pos += $value;
+
 
}
 
}
 
 
public function ReadCUInt32()
+
public function ReadCUInt32(){
{
+
$value = unpack("C", substr($this->data, $this->pos, 1));
$value = unpack("C", substr($this -> data, $this -> pos, 1));
+
 
$value = $value[1];
 
$value = $value[1];
$this -> pos++;
+
$this->pos++;
 
 
switch($value & 0xE0)
+
switch ($value & 0xE0) {
{
+
 
case 0xE0:
 
case 0xE0:
$value = unpack("N", substr($this -> data, $this -> pos, 4));
+
$value = unpack("N", substr($this->data, $this->pos, 4));
 
$value = $value[1];
 
$value = $value[1];
$this -> pos += 4;
+
$this->pos += 4;
 
break;
 
break;
 
case 0xC0:
 
case 0xC0:
$value = unpack("N", substr($this -> data, $this -> pos - 1, 4));
+
$value = unpack("N", substr($this->data, $this->pos - 1, 4));
 
$value = $value[1] & 0x1FFFFFFF;
 
$value = $value[1] & 0x1FFFFFFF;
$this -> pos += 3;
+
$this->pos += 3;
 
break;
 
break;
 
case 0x80:
 
case 0x80:
 
case 0xA0:
 
case 0xA0:
$value = unpack("n", substr($this -> data, $this -> pos - 1, 2));
+
$value = unpack("n", substr($this->data, $this->pos - 1, 2));
 
$value = $value[1] & 0x3FFF;
 
$value = $value[1] & 0x3FFF;
$this -> pos++;
+
$this->pos++;
 
break;
 
break;
 
}
 
}
Строка 113: Строка 99:
 
}
 
}
 
}
 
}
 
+
class WritePacket {
class WritePacket
+
{
+
 
public $request, $response, $passestablished = false, $getresponse = true;
 
public $request, $response, $passestablished = false, $getresponse = true;
 
 
public function WriteBytes($value)
+
public function WriteBytes($value){
{
+
$this->request .= $value;
$this -> request .= $value;
+
 
}
 
}
 
 
public function WriteUByte($value)
+
public function WriteUByte($value){
{
+
$this->request .= pack("C", $value);
$this -> request .= pack("C", $value);
+
 
}
 
}
 
 
public function WriteFloat($value)
+
public function WriteFloat($value){
{
+
$this->request .= strrev(pack("f", $value));
$this -> request .= strrev(pack("f", $value));
+
 
}
 
}
 
 
public function WriteUInt32($value)
+
public function WriteUInt32($value){
{
+
$this->request .= pack("N", $value);
$this -> request .= pack("N", $value);
+
 
}
 
}
 
 
public function WriteUInt16($value)
+
public function WriteUInt16($value){
{
+
$this->request .= pack("n", $value);
$this -> request .= pack("n", $value);
+
 
}
 
}
 
 
public function WriteOctets($value)
+
public function WriteOctets($value){
{
+
 
if (ctype_xdigit($value))
 
if (ctype_xdigit($value))
 
$value = pack("H*", $value);
 
$value = pack("H*", $value);
+
$this->request .= $this->CUInt(strlen($value));
$this -> request .= $this -> CUInt(strlen($value));
+
$this->request .= $value;
$this -> request .= $value;
+
 
}
 
}
 
 
public function WriteUString($value, $coding = "UTF-16LE")
+
public function WriteUString($value, $coding = "UTF-16LE"){
{
+
 
$value = iconv("UTF-8", $coding, $value);
 
$value = iconv("UTF-8", $coding, $value);
$this -> request .= $this -> CUInt(strlen($value));
+
$this->request .= $this->CUInt(strlen($value));
$this -> request .= $value;
+
$this->request .= $value;
 
}
 
}
 
 
public function Pack($value)
+
public function Pack($value){
{
+
$this->request = $this->CUInt($value) . $this->CUInt(strlen($this->request)) . $this->request;
$this -> request = $this -> CUInt($value) . $this -> CUInt(strlen($this -> request)) . $this -> request;
+
 
}
 
}
 
 
public function Unmarshal()
+
public function Unmarshal(){
{
+
return $this->CUInt(strlen($this->request)) . $this->request;
return $this -> CUInt(strlen($this -> request)) . $this -> request;
+
 
}
 
}
 
 
public function Send($address, $port)
+
public function Send($address, $port){
{
+
 
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
 
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
 
 
if (socket_connect($socket, $address, $port))
+
if (socket_connect($socket, $address, $port)) {
{
+
 
socket_set_block($socket);
 
socket_set_block($socket);
 
if ($this -> passestablished)
 
socket_recv($socket, $trash, 1024, 0);
 
 
 
$send = socket_send($socket, $this -> request, 131072, 0);
+
if ($this->passestablished)
 +
socket_recv($socket, $trash, 1024, 0);
 +
 +
$send = socket_send($socket, $this->request, 131072, 0);
 +
 +
if ($this->getresponse)
 +
$recv = socket_recv($socket, $this->response, 131072, 0);
 
 
if ($this -> getresponse)
 
$recv = socket_recv($socket, $this -> response, 131072, 0);
 
 
 
socket_set_nonblock($socket);
 
socket_set_nonblock($socket);
 
socket_close($socket);
 
socket_close($socket);
 
 
 
return true;
 
return true;
}
+
} else return false;
else
+
return false;
+
 
}
 
}
 
 
public function WriteCUInt32($value)
+
public function WriteCUInt32($value){
{
+
$this->request .= $this->CUInt($value);
$this -> request .= $this -> CUInt($value);
+
 
}
 
}
 
 
private function CUInt($value)
+
private function CUInt($value){
{
+
 
if ($value <= 0x7F)
 
if ($value <= 0x7F)
 
return pack("C", $value);
 
return pack("C", $value);

Версия 09:25, 7 июня 2018

><?
// "Packet Class PW".
// By JonMagon (Desmond Hume)
class ReadPacket {
	public $data, $pos;
 
	function __construct($obj = null){
		$this->data = $obj->response;
	}
 
	public function ReadBytes($length){
		$value = substr($this->data, $this->pos, $length);
		$this->pos += $length;
 
		return $value;
	}
 
	public function ReadUByte(){
		$value = unpack("C", substr($this->data, $this->pos, 1));
		$this->pos++;
 
		return $value[1];
	}
 
	public function ReadFloat(){
		$value = unpack("f", strrev(substr($this->data, $this->pos, 4)));
		$this->pos += 4;
 
		return $value[1];
	}
 
	public function ReadUInt32(){
		$value = unpack("N", substr($this->data, $this->pos, 4));
		$this->pos += 4;
 
		return $value[1];
	}
 
	public function ReadUInt16(){
		$value = unpack("n", substr($this->data, $this->pos, 2));
		$this->pos += 2;
 
		return $value[1];
	}
 
	public function ReadOctets(){
		$length = $this->ReadCUInt32();
		$value  = unpack("H*", substr($this->data, $this->pos, $length));
		$this->pos += $length;
 
		return $value[1];
	}
 
	public function ReadUString(){
		$length = $this->ReadCUInt32();
 
		$value  = iconv("UTF-16", "UTF-8", substr($this->data, $this->pos, $length)); // LE?
		$this->pos += $length;
 
		return $value;
	}
 
	public function ReadPacketInfo(){
		$packetinfo['Opcode'] = $this->ReadCUInt32();
		$packetinfo['Length'] = $this->ReadCUInt32();
 
		return $packetinfo;
	}
 
	public function Seek($value){
		$this->pos += $value;
	}
 
	public function ReadCUInt32(){
		$value = unpack("C", substr($this->data, $this->pos, 1));
		$value = $value[1];
		$this->pos++;
 
		switch ($value & 0xE0) {
			case 0xE0:
				$value = unpack("N", substr($this->data, $this->pos, 4));
				$value = $value[1];
				$this->pos += 4;
				break;
			case 0xC0:
				$value = unpack("N", substr($this->data, $this->pos - 1, 4));
				$value = $value[1] & 0x1FFFFFFF;
				$this->pos += 3;
				break;
			case 0x80:
			case 0xA0:
				$value = unpack("n", substr($this->data, $this->pos - 1, 2));
				$value = $value[1] & 0x3FFF;
				$this->pos++;
				break;
		}
 
		return $value;
	}
}
class WritePacket {
	public $request, $response, $passestablished = false, $getresponse = true;
 
	public function WriteBytes($value){
		$this->request .= $value;
	}
 
	public function WriteUByte($value){
		$this->request .= pack("C", $value);
	}
 
	public function WriteFloat($value){
		$this->request .= strrev(pack("f", $value));
	}
 
	public function WriteUInt32($value){
		$this->request .= pack("N", $value);
	}
 
	public function WriteUInt16($value){
		$this->request .= pack("n", $value);
	}
 
	public function WriteOctets($value){
		if (ctype_xdigit($value))
			$value = pack("H*", $value);
		$this->request .= $this->CUInt(strlen($value));
		$this->request .= $value;
	}
 
	public function WriteUString($value, $coding = "UTF-16LE"){
		$value = iconv("UTF-8", $coding, $value);
		$this->request .= $this->CUInt(strlen($value));
		$this->request .= $value;
	}
 
	public function Pack($value){
		$this->request = $this->CUInt($value) . $this->CUInt(strlen($this->request)) . $this->request;
	}
 
	public function Unmarshal(){
		return $this->CUInt(strlen($this->request)) . $this->request;
	}
 
	public function Send($address, $port){
		$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
 
		if (socket_connect($socket, $address, $port)) {
			socket_set_block($socket);
 
			if ($this->passestablished)
				socket_recv($socket, $trash, 1024, 0);
 
			$send = socket_send($socket, $this->request, 131072, 0);
 
			if ($this->getresponse)
				$recv = socket_recv($socket, $this->response, 131072, 0);
 
			socket_set_nonblock($socket);
			socket_close($socket);
 
			return true;
		} else return false;
	}
 
	public function WriteCUInt32($value){
		$this->request .= $this->CUInt($value);
	}
 
	private function CUInt($value){
		if ($value <= 0x7F)
			return pack("C", $value);
		else if ($value <= 0x3FFF)
			return pack("n", ($value | 0x8000));
		else if ($value <= 0x1FFFFFFF)
			return pack("N", ($value | 0xC0000000));
		else
			return pack("C", 0xE0) . pack("N", $value);
	}
}
?>