0

textures: implement proper fallback loading

Sometimes a texture pack is not complete, but system textures are
available to make up the difference. In that case, we should load
those.

Current caveat is that we might not notice texture names changing
with newer minecraft clients because we have old ones installed.

I'll have to think some more about that one.
This commit is contained in:
Nicolas F
2019-07-06 23:36:47 +02:00
parent 6b0ccc1513
commit a6bcc0f957

View File

@@ -86,8 +86,8 @@ class Textures(object):
self.texture_cache = {} self.texture_cache = {}
# once we find a jarfile that contains a texture, we cache the ZipFile object here # once we find a jarfile that contains a texture, we cache the ZipFile object here
self.jar = None self.jars = []
self.jarpath = "" self.jarpaths = []
## ##
## pickle support ## pickle support
@@ -101,7 +101,7 @@ class Textures(object):
del attributes[attr] del attributes[attr]
except KeyError: except KeyError:
pass pass
attributes['jar'] = None attributes['jars'] = []
return attributes return attributes
def __setstate__(self, attrs): def __setstate__(self, attrs):
# regenerate textures, if needed # regenerate textures, if needed
@@ -116,6 +116,17 @@ class Textures(object):
## ##
def generate(self): def generate(self):
# Make sure we have the foliage/grasscolor images available
try:
self.load_foliage_color()
self.load_grass_color()
except TextureException as e:
logging.error(
"Your system is missing either assets/minecraft/textures/colormap/foliage.png "
"or assets/minecraft/textures/colormap/grass.png. Either complement your "
"resource pack with these texture files, or install the vanilla Minecraft "
"client to use as a fallback.")
raise e
# generate biome grass mask # generate biome grass mask
self.biome_grass_texture = self.build_block(self.load_image_texture("assets/minecraft/textures/block/grass_block_top.png"), self.load_image_texture("assets/minecraft/textures/block/grass_block_side_overlay.png")) self.biome_grass_texture = self.build_block(self.load_image_texture("assets/minecraft/textures/block/grass_block_top.png"), self.load_image_texture("assets/minecraft/textures/block/grass_block_side_overlay.png"))
@@ -173,13 +184,19 @@ class Textures(object):
# we've sucessfully loaded something from here before, so let's quickly try # we've sucessfully loaded something from here before, so let's quickly try
# this before searching again # this before searching again
if self.jar is not None: # We might already know some jarpaths from other processes though.
try: if len(self.jarpaths) > len(self.jars):
self.jar.getinfo(filename) for p in self.jarpaths:
if verbose: logging.info("Found (cached) %s in '%s'", filename, self.jarpath) self.jars.append(zipfile.ZipFile(p))
return self.jar.open(filename) if len(self.jars) > 0:
except (KeyError, IOError) as e: for jar_num, jar in enumerate(self.jars):
pass try:
jar.getinfo(filename)
if verbose: logging.info("Found (cached) %s in '%s'", filename,
self.jarpaths[jar_num])
return jar.open(filename)
except (KeyError, IOError) as e:
pass
# A texture path was given on the command line. Search this location # A texture path was given on the command line. Search this location
# for the file first. # for the file first.
@@ -199,7 +216,8 @@ class Textures(object):
pack.getinfo(filename) pack.getinfo(filename)
if verbose: logging.info("Found %s in '%s'", filename, if verbose: logging.info("Found %s in '%s'", filename,
self.find_file_local_path) self.find_file_local_path)
self.jar, self.jarpath = pack, self.find_file_local_path self.jars.append(pack)
self.jarpaths.append(self.find_file_local_path)
return pack.open(filename) return pack.open(filename)
except (zipfile.BadZipfile, KeyError, IOError): except (zipfile.BadZipfile, KeyError, IOError):
pass pass
@@ -283,7 +301,8 @@ class Textures(object):
try: try:
jar.getinfo(filename) jar.getinfo(filename)
if verbose: logging.info("Found %s in '%s'", filename, jarpath) if verbose: logging.info("Found %s in '%s'", filename, jarpath)
self.jar, self.jarpath = jar, jarpath self.jars.append(jar)
self.jarpaths.append(jarpath)
return jar.open(filename) return jar.open(filename)
except (KeyError, IOError) as e: except (KeyError, IOError) as e:
pass pass