minosoft/util/blockModelGenerator.py
2020-11-17 22:24:30 +01:00

188 lines
4.6 KiB
Python

# minosoft
# Copyright (C) 2020 Lukas Eisenhauer
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
#
# This software is not affiliated with Mojang AB, the original developer of Minecraft.
import io
import requests
import sys
import ujson
import zipfile
if len(sys.argv) != 3:
print("Usage: %s <destination path> <jar url>".format(
sys.argv[
0]))
sys.exit()
blockStates = {}
blockModels = {}
modName = "minecraft"
print(
"Downloading minecraft jar...")
request = requests.get(sys.argv[2], allow_redirects=True)
print(
"Unpacking minecraft jar...")
zip = zipfile.ZipFile(
io.BytesIO(
request.content),
"r")
files = zip.namelist()
print(
"Loading blockstates...")
def readRotations(
apply,
current):
if "x" in current:
apply[
"x"] = \
current[
"x"]
if "y" in current:
apply[
"y"] = \
current[
"y"]
if "z" in current:
apply[
"z"] = \
current[
"z"]
def readPart(part):
properties = []
if "when" in part:
when = part["when"]
if "OR" in when:
for item in when["OR"]:
properties.append(item)
else:
properties.append(part["when"])
apply = {}
current = part["apply"]
if type(current) == type([]):
current = current[0]
apply["model"] = current["model"].split("/")[1]
readRotations(apply, current)
result = []
for item in properties:
state = {}
state["properties"] = item
for i in apply:
state[i] = apply[i]
result.append(state)
if len(result) == 0:
result.append(apply)
return result
for blockStateFile in [
f
for
f
in
files
if
f.startswith(
'assets/minecraft/blockstates/')]:
with zip.open(
blockStateFile) as file:
data = ujson.load(
file)
block = {}
if "variants" in data:
variants = \
data[
"variants"]
states = []
for variant in variants:
state = {}
properties = {}
if variant != "":
for part in variant.split(
","):
properties[
part.split(
"=")[
0]] = \
part.split(
"=")[
1]
state["properties"] = properties
current = variants[variant]
if type(current) == type([]):
current = current[0]
state["model"] = current["model"].split("/")[1]
readRotations(state, current)
states.append(state)
block = {
"states": states
}
elif "multipart" in data:
parts = \
data[
"multipart"]
conditional = []
for part in parts:
conditional.extend(
readPart(
part))
block = {
"conditional": conditional
}
blockStates[
blockStateFile.split(
".")[
0]] = block
print(
"Loading models...")
for blockModelFile in [
f
for
f
in
files
if
f.startswith(
'assets/minecraft/models/block/')]:
with zip.open(
blockModelFile) as file:
data = ujson.load(
file)
blockModels[
blockModelFile.split(
".")[
0]] = data
print(
"Combining files...")
finalJson = {
"mod": modName,
"blockStates": blockStates,
"blockModels": blockModels,
}
print("Saving...")
with open(sys.argv[1], "w+") as file:
finalJson = ujson.dumps(finalJson)
file.write(finalJson.replace("minecraft:", ""))
print(
"Finished successfully")