Created
August 1, 2018 09:22
-
-
Save Earthcomputer/c32fc5a3b3df3b261518cc0380115cd7 to your computer and use it in GitHub Desktop.
specialsource_fix.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# EARTHCOMPUTER'S HACKFIX FOR SPECIALSOURCE FUCKING UP IN 1.13 | |
from zipfile import ZipFile | |
import sys | |
def load_csrg(csrgf): | |
csrg = {} | |
for line in csrgf: | |
parts = line.rstrip().split(" ") | |
if len(parts) > 2: | |
cls = parts[0] | |
name = parts[-1] | |
obf = parts[1] | |
if name.startswith("field_") or name.startswith("func_"): | |
csrg[bytes(name, "utf8")] = bytes(obf, "utf8") | |
else: | |
csrg[(bytes(cls, "utf8"), bytes(name, "utf8"))] = bytes(obf, "utf8") | |
return csrg | |
def u2(data, index): | |
return 256 * data[index] + data[index + 1] | |
def writeu2(outdata, value): | |
outdata.append(value // 256) | |
outdata.append(value % 256) | |
def cpiter(data): | |
sizes = [None, None, None, 5, 5, 9, 9, 3, 3, 5, 5, 5, 5, None, None, 4, 3, None, 5] | |
cpsize = u2(data, 8) | |
index = 10 | |
cpindex = 1 | |
while cpindex < cpsize: | |
tag = data[index] | |
if tag == 1: | |
size = 3 + u2(data, index + 1) | |
else: | |
size = sizes[tag] | |
yield (index, size, cpindex) | |
index += size | |
if tag == 5 or tag == 6: | |
cpindex += 2 | |
else: | |
cpindex += 1 | |
def transform_class(injar, outjar, csrg, name): | |
print(name) | |
data = injar.read(name) | |
outdata = bytearray() | |
cpsize = u2(data, 8) | |
cpend = 10 | |
cpdata = [None] * cpsize | |
extradata = [] | |
for index, size, cpindex in cpiter(data): | |
cpend = index + size | |
if data[index] == 1: | |
cpdata[cpindex] = bytes(data[index+3:index+size]) | |
elif data[index] == 7: | |
cpdata[cpindex] = u2(data, index + 1) | |
elif data[index] == 12: | |
n = u2(data, index + 1) | |
t = u2(data, index + 3) | |
cpdata[cpindex] = [n, t] | |
for index, size, cpindex in cpiter(data): | |
if data[index] == 9: | |
cls = cpdata[cpdata[u2(data, index + 1)]] | |
nat = cpdata[u2(data, index + 3)] | |
field_name = cpdata[nat[0]] | |
if (cls, field_name) in csrg: | |
nat[0] = cpsize | |
extradata.append(csrg[(cls, field_name)]) | |
cpsize += 1 | |
for index, size, cpindex in cpiter(data): | |
if data[index] == 1: | |
if cpdata[cpindex] in csrg: | |
cpdata[cpindex] = csrg[cpdata[cpindex]] | |
outdata += data[:8] | |
writeu2(outdata, cpsize) | |
for index, size, cpindex in cpiter(data): | |
if data[index] == 1: | |
outdata += data[index:index+1] | |
writeu2(outdata, len(cpdata[cpindex])) | |
outdata += cpdata[cpindex] | |
elif data[index] == 12: | |
outdata += data[index:index+1] | |
writeu2(outdata, cpdata[cpindex][0]) | |
writeu2(outdata, cpdata[cpindex][1]) | |
else: | |
outdata += data[index:index+size] | |
for const in extradata: | |
outdata.append(1) | |
writeu2(outdata, len(const)) | |
outdata += const | |
outdata += data[cpend:] | |
outjar.writestr(name, bytes(outdata)) | |
def main(argv): | |
if len(argv) < 4: | |
print("specialsource_fix.py <injar> <outjar> <csrg>") | |
return | |
with open(argv[3]) as csrgf: | |
csrg = load_csrg(csrgf) | |
with ZipFile(argv[1]) as injar: | |
with ZipFile(argv[2], "w") as outjar: | |
for name in injar.namelist(): | |
if name.endswith(".class"): | |
transform_class(injar, outjar, csrg, name) | |
else: | |
outjar.writestr(name, injar.read(name)) | |
main(sys.argv) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment