-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpackets.php
124 lines (122 loc) · 2.54 KB
/
packets.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php /** @noinspection PhpUnhandledExceptionInspection */
if(empty($argv[1]) || empty($argv[2]))
{
die("Syntax: packets <recipient: client or server> <file>\n");
}
require __DIR__."/_autoload.php";
use Phpcraft\
{Connection, Packet\ClientboundPacketId, Packet\PacketId, Packet\ServerboundPacketId, Versions};
echo "Phpcraft Packet Dump Reader\n\n";
if(!in_array($argv[1], [
"client",
"server"
]))
{
die("Invalid recipient '".$argv[1]."', expected 'client' or 'server'.\n");
}
$fh = fopen($argv[2], "r");
$con = new Connection(-1, $fh);
if(!($pv = $con->readPacket()) || strlen($con->read_buffer) > 0)
{
die("Failed to read protocol version.\nWrite 0x05 0xff 0xff 0xff 0xff 0x0f to the beginning of the file so protocol version -1 is detected.\n");
}
if($range = Versions::protocolToRange($pv))
{
echo "Detected Minecraft $range (protocol version $pv).\n";
}
else
{
echo "Detected unsupported protocol version {$pv}.\n";
}
function processBatch()
{
global $id_count, $last_id, $last_name, $total_size;
if($id_count == 1)
{
echo "1x ".convertPacket($last_id, $last_name)." with {$total_size} B of data\n";
}
else
{
echo $id_count."x ".convertPacket($last_id, $last_name)." with {$total_size} B (avg. ".round($total_size / $id_count)." B) of data\n";
}
}
function convertPacket(int $id, string $name)
{
if($name)
{
return $name." (0x".dechex($id)." | {$id})";
}
else
{
return "0x".dechex($id)." ({$id})";
}
}
$con->protocol_version = $pv;
$last_id = null;
$last_name = "";
$id_count = 0;
$total_size = 0;
while(($id = $con->readPacket()) !== false)
{
$size = strlen($con->read_buffer);
if($argv[1] == "client")
{
$packetId = ClientboundPacketId::getById($id, $pv);
}
else
{
$packetId = ServerboundPacketId::getById($id, $pv);
}
if($packetId)
{
$name = $packetId->name;
}
else
{
$name = "";
}
if($size == 0)
{
die(convertPacket($id, $name)." has no data.\n");
}
if($packetId instanceof PacketId && ($packet = $packetId->getInstance($con)))
{
if($last_id)
{
processBatch();
$last_id = false;
$id_count = 0;
$total_size = 0;
}
echo $packet->__toString()."\n";
}
else if($last_id === $id)
{
$id_count++;
$total_size += $size;
}
else
{
if($last_id)
{
processBatch();
}
$last_id = $id;
$last_name = $name;
$id_count = 1;
$total_size = $size;
}
}
if($last_id)
{
processBatch();
}
if(strlen(stream_get_contents($fh)) > 0)
{
echo "Error: There was still some data left in the stream despite having finished reading.\n";
}
else
{
echo "This seems to have been a valid packet dump file.\n";
}
fclose($fh);