mirror of
https://github.com/ammaraskar/pyCraft.git
synced 2025-01-07 16:37:59 +01:00
Update to 1.3 protocol, sha1 digest still needs work
This commit is contained in:
parent
fb7b22b771
commit
f18c6496b8
22
Utils.py
Normal file
22
Utils.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import array
|
||||||
|
|
||||||
|
def stringToByteArray(string):
|
||||||
|
return array.array('B', string.decode("hex"))
|
||||||
|
|
||||||
|
def TwosCompliment(hash):
|
||||||
|
hash = array.array('B', hash.decode("hex"))
|
||||||
|
carry = True
|
||||||
|
for i in range((hash.__len__() - 1), 0, -1):
|
||||||
|
if(carry):
|
||||||
|
carry = hash[i] == 0xFF
|
||||||
|
hash[i] += 1
|
||||||
|
return hash
|
||||||
|
|
||||||
|
def trimStart(string, character):
|
||||||
|
for c in string:
|
||||||
|
if (c == character):
|
||||||
|
string = string[1:]
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
return string
|
||||||
|
|
@ -2,10 +2,12 @@ import socket
|
|||||||
import wx
|
import wx
|
||||||
import PacketListenerManager
|
import PacketListenerManager
|
||||||
import urllib2
|
import urllib2
|
||||||
|
import urllib
|
||||||
import traceback
|
import traceback
|
||||||
import threading
|
import threading
|
||||||
import hashlib
|
import hashlib
|
||||||
import string
|
import string
|
||||||
|
import Utils
|
||||||
from networking import PacketSenderManager
|
from networking import PacketSenderManager
|
||||||
from Crypto.Random import _UserFriendlyRNG
|
from Crypto.Random import _UserFriendlyRNG
|
||||||
from Crypto.Util import asn1
|
from Crypto.Util import asn1
|
||||||
@ -65,28 +67,34 @@ class ServerConnection(threading.Thread):
|
|||||||
packetFD = PacketListenerManager.handleFD(self.FileObject)
|
packetFD = PacketListenerManager.handleFD(self.FileObject)
|
||||||
|
|
||||||
#Import the server's public key
|
#Import the server's public key
|
||||||
print "#Import the server's public key"
|
|
||||||
self.pubkey = RSA.importKey(packetFD['Public Key'])
|
self.pubkey = RSA.importKey(packetFD['Public Key'])
|
||||||
|
|
||||||
#Generate a 16 byte (128 bit) shared secret
|
#Generate a 16 byte (128 bit) shared secret
|
||||||
print "#Generate a 16 byte (128 bit) shared secret"
|
|
||||||
self.sharedSecret = _UserFriendlyRNG.get_random_bytes(16)
|
self.sharedSecret = _UserFriendlyRNG.get_random_bytes(16)
|
||||||
|
|
||||||
#Grab the server id
|
#Grab the server id
|
||||||
print "#Grab the server id"
|
|
||||||
serverid = packetFD['ServerID']
|
|
||||||
sha1 = hashlib.sha1()
|
sha1 = hashlib.sha1()
|
||||||
sha1.update(serverid)
|
sha1.update(packetFD['ServerID'])
|
||||||
sha1.update(str(self.sharedSecret))
|
sha1.update(self.sharedSecret)
|
||||||
sha1.update(str(self.pubkey))
|
sha1.update(packetFD['Public Key'])
|
||||||
serverid = sha1.hexdigest()
|
#lovely java style hex digest by SirCmpwn
|
||||||
|
sha1 = sha1.hexdigest()
|
||||||
|
negative = (int(sha1[0], 16) & 0x80) == 0x80
|
||||||
|
if(negative):
|
||||||
|
sha1 = Utils.TwosCompliment(sha1.digest())
|
||||||
|
#else:
|
||||||
|
# sha1 = sha1.digest()
|
||||||
|
Utils.trimStart(str(sha1), '0')
|
||||||
|
if (negative):
|
||||||
|
sha1 = '-' + sha1
|
||||||
|
serverid = sha1
|
||||||
|
|
||||||
#Authenticate the server from sessions.minecraft.net
|
#Authenticate the server from sessions.minecraft.net
|
||||||
print "#Authenticate the server from sessions.minecraft.net"
|
|
||||||
if(serverid != '-'):
|
if(serverid != '-'):
|
||||||
try:
|
try:
|
||||||
#Open up the url with the appropriate get parameters
|
#Open up the url with the appropriate get parameters
|
||||||
url = "http://session.minecraft.net/game/joinserver.jsp?user=" + self.username + "&sessionId=" + self.sessionID + "&serverId=" + serverid
|
url = "http://session.minecraft.net/game/joinserver.jsp?user=" + self.username + "&sessionId=" + self.sessionID + "&serverId=" + serverid
|
||||||
|
print url
|
||||||
response = urllib2.urlopen(url).read()
|
response = urllib2.urlopen(url).read()
|
||||||
|
|
||||||
if(response != "OK"):
|
if(response != "OK"):
|
||||||
@ -99,20 +107,16 @@ class ServerConnection(threading.Thread):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
#Success \o/ We can now begin sending our stuff to the server
|
#Success \o/ We can now begin sending our stuff to the server
|
||||||
print "#Success \o/ We can now begin sending our stuff to the server"
|
|
||||||
|
|
||||||
#Instantiate our main packet listener
|
#Instantiate our main packet listener
|
||||||
print "#Instantiate our main packet listener"
|
|
||||||
PacketListener(self, self.window, self.socket, self.FileObject).start()
|
PacketListener(self, self.window, self.socket, self.FileObject).start()
|
||||||
|
|
||||||
#Encrypt the verification token from earlier along with our shared secret with the server's rsa key
|
#Encrypt the verification token from earlier along with our shared secret with the server's rsa key
|
||||||
print "#Encrypt the verification token from earlier along with our shared secret"
|
|
||||||
self.RSACipher = PKCS1_v1_5.new(self.pubkey)
|
self.RSACipher = PKCS1_v1_5.new(self.pubkey)
|
||||||
encryptedSanityToken = self.RSACipher.encrypt(str(packetFD['Token']))
|
encryptedSanityToken = self.RSACipher.encrypt(str(packetFD['Token']))
|
||||||
encryptedSharedSecret = self.RSACipher.encrypt(str(self.sharedSecret))
|
encryptedSharedSecret = self.RSACipher.encrypt(str(self.sharedSecret))
|
||||||
|
|
||||||
#Send out a a packet FC to the server
|
#Send out a a packet FC to the server
|
||||||
print "#Send out a a packet FC to the server"
|
|
||||||
PacketSenderManager.sendFC(self.socket, encryptedSharedSecret, encryptedSanityToken)
|
PacketSenderManager.sendFC(self.socket, encryptedSharedSecret, encryptedSanityToken)
|
||||||
|
|
||||||
#GUI handling
|
#GUI handling
|
||||||
@ -151,7 +155,9 @@ class EncryptedFileObjectHandler():
|
|||||||
self.cipher = cipher
|
self.cipher = cipher
|
||||||
|
|
||||||
def read(self, length):
|
def read(self, length):
|
||||||
return self.cipher.decrypt(self.fileobject.read(length))
|
rawData = self.fileobject.read(length)
|
||||||
|
unencryptedData = self.cipher.decrypt(rawData)
|
||||||
|
return unencryptedData
|
||||||
|
|
||||||
class EncryptedSocketObjectHandler():
|
class EncryptedSocketObjectHandler():
|
||||||
|
|
||||||
@ -161,9 +167,6 @@ class EncryptedSocketObjectHandler():
|
|||||||
|
|
||||||
def send(self, stuff):
|
def send(self, stuff):
|
||||||
self.socket.send(self.cipher.encrypt(stuff))
|
self.socket.send(self.cipher.encrypt(stuff))
|
||||||
|
|
||||||
def recv(self, length):
|
|
||||||
return self.cipher.decrypt(self.socket.recv(length))
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
@ -180,14 +183,13 @@ class PacketListener(threading.Thread):
|
|||||||
|
|
||||||
def enableEncryption(self):
|
def enableEncryption(self):
|
||||||
#Create an AES cipher from the previously obtained public key
|
#Create an AES cipher from the previously obtained public key
|
||||||
print "#Create an AES cipher from the previously generated shared secret"
|
self.cipher = AES.new(self.connection.sharedSecret, AES.MODE_CFB, IV=self.connection.sharedSecret)
|
||||||
self.cipher = AES.new(str(self.connection.sharedSecret), AES.MODE_CFB, IV=self.connection.sharedSecret, segment_size=8)
|
self.decipher = AES.new(self.connection.sharedSecret, AES.MODE_CFB, IV=self.connection.sharedSecret)
|
||||||
self.rawsocket = self.socket
|
self.rawsocket = self.socket
|
||||||
self.socket = EncryptedSocketObjectHandler(self.rawsocket, self.cipher)
|
self.socket = EncryptedSocketObjectHandler(self.rawsocket, self.cipher)
|
||||||
self.rawFileObject = self.FileObject
|
self.rawFileObject = self.FileObject
|
||||||
self.FileObject = EncryptedFileObjectHandler(self.rawFileObject, self.cipher)
|
self.FileObject = EncryptedFileObjectHandler(self.rawFileObject, self.decipher)
|
||||||
self.encryptedConnection = True
|
self.encryptedConnection = True
|
||||||
print "#Encryption enabled"
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
@ -202,11 +204,11 @@ class PacketListener(threading.Thread):
|
|||||||
print "Ping timeout"
|
print "Ping timeout"
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
break
|
break
|
||||||
print hex(ord(response))
|
|
||||||
if(response == "\x00"):
|
if(response == "\x00"):
|
||||||
PacketListenerManager.handle00(self.FileObject, self.socket)
|
PacketListenerManager.handle00(self.FileObject, self.socket)
|
||||||
elif(response == "\x01"):
|
elif(response == "\x01"):
|
||||||
PacketListenerManager.handle01(self.FileObject)
|
packet01 = PacketListenerManager.handle01(self.FileObject)
|
||||||
|
print "Logged in \o/ Received an entity id of " + str(packet01['EntityID'])
|
||||||
elif(response == "\x03"):
|
elif(response == "\x03"):
|
||||||
message = PacketListenerManager.handle03(self.FileObject)
|
message = PacketListenerManager.handle03(self.FileObject)
|
||||||
if(self.connection.NoGUI):
|
if(self.connection.NoGUI):
|
||||||
@ -275,8 +277,6 @@ class PacketListener(threading.Thread):
|
|||||||
PacketListenerManager.handle2A(self.FileObject)
|
PacketListenerManager.handle2A(self.FileObject)
|
||||||
elif(response == "\x2B"):
|
elif(response == "\x2B"):
|
||||||
PacketListenerManager.handle2B(self.FileObject)
|
PacketListenerManager.handle2B(self.FileObject)
|
||||||
elif(response == "\x32"):
|
|
||||||
PacketListenerManager.handle32(self.FileObject)
|
|
||||||
elif(response == "\x33"):
|
elif(response == "\x33"):
|
||||||
PacketListenerManager.handle33(self.FileObject)
|
PacketListenerManager.handle33(self.FileObject)
|
||||||
elif(response == "\x34"):
|
elif(response == "\x34"):
|
||||||
@ -285,10 +285,16 @@ class PacketListener(threading.Thread):
|
|||||||
PacketListenerManager.handle35(self.FileObject)
|
PacketListenerManager.handle35(self.FileObject)
|
||||||
elif(response == "\x36"):
|
elif(response == "\x36"):
|
||||||
PacketListenerManager.handle36(self.FileObject)
|
PacketListenerManager.handle36(self.FileObject)
|
||||||
|
elif(response == "\x37"):
|
||||||
|
PacketListenerManager.handle37(self.FileObject)
|
||||||
|
elif(response == "\x38"):
|
||||||
|
PacketListenerManager.handle38(self.FileObject)
|
||||||
elif(response == "\x3C"):
|
elif(response == "\x3C"):
|
||||||
PacketListenerManager.handle3C(self.FileObject)
|
PacketListenerManager.handle3C(self.FileObject)
|
||||||
elif(response == "\x3D"):
|
elif(response == "\x3D"):
|
||||||
PacketListenerManager.handle3D(self.FileObject)
|
PacketListenerManager.handle3D(self.FileObject)
|
||||||
|
elif(response == "\x3E"):
|
||||||
|
PacketListenerManager.handle3E(self.FileObject)
|
||||||
elif(response == "\x46"):
|
elif(response == "\x46"):
|
||||||
PacketListenerManager.handle46(self.FileObject)
|
PacketListenerManager.handle46(self.FileObject)
|
||||||
elif(response == "\x47"):
|
elif(response == "\x47"):
|
||||||
@ -300,7 +306,7 @@ class PacketListener(threading.Thread):
|
|||||||
elif(response == "\x67"):
|
elif(response == "\x67"):
|
||||||
PacketListenerManager.handle67(self.FileObject)
|
PacketListenerManager.handle67(self.FileObject)
|
||||||
elif(response == "\x68"):
|
elif(response == "\x68"):
|
||||||
PacketListenerManager.handle68(self.FileObject)
|
print PacketListenerManager.handle68(self.FileObject)
|
||||||
elif(response == "\x69"):
|
elif(response == "\x69"):
|
||||||
PacketListenerManager.handle69(self.FileObject)
|
PacketListenerManager.handle69(self.FileObject)
|
||||||
elif(response == "\x6A"):
|
elif(response == "\x6A"):
|
||||||
@ -316,9 +322,11 @@ class PacketListener(threading.Thread):
|
|||||||
elif(response == "\xC8"):
|
elif(response == "\xC8"):
|
||||||
PacketListenerManager.handleC8(self.FileObject)
|
PacketListenerManager.handleC8(self.FileObject)
|
||||||
elif(response == "\xC9"):
|
elif(response == "\xC9"):
|
||||||
PacketListenerManager.handleC9(self.FileObject)
|
print PacketListenerManager.handleC9(self.FileObject)
|
||||||
elif(response == "\xCA"):
|
elif(response == "\xCA"):
|
||||||
PacketListenerManager.handleCA(self.FileObject)
|
PacketListenerManager.handleCA(self.FileObject)
|
||||||
|
elif(response == "\xCB"):
|
||||||
|
PacketListenerManager.handleCB(self.FileObject)
|
||||||
elif(response == "\xFA"):
|
elif(response == "\xFA"):
|
||||||
PacketListenerManager.handleFA(self.FileObject)
|
PacketListenerManager.handleFA(self.FileObject)
|
||||||
elif(response == "\xFC"):
|
elif(response == "\xFC"):
|
||||||
|
@ -9,8 +9,8 @@ def handle01(FileObject):
|
|||||||
Eid = struct.unpack('!i', FileObject.read(4))[0]
|
Eid = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
length = struct.unpack('!h', FileObject.read(2))[0] * 2
|
length = struct.unpack('!h', FileObject.read(2))[0] * 2
|
||||||
world = FileObject.read(length).decode('utf-16be')
|
world = FileObject.read(length).decode('utf-16be')
|
||||||
mode = struct.unpack('!i', FileObject.read(4))[0]
|
mode = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
dimension = struct.unpack('!i', FileObject.read(4))[0]
|
dimension = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
difficulty = struct.unpack('!b', FileObject.read(1))[0]
|
difficulty = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
FileObject.read(1)
|
FileObject.read(1)
|
||||||
maxplayers = struct.unpack('!B', FileObject.read(1))[0]
|
maxplayers = struct.unpack('!B', FileObject.read(1))[0]
|
||||||
@ -29,6 +29,12 @@ def handle02(FileObject):
|
|||||||
message = message.decode('utf-16be', 'strict')
|
message = message.decode('utf-16be', 'strict')
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
def handle03(FileObject):
|
||||||
|
length = struct.unpack('!h', FileObject.read(2))[0] * 2
|
||||||
|
message = FileObject.read(length)
|
||||||
|
message = message.decode('utf-16be','strict')
|
||||||
|
return message
|
||||||
|
|
||||||
def handle04(FileObject):
|
def handle04(FileObject):
|
||||||
time = struct.unpack('!q', FileObject.read(8))[0]
|
time = struct.unpack('!q', FileObject.read(8))[0]
|
||||||
return time
|
return time
|
||||||
@ -140,7 +146,6 @@ def handle14(FileObject):
|
|||||||
'curItem' : curItem,
|
'curItem' : curItem,
|
||||||
'Metadata' : metadata
|
'Metadata' : metadata
|
||||||
}
|
}
|
||||||
print toReturn
|
|
||||||
return toReturn
|
return toReturn
|
||||||
|
|
||||||
def handle15(FileObject):
|
def handle15(FileObject):
|
||||||
@ -211,6 +216,9 @@ def handle18(FileObject):
|
|||||||
Yaw = struct.unpack('!b', FileObject.read(1))[0]
|
Yaw = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
Pitch = struct.unpack('!b', FileObject.read(1))[0]
|
Pitch = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
HeadYaw = struct.unpack('!b', FileObject.read(1))[0]
|
HeadYaw = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
|
VelocityX = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
|
VelocityY = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
|
VelocityZ = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
metadata = readEntityMetadata(FileObject)
|
metadata = readEntityMetadata(FileObject)
|
||||||
|
|
||||||
return {'EntityID' : EntityID,
|
return {'EntityID' : EntityID,
|
||||||
@ -221,7 +229,10 @@ def handle18(FileObject):
|
|||||||
'Yaw' : Yaw,
|
'Yaw' : Yaw,
|
||||||
'Pitch' : Pitch,
|
'Pitch' : Pitch,
|
||||||
'HeadYaw' : HeadYaw,
|
'HeadYaw' : HeadYaw,
|
||||||
'Metadata' : metadata
|
'Metadata' : metadata,
|
||||||
|
'VelocityX' : VelocityX,
|
||||||
|
'VelocityY' : VelocityY,
|
||||||
|
'VelocityZ' : VelocityZ
|
||||||
}
|
}
|
||||||
|
|
||||||
def handle19(FileObject):
|
def handle19(FileObject):
|
||||||
@ -266,8 +277,11 @@ def handle1C(FileObject):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def handle1D(FileObject):
|
def handle1D(FileObject):
|
||||||
EntityID = struct.unpack('!i', FileObject.read(4))[0]
|
EntityArrayLength = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
return EntityID
|
Entities = []
|
||||||
|
for i in range(EntityArrayLength):
|
||||||
|
Entities.append(struct.unpack('!i', FileObject.read(4))[0])
|
||||||
|
return Entities
|
||||||
|
|
||||||
def handle1E(FileObject):
|
def handle1E(FileObject):
|
||||||
EntityID = struct.unpack('!i', FileObject.read(4))[0]
|
EntityID = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
@ -377,16 +391,6 @@ def handle2B(FileObject):
|
|||||||
'Level' : Level,
|
'Level' : Level,
|
||||||
'TotalExp' : TotalExp
|
'TotalExp' : TotalExp
|
||||||
}
|
}
|
||||||
|
|
||||||
def handle32(FileObject):
|
|
||||||
X = struct.unpack('!i', FileObject.read(4))[0]
|
|
||||||
raw = FileObject.read(4)
|
|
||||||
Z = struct.unpack('!i', raw)[0]
|
|
||||||
Mode = struct.unpack('?', FileObject.read(1))[0]
|
|
||||||
return {'x' : X,
|
|
||||||
'z' : Z,
|
|
||||||
'Mode' : Mode
|
|
||||||
}
|
|
||||||
|
|
||||||
def handle33(FileObject):
|
def handle33(FileObject):
|
||||||
X = struct.unpack('!i', FileObject.read(4))[0]
|
X = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
@ -395,7 +399,6 @@ def handle33(FileObject):
|
|||||||
PrimaryBitMap = struct.unpack('!H', FileObject.read(2))[0]
|
PrimaryBitMap = struct.unpack('!H', FileObject.read(2))[0]
|
||||||
AddBitMap = struct.unpack('!H', FileObject.read(2))[0]
|
AddBitMap = struct.unpack('!H', FileObject.read(2))[0]
|
||||||
CompressedSize = struct.unpack('!i', FileObject.read(4))[0]
|
CompressedSize = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
FileObject.read(4) #unused int
|
|
||||||
FileObject.read(CompressedSize) #not going to be deflating and using this data until I know how to :3
|
FileObject.read(CompressedSize) #not going to be deflating and using this data until I know how to :3
|
||||||
return {'x' : X,
|
return {'x' : X,
|
||||||
'z' : Z
|
'z' : Z
|
||||||
@ -416,7 +419,7 @@ def handle35(FileObject):
|
|||||||
X = struct.unpack('!i', FileObject.read(4))[0]
|
X = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
Y = struct.unpack('!b', FileObject.read(1))[0]
|
Y = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
Z = struct.unpack('!i', FileObject.read(4))[0]
|
Z = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
BlockType = struct.unpack('!b', FileObject.read(1))[0]
|
BlockType = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
BlockMetaData = struct.unpack('!b', FileObject.read(1))[0]
|
BlockMetaData = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
return {'x' : X,
|
return {'x' : X,
|
||||||
'y' : Y,
|
'y' : Y,
|
||||||
@ -431,18 +434,57 @@ def handle36(FileObject):
|
|||||||
Z = struct.unpack('!i', FileObject.read(4))[0]
|
Z = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
Byte1 = struct.unpack('!b', FileObject.read(1))[0]
|
Byte1 = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
Byte2 = struct.unpack('!b', FileObject.read(1))[0]
|
Byte2 = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
|
BlockID = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
return {'x' : X,
|
return {'x' : X,
|
||||||
'y' : Y,
|
'y' : Y,
|
||||||
'z' : Z,
|
'z' : Z,
|
||||||
'Byte1' : Byte1,
|
'Byte1' : Byte1,
|
||||||
'Byte2' : Byte2
|
'Byte2' : Byte2,
|
||||||
|
'BlockID' : BlockID
|
||||||
|
}
|
||||||
|
|
||||||
|
def handle37(FileObject):
|
||||||
|
#int - EntityID
|
||||||
|
EntityID = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
|
|
||||||
|
#int - X cord
|
||||||
|
x = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
|
|
||||||
|
#int - Y cord
|
||||||
|
y = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
|
|
||||||
|
#int - Z cord
|
||||||
|
z = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
|
|
||||||
|
#byte - Stage
|
||||||
|
DestroyedStage = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
|
return {'EntityID' : EntityID,
|
||||||
|
'x' : x,
|
||||||
|
'y' : y,
|
||||||
|
'z' : z,
|
||||||
|
'DestroyedStage' : DestroyedStage
|
||||||
|
}
|
||||||
|
|
||||||
|
def handle38(FileObject):
|
||||||
|
#short - number of chunks
|
||||||
|
ChunkCount = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
|
|
||||||
|
#int - chunk data length
|
||||||
|
ChunkDataLength = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
|
FileObject.read(ChunkDataLength) #just gonna ignore this for now
|
||||||
|
|
||||||
|
#metadata - ignoring this
|
||||||
|
for i in range(ChunkCount):
|
||||||
|
FileObject.read(12)
|
||||||
|
|
||||||
|
return {'ChunkCount' : ChunkCount
|
||||||
}
|
}
|
||||||
|
|
||||||
def handle3C(FileObject):
|
def handle3C(FileObject):
|
||||||
X = struct.unpack('!d', FileObject.read(8))[0]
|
X = struct.unpack('!d', FileObject.read(8))[0]
|
||||||
Y = struct.unpack('!d', FileObject.read(8))[0]
|
Y = struct.unpack('!d', FileObject.read(8))[0]
|
||||||
Z = struct.unpack('!d', FileObject.read(8))[0]
|
Z = struct.unpack('!d', FileObject.read(8))[0]
|
||||||
FileObject.read(4) #Unknown what this float does
|
Radius = struct.unpack('!f', FileObject.read(4))[0]
|
||||||
RecordCount = struct.unpack('!i', FileObject.read(4))[0]
|
RecordCount = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
AffectedBlocks = []
|
AffectedBlocks = []
|
||||||
for i in range((RecordCount * 3)):
|
for i in range((RecordCount * 3)):
|
||||||
@ -450,9 +492,15 @@ def handle3C(FileObject):
|
|||||||
y = struct.unpack('!b', FileObject.read(1))[0]
|
y = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
z = struct.unpack('!b', FileObject.read(1))[0]
|
z = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
AffectedBlocks.append({'x' : x, 'y' : y, 'z' : z})
|
AffectedBlocks.append({'x' : x, 'y' : y, 'z' : z})
|
||||||
return {'X' : X,
|
#---Unknown what these floats do
|
||||||
'Y' : Y,
|
FileObject.read(4)
|
||||||
'Z' : Z,
|
FileObject.read(4)
|
||||||
|
FileObject.read(4)
|
||||||
|
#---
|
||||||
|
return {'x' : X,
|
||||||
|
'y' : Y,
|
||||||
|
'z' : Z,
|
||||||
|
'Raidus' : Radius,
|
||||||
'AffectedBlocks' : AffectedBlocks
|
'AffectedBlocks' : AffectedBlocks
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,6 +517,22 @@ def handle3D(FileObject):
|
|||||||
'Data' : Data
|
'Data' : Data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def handle3E(FileObject):
|
||||||
|
length = struct.unpack('!h', FileObject.read(2))[0] * 2
|
||||||
|
Sound = FileObject.read(length).decode('utf-16be')
|
||||||
|
x = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
|
y = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
|
z = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
|
Volume = struct.unpack('!f', FileObject.read(4))[0]
|
||||||
|
Pitch = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
|
return {'Sound' : Sound,
|
||||||
|
'x' : x,
|
||||||
|
'y' : y,
|
||||||
|
'z' : z,
|
||||||
|
'Volume' : Volume,
|
||||||
|
'Pitch' : Pitch
|
||||||
|
}
|
||||||
|
|
||||||
def handle46(FileObject):
|
def handle46(FileObject):
|
||||||
Reason = struct.unpack('!b', FileObject.read(1))[0]
|
Reason = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
GameMode = struct.unpack('!b', FileObject.read(1))[0]
|
GameMode = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
@ -519,7 +583,6 @@ def handle68(FileObject):
|
|||||||
Slots = []
|
Slots = []
|
||||||
for i in range(Count):
|
for i in range(Count):
|
||||||
SlotData = decodeSlotData(FileObject)
|
SlotData = decodeSlotData(FileObject)
|
||||||
SlotData["index"] = i
|
|
||||||
Slots.append(SlotData)
|
Slots.append(SlotData)
|
||||||
return {'WindowID' : WindowID,
|
return {'WindowID' : WindowID,
|
||||||
'Count' : Count,
|
'Count' : Count,
|
||||||
@ -555,7 +618,7 @@ def handle82(FileObject):
|
|||||||
X = struct.unpack('!i', FileObject.read(4))[0]
|
X = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
Y = struct.unpack('!h', FileObject.read(2))[0]
|
Y = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
Z = struct.unpack('!i', FileObject.read(4))[0]
|
Z = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
length = struct.unpack('!i', FileObject.read(2))[0] * 2
|
length = struct.unpack('!h', FileObject.read(2))[0] * 2
|
||||||
Line1 = FileObject.read(length).decode("utf-16be")
|
Line1 = FileObject.read(length).decode("utf-16be")
|
||||||
length = struct.unpack('!h', FileObject.read(2))[0] * 2
|
length = struct.unpack('!h', FileObject.read(2))[0] * 2
|
||||||
Line2 = FileObject.read(length).decode("utf-16be")
|
Line2 = FileObject.read(length).decode("utf-16be")
|
||||||
@ -587,16 +650,19 @@ def handle84(FileObject):
|
|||||||
Y = struct.unpack('!h', FileObject.read(2))[0]
|
Y = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
Z = struct.unpack('!i', FileObject.read(4))[0]
|
Z = struct.unpack('!i', FileObject.read(4))[0]
|
||||||
Action = struct.unpack('!b', FileObject.read(1))[0]
|
Action = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
Custom1 = struct.unpack('!i', FileObject.read(4))[0]
|
DataLength = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
Custom2 = struct.unpack('!i', FileObject.read(4))[0]
|
if (DataLength != -1):
|
||||||
Custom3 = struct.unpack('!i', FileObject.read(4))[0]
|
NBTData = struct.unpack(str(DataLength) + "s", FileObject.read(DataLength))[0]
|
||||||
|
return {'x' : X,
|
||||||
|
'y' : Y,
|
||||||
|
'z' : Z,
|
||||||
|
'Action' : Action,
|
||||||
|
'NBTData' : NBTData
|
||||||
|
}
|
||||||
return {'x' : X,
|
return {'x' : X,
|
||||||
'y' : Y,
|
'y' : Y,
|
||||||
'z' : Z,
|
'z' : Z,
|
||||||
'Action' : Action,
|
'Action' : Action
|
||||||
'Custom1' : Custom1,
|
|
||||||
'Custom2' : Custom2,
|
|
||||||
'Custom3': Custom3
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def handleC8(FileObject):
|
def handleC8(FileObject):
|
||||||
@ -617,16 +683,24 @@ def handleC9(FileObject):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def handleCA(FileObject):
|
def handleCA(FileObject):
|
||||||
Invulnerable = struct.unpack('?', FileObject.read(1))[0]
|
#byte - flags
|
||||||
IsFlying = struct.unpack('?', FileObject.read(1))[0]
|
Flags = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
CanFly = struct.unpack('?', FileObject.read(1))[0]
|
|
||||||
InstantDestroy = struct.unpack('?', FileObject.read(1))[0]
|
#byte - fly speed
|
||||||
return {'Invulnerable' : Invulnerable,
|
FlySpeed = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
'IsFlying' : IsFlying,
|
|
||||||
'CanFly' : CanFly,
|
#byte - walk speed
|
||||||
'InstantDestroy' : InstantDestroy
|
WalkSpeed = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
|
return {'Flags' : Flags,
|
||||||
|
'Fly Speed' : FlySpeed,
|
||||||
|
'Walk Speed' : WalkSpeed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def handleCB(FileObject):
|
||||||
|
length = struct.unpack('!h', FileObject.read(2))[0] * 2
|
||||||
|
text = FileObject.read(length).decode("utf-16be")
|
||||||
|
return {'Text' : text}
|
||||||
|
|
||||||
def handleFA(FileObject):
|
def handleFA(FileObject):
|
||||||
length = struct.unpack('!h', FileObject.read(2))[0] * 2
|
length = struct.unpack('!h', FileObject.read(2))[0] * 2
|
||||||
Channel = FileObject.read(length).decode("utf-16be")
|
Channel = FileObject.read(length).decode("utf-16be")
|
||||||
@ -716,22 +790,21 @@ def decodeSlotData(FileObject):
|
|||||||
BlockID = struct.unpack('!h', FileObject.read(2))[0]
|
BlockID = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
if(BlockID != -1):
|
if(BlockID != -1):
|
||||||
ItemCount = struct.unpack('!b', FileObject.read(1))[0]
|
ItemCount = struct.unpack('!b', FileObject.read(1))[0]
|
||||||
MetaData = struct.unpack('!h', FileObject.read(2))[0]
|
Damage = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
if((256 <= BlockID and BlockID <= 259) or (267 <= BlockID and BlockID <= 279) or (283 <= BlockID and BlockID <= 286) or (290 <= BlockID and BlockID <= 294) or (298 <= BlockID and BlockID <= 317) or BlockID == 261 or BlockID == 359 or BlockID == 346):
|
MetadataLength = struct.unpack('!h', FileObject.read(2))[0]
|
||||||
IncomingDataLength = struct.unpack('!h', FileObject.read(2))[0]
|
if(MetadataLength != -1):
|
||||||
if(IncomingDataLength != -1):
|
raw = FileObject.read(MetadataLength)
|
||||||
raw = FileObject.read(IncomingDataLength)
|
ByteArray = struct.unpack(str(MetadataLength) + "s", raw)[0]
|
||||||
ByteArray = struct.unpack(str(IncomingDataLength) + "s", raw)[0]
|
Data = zlib.decompress(ByteArray, 15+32)
|
||||||
Data = zlib.decompress(ByteArray, 15+32)
|
return {'BlockID' : BlockID,
|
||||||
return {'BlockID' : BlockID,
|
'ItemCount' : ItemCount,
|
||||||
'ItemCount' : ItemCount,
|
'Damage' : Damage,
|
||||||
'MetaData' : MetaData,
|
'Data' : Data
|
||||||
'Data' : Data
|
}
|
||||||
}
|
|
||||||
return {'BlockID' : BlockID,
|
return {'BlockID' : BlockID,
|
||||||
'ItemCount' : ItemCount,
|
'ItemCount' : ItemCount,
|
||||||
'MetaData' : MetaData
|
'Damage' : Damage
|
||||||
}
|
}
|
||||||
return {'BlockID' : -1,
|
return {'BlockID' : -1,
|
||||||
'ItemCount' : -1
|
'ItemCount' : 0
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user