2012-10-26 12:31:47 +02:00
|
|
|
import struct
|
2012-10-26 15:09:16 +02:00
|
|
|
import types
|
2012-11-03 15:08:39 +01:00
|
|
|
from io import BytesIO
|
|
|
|
from pynbt import NBTFile
|
2012-10-26 12:31:47 +02:00
|
|
|
|
2012-12-31 03:20:06 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readBoolean(FileObject):
|
|
|
|
return struct.unpack('?', FileObject.read(1))[0]
|
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readByte(FileObject):
|
2012-11-27 16:00:39 +01:00
|
|
|
return struct.unpack('>b', FileObject.read(1))[0]
|
2012-10-26 12:31:47 +02:00
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readUnsignedByte(FileObject):
|
2012-11-27 16:00:39 +01:00
|
|
|
return struct.unpack('>B', FileObject.read(1))[0]
|
2012-10-26 12:31:47 +02:00
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readShort(FileObject):
|
2012-11-27 16:00:39 +01:00
|
|
|
return struct.unpack('>h', FileObject.read(2))[0]
|
2012-10-26 12:31:47 +02:00
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readUnsignedShort(FileObject):
|
2012-11-27 16:00:39 +01:00
|
|
|
return struct.unpack('>H', FileObject.read(2))[0]
|
2012-10-26 12:31:47 +02:00
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readInt(FileObject):
|
2012-11-27 16:00:39 +01:00
|
|
|
return struct.unpack('>i', FileObject.read(4))[0]
|
2012-10-26 12:31:47 +02:00
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readFloat(FileObject):
|
2012-11-27 16:00:39 +01:00
|
|
|
return struct.unpack('>f', FileObject.read(4))[0]
|
2012-10-26 12:31:47 +02:00
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readLong(FileObject):
|
2012-11-27 16:00:39 +01:00
|
|
|
return struct.unpack('>q', FileObject.read(8))[0]
|
2012-10-26 12:31:47 +02:00
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readDouble(FileObject):
|
2012-11-27 16:00:39 +01:00
|
|
|
return struct.unpack('>d', FileObject.read(8))[0]
|
2012-10-26 12:31:47 +02:00
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readByteArray(FileObject, length):
|
|
|
|
return struct.unpack(str(length) + "s", FileObject.read(length))[0]
|
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readString(FileObject):
|
|
|
|
length = readShort(FileObject) * 2
|
2013-01-31 16:42:47 +01:00
|
|
|
return unicode(FileObject.read(length), "utf-16be")
|
2012-10-26 12:31:47 +02:00
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 15:09:16 +02:00
|
|
|
def sendBoolean(socket, value):
|
|
|
|
assert type(value) is types.BooleanType, "value is not a boolean: %r" % value
|
|
|
|
socket.send(struct.pack('?', value))
|
2012-12-25 21:38:02 +01:00
|
|
|
|
|
|
|
|
2012-10-26 15:09:16 +02:00
|
|
|
def sendByte(socket, value):
|
2012-11-27 16:00:39 +01:00
|
|
|
socket.send(struct.pack('>b', value))
|
2012-12-25 21:38:02 +01:00
|
|
|
|
|
|
|
|
2012-10-26 15:09:16 +02:00
|
|
|
def sendUnsignedByte(socket, value):
|
2012-11-27 16:00:39 +01:00
|
|
|
socket.send(struct.pack('>B', value))
|
2012-12-25 21:38:02 +01:00
|
|
|
|
|
|
|
|
2012-10-26 15:09:16 +02:00
|
|
|
def sendShort(socket, value):
|
2012-11-27 16:00:39 +01:00
|
|
|
socket.send(struct.pack('>h', value))
|
2012-12-25 21:38:02 +01:00
|
|
|
|
|
|
|
|
2012-10-26 15:09:16 +02:00
|
|
|
def sendUnsignedShort(socket, value):
|
2012-11-27 16:00:39 +01:00
|
|
|
socket.send(struct.pack('>H', value))
|
2012-12-25 21:38:02 +01:00
|
|
|
|
|
|
|
|
2012-10-26 15:09:16 +02:00
|
|
|
def sendInt(socket, value):
|
|
|
|
assert type(value) is types.IntType, "value is not an integer: %r" % value
|
2012-11-27 16:00:39 +01:00
|
|
|
socket.send(struct.pack('>i', value))
|
2012-10-26 15:09:16 +02:00
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 15:09:16 +02:00
|
|
|
def sendFloat(socket, value):
|
2012-11-27 16:00:39 +01:00
|
|
|
socket.send(struct.pack('>f', value))
|
2012-12-25 21:38:02 +01:00
|
|
|
|
|
|
|
|
2012-10-26 15:09:16 +02:00
|
|
|
def sendLong(socket, value):
|
2012-11-27 16:00:39 +01:00
|
|
|
socket.send(struct.pack('>q', value))
|
2012-12-25 21:38:02 +01:00
|
|
|
|
|
|
|
|
2012-10-26 15:09:16 +02:00
|
|
|
def sendDouble(socket, value):
|
2012-12-04 16:47:29 +01:00
|
|
|
socket.send(struct.pack('>d', value))
|
2012-12-25 21:38:02 +01:00
|
|
|
|
|
|
|
|
2012-10-26 15:09:16 +02:00
|
|
|
def sendString(socket, value):
|
2013-01-31 16:42:47 +01:00
|
|
|
value = unicode(value).encode('utf-16be')
|
|
|
|
socket.send(struct.pack('>h', len(value) / 2))
|
|
|
|
socket.send(value)
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 15:09:16 +02:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readEntityMetadata(FileObject):
|
|
|
|
metadata = {}
|
2012-10-29 14:05:17 +01:00
|
|
|
byte = readUnsignedByte(FileObject)
|
2012-10-26 12:31:47 +02:00
|
|
|
while byte != 127:
|
|
|
|
index = byte & 0x1F # Lower 5 bits
|
2012-12-25 21:38:02 +01:00
|
|
|
ty = byte >> 5 # Upper 3 bits
|
2012-10-29 14:05:17 +01:00
|
|
|
if ty == 0: val = readByte(FileObject)
|
|
|
|
if ty == 1: val = readShort(FileObject)
|
2012-10-26 12:31:47 +02:00
|
|
|
if ty == 2: val = readInt(FileObject)
|
2012-10-29 14:05:17 +01:00
|
|
|
if ty == 3: val = readFloat(FileObject)
|
2012-12-25 21:38:02 +01:00
|
|
|
if ty == 4:
|
2012-10-29 14:05:17 +01:00
|
|
|
val = readString(FileObject)
|
2012-10-26 12:31:47 +02:00
|
|
|
if ty == 5:
|
|
|
|
val = {}
|
2012-10-29 14:05:17 +01:00
|
|
|
val["id"] = readShort(FileObject)
|
2012-10-26 12:31:47 +02:00
|
|
|
if (val["id"] != -1):
|
2012-12-25 21:38:02 +01:00
|
|
|
val["count"] = readByte(FileObject)
|
2012-10-29 14:05:17 +01:00
|
|
|
val["damage"] = readShort(FileObject)
|
2012-11-19 19:56:51 +01:00
|
|
|
nbtDataLength = readShort(FileObject)
|
|
|
|
if (nbtDataLength != -1):
|
2012-12-25 21:38:02 +01:00
|
|
|
val["NBT"] = NBTFile(BytesIO(readByteArray(FileObject, nbtDataLength)),
|
|
|
|
compression=NBTFile.Compression.GZIP)
|
2012-10-26 12:31:47 +02:00
|
|
|
if ty == 6:
|
|
|
|
val = []
|
|
|
|
for i in range(3):
|
|
|
|
val.append(readInt(FileObject))
|
|
|
|
metadata[index] = (ty, val)
|
2012-10-29 14:05:17 +01:00
|
|
|
byte = readUnsignedByte(FileObject)
|
2012-10-26 12:31:47 +02:00
|
|
|
return metadata
|
|
|
|
|
2012-12-25 21:38:02 +01:00
|
|
|
|
2012-10-26 12:31:47 +02:00
|
|
|
def readSlotData(FileObject):
|
2012-10-29 14:05:17 +01:00
|
|
|
BlockID = readShort(FileObject)
|
2012-12-25 21:38:02 +01:00
|
|
|
if (BlockID != -1):
|
2012-10-29 14:05:17 +01:00
|
|
|
ItemCount = readByte(FileObject)
|
|
|
|
Damage = readShort(FileObject)
|
|
|
|
MetadataLength = readShort(FileObject)
|
2012-12-25 21:38:02 +01:00
|
|
|
if (MetadataLength != -1):
|
2012-10-29 14:05:17 +01:00
|
|
|
ByteArray = readByteArray(FileObject, MetadataLength)
|
2012-11-03 15:08:39 +01:00
|
|
|
NBTData = NBTFile(BytesIO(ByteArray), compression=NBTFile.Compression.GZIP)
|
2012-12-25 21:38:02 +01:00
|
|
|
return {'BlockID': BlockID,
|
|
|
|
'ItemCount': ItemCount,
|
|
|
|
'Damage': Damage,
|
|
|
|
'Data': NBTData
|
2012-12-26 16:23:47 +01:00
|
|
|
}
|
2012-12-25 21:38:02 +01:00
|
|
|
return {'BlockID': BlockID,
|
|
|
|
'ItemCount': ItemCount,
|
|
|
|
'Damage': Damage
|
2012-12-26 16:23:47 +01:00
|
|
|
}
|
2012-12-25 21:38:02 +01:00
|
|
|
return {'BlockID': -1,
|
|
|
|
'ItemCount': 0
|
2013-01-31 16:42:47 +01:00
|
|
|
}
|