uzbek-plus/b12/vncshot.py

38 lines
1.5 KiB
Python

#!/usr/bin/env python3
# Minimal RFB 3.8 client (security None, Raw encoding, 32bpp) -> PPM. Usage: vncshot.py HOST PORT OUT.ppm
import socket, struct, sys
h, p, out = sys.argv[1], int(sys.argv[2]), sys.argv[3]
s = socket.create_connection((h, p), 10)
def rx(n):
b = b''
while len(b) < n:
c = s.recv(n - len(b))
if not c: raise SystemExit('eof')
b += c
return b
ver = rx(12); s.sendall(b'RFB 003.008\n')
n = rx(1)[0]; types = rx(n)
if 1 not in types: raise SystemExit('no None auth: %r' % types)
s.sendall(b'\x01'); assert struct.unpack('>I', rx(4))[0] == 0
s.sendall(b'\x01')
w, hh = struct.unpack('>HH', rx(4)); rx(16); name = rx(struct.unpack('>I', rx(4))[0])
s.sendall(struct.pack('>BxxxBBBBHHHBBBxxx', 0, 32, 24, 0, 1, 255, 255, 255, 16, 8, 0))
s.sendall(struct.pack('>BxHi', 2, 1, 0))
s.sendall(struct.pack('>BBHHHH', 3, 0, 0, 0, w, hh))
img = bytearray(w * hh * 3)
got = 0
while got < w * hh:
t = rx(1)[0]
if t != 0: raise SystemExit('msg %d' % t)
rx(1); nr = struct.unpack('>H', rx(2))[0]
for _ in range(nr):
x, y, rw, rh, enc = struct.unpack('>HHHHi', rx(12))
px = rx(rw * rh * 4)
for j in range(rh):
for i in range(rw):
v = px[(j * rw + i) * 4:(j * rw + i) * 4 + 4]
o = ((y + j) * w + x + i) * 3
img[o:o + 3] = bytes((v[2], v[1], v[0]))
got += rw * rh
open(out, 'wb').write(b'P6 %d %d 255\n' % (w, hh) + img)
print('server', ver.strip().decode(), 'name', name.decode(), 'size %dx%d' % (w, hh))