-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmcr.py
135 lines (126 loc) · 3.69 KB
/
mcr.py
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
125
126
127
128
129
130
131
132
133
134
135
import math
import zlib
import gzip
from io import BytesIO
region_x = 0
region_z = 0
kib = 1024
header_index = 0
regionFile = f"r.{region_x}.{region_z}.mcr"
f = open(regionFile, "rb")
print(f"X: {region_x}\nZ: {region_z}")
def intread(file, length):
return int.from_bytes(file.read(length),byteorder='big')
def floatread(file, length):
return float.from_bytes(file.read(length),byteorder='big')
def tagType(tag):
if tag==0: # TAG_END
return "TAG_END"
elif tag==1: # TAG_Byte
return "TAG_Byte"
elif tag==2: # TAG_Short
return "TAG_Short"
elif tag==3: # TAG_Int
return "TAG_Int"
elif tag==4: # TAG_Long
return "TAG_Long"
elif tag==5: # TAG_Float
return "TAG_Float"
elif tag==6: # TAG_Double
return "TAG_Double"
elif tag==7: # TAG_Byte_Array
return "TAG_Byte_Array"
elif tag==8: # TAG_String
return "TAG_String"
elif tag==9: # TAG_List
return "TAG_List"
elif tag==10: # TAG_Compound
return "TAG_Compound"
elif tag==11: # TAG_Int_Array
return "TAG_Int_Array"
elif tag==12: # TAG_Long_Array
return "TAG_Long_Array"
else:
return "Unknown"
def decodeTag(file):
tag = intread(file,1)
tagNameLength = intread(file,2)
tagName = ""
data = None
if tagNameLength > 0:
tagName = file.read(tagNameLength).decode("utf-8")
if tag==0: # TAG_END
data = None
elif tag==1: # TAG_Byte
data = intread(file,1)
elif tag==2: # TAG_Short
data = intread(file,2)
elif tag==3: # TAG_Int
data = intread(file,4)
elif tag==4: # TAG_Long
data = intread(file,8)
elif tag==5: # TAG_Float
data = floatread(file,4)
elif tag==6: # TAG_Double
data = floatread(file,8)
elif tag==7: # TAG_Byte_Array
size = intread(file,4)
print(size)
data = []
for i in range(size):
data.append(intread(file,1))
#data = f"{len(data)} Entries"
x = (header_index % 32 * 16) #region_x + (header_index % 32 * 16)
z = (math.floor(header_index / 32) * 16) #region_z + (math.floor(header_index / 32) * 16)
open(f'./extracted/chunk_{x}_{z}.bin', 'wb').write(bytes(data))
elif tag==8: # TAG_String
length = intread(file,2)
data = file.read(length).decode("utf-8")
elif tag==9: # TAG_List
data = None
elif tag==10: # TAG_Compound
data = None
elif tag==11: # TAG_Int_Array
data = None
elif tag==12: # TAG_Long_Array
data = None
else:
print(f"Invalid Tag: {tag}")
#print(f"{tagType(tag)}: \"{tagName}\"\n\t{data}")
def csDecode(index):
if index == 1:
return "GZip"
elif index == 2:
return "Zlib"
elif index == 3:
return "Uncompressed"
elif index == 4:
return "LZ4"
elif index == 127:
return "Custom"
else:
return "Unsupported"
for c in range(1024):
f.seek(c*4, 0)
depth = 0
header_index = c
offset = intread(f,3)*(4*kib)
sector = intread(f,1)*(4*kib)
if offset == 0 and sector == 0:
continue
else:
print(f"Chunk #{header_index}: {offset}, {sector}KiB")
f.seek(offset, 0)
length = intread(f,4)
compressionScheme = intread(f,1)
if compressionScheme == 1: #GZip
data = gzip.decompress(f.read(length-1))
elif compressionScheme == 2: #Zlip
data = zlib.decompress(f.read(length-1))
print(f"\t{length} Bytes\n\tCompression {csDecode(compressionScheme)}")
nbt = BytesIO(data)
for i in range(4):
decodeTag(nbt)
#open('out.nbt', 'wb').write(data)
f.read(1024*4)
f.close()