Skip to content

Instantly share code, notes, and snippets.

@Earthcomputer
Created August 1, 2018 09:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Earthcomputer/c32fc5a3b3df3b261518cc0380115cd7 to your computer and use it in GitHub Desktop.
Save Earthcomputer/c32fc5a3b3df3b261518cc0380115cd7 to your computer and use it in GitHub Desktop.
specialsource_fix.py
# 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