textures: greatly simplify find_file and friends
find_file contained a lot of code for searching textures in ways that haven't been relevant for years. For example, it had workarounds for MCPatcher, a tool that hasn't been updated since 2015. Instead of searching in multiple paths that will never succeed in a resource pack and Minecraft version that actually work, just look for the filename that the block functions ask for. Also, if we already have a manually specified resource pack open, we shouldn't repeatedly re-open it. Furthermore, it's best if the very first thing find_file does is try to find the file in the resource pack or client jar we've already opened previously. We can now also remove chest.png, ender.png, foliage.png, grass.png and normal_double.png because Minecraft ships them, so we don't need to ship them ourselves too. Us shipping them actually hid the whole find_file garbagefire. Concerns issue #1604.
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
@@ -151,6 +151,7 @@ class Textures(object):
|
|||||||
"""Searches for the given file and returns an open handle to it.
|
"""Searches for the given file and returns an open handle to it.
|
||||||
This searches the following locations in this order:
|
This searches the following locations in this order:
|
||||||
|
|
||||||
|
* In an already open resource pack or client jar file
|
||||||
* In the directory textures_path given in the initializer
|
* In the directory textures_path given in the initializer
|
||||||
* In the resource pack given by textures_path
|
* In the resource pack given by textures_path
|
||||||
* The program dir (same dir as overviewer.py) for extracted textures
|
* The program dir (same dir as overviewer.py) for extracted textures
|
||||||
@@ -167,58 +168,40 @@ class Textures(object):
|
|||||||
|
|
||||||
* The overviewer_core/data/textures dir
|
* The overviewer_core/data/textures dir
|
||||||
|
|
||||||
In all of these, files are searched for in '.', 'anim', 'misc/', and
|
|
||||||
'environment/'.
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if verbose: logging.info("Starting search for {0}".format(filename))
|
if verbose: logging.info("Starting search for {0}".format(filename))
|
||||||
|
|
||||||
# a list of subdirectories to search for a given file,
|
# we've sucessfully loaded something from here before, so let's quickly try
|
||||||
# after the obvious '.'
|
# this before searching again
|
||||||
search_dirs = ['anim', 'misc', 'environment', 'item', 'item/chests', 'entity', 'entity/chest']
|
if self.jar is not None:
|
||||||
search_zip_paths = [filename,] + [d + '/' + filename for d in search_dirs]
|
try:
|
||||||
def search_dir(base):
|
self.jar.getinfo(filename)
|
||||||
"""Search the given base dir for filename, in search_dirs."""
|
if verbose: logging.info("Found (cached) %s in '%s'", filename, self.jarpath)
|
||||||
for path in [os.path.join(base, d, filename) for d in ['',] + search_dirs]:
|
return self.jar.open(filename)
|
||||||
if verbose: logging.info('filename: ' + filename + ' ; path: ' + path)
|
except (KeyError, IOError) as e:
|
||||||
if os.path.isfile(path):
|
pass
|
||||||
return path
|
|
||||||
|
|
||||||
return None
|
|
||||||
if verbose: logging.info('search_zip_paths: ' + ', '.join(search_zip_paths))
|
|
||||||
|
|
||||||
# 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.
|
||||||
if self.find_file_local_path:
|
if self.find_file_local_path:
|
||||||
if os.path.isdir(self.find_file_local_path):
|
if os.path.isdir(self.find_file_local_path):
|
||||||
path = search_dir(self.find_file_local_path)
|
full_path = os.path.join(self.find_file_local_path, filename)
|
||||||
if path:
|
if os.path.isfile(full_path):
|
||||||
if verbose: logging.info("Found %s in '%s'", filename, path)
|
if verbose: logging.info("Found %s in '%s'", filename, full_path)
|
||||||
return open(path, mode)
|
return open(full_path, mode)
|
||||||
elif os.path.isfile(self.find_file_local_path):
|
elif os.path.isfile(self.find_file_local_path):
|
||||||
# Must be a resource pack. Look for the requested file within
|
# Must be a resource pack. Look for the requested file within
|
||||||
# it.
|
# it.
|
||||||
try:
|
try:
|
||||||
pack = zipfile.ZipFile(self.find_file_local_path)
|
pack = zipfile.ZipFile(self.find_file_local_path)
|
||||||
for packfilename in search_zip_paths:
|
# pack.getinfo() will raise KeyError if the file is
|
||||||
try:
|
# not found.
|
||||||
# pack.getinfo() will raise KeyError if the file is
|
pack.getinfo(filename)
|
||||||
# not found.
|
if verbose: logging.info("Found %s in '%s'", filename,
|
||||||
pack.getinfo(packfilename)
|
self.find_file_local_path)
|
||||||
if verbose: logging.info("Found %s in '%s'", packfilename, self.find_file_local_path)
|
self.jar, self.jarpath = pack, self.find_file_local_path
|
||||||
return pack.open(packfilename)
|
return pack.open(filename)
|
||||||
except (KeyError, IOError):
|
except (zipfile.BadZipfile, KeyError, IOError):
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
# 2nd try with completed path.
|
|
||||||
packfilename = 'assets/minecraft/textures/' + packfilename
|
|
||||||
pack.getinfo(packfilename)
|
|
||||||
if verbose: logging.info("Found %s in '%s'", packfilename, self.find_file_local_path)
|
|
||||||
return pack.open(packfilename)
|
|
||||||
except (KeyError, IOError):
|
|
||||||
pass
|
|
||||||
except (zipfile.BadZipfile, IOError):
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# If we haven't returned at this point, then the requested file was NOT
|
# If we haven't returned at this point, then the requested file was NOT
|
||||||
@@ -228,31 +211,20 @@ class Textures(object):
|
|||||||
|
|
||||||
# Look in the location of the overviewer executable for the given path
|
# Look in the location of the overviewer executable for the given path
|
||||||
programdir = util.get_program_path()
|
programdir = util.get_program_path()
|
||||||
path = search_dir(programdir)
|
path = os.path.join(programdir, filename)
|
||||||
if path:
|
if os.path.isfile(path):
|
||||||
if verbose: logging.info("Found %s in '%s'", filename, path)
|
if verbose: logging.info("Found %s in '%s'", filename, path)
|
||||||
return open(path, mode)
|
return open(path, mode)
|
||||||
|
|
||||||
if sys.platform.startswith("darwin"):
|
if sys.platform.startswith("darwin"):
|
||||||
path = search_dir("/Applications/Minecraft")
|
path = os.path.join("/Applications/Minecraft", filename)
|
||||||
if path:
|
if os.path.isfile(path):
|
||||||
if verbose: logging.info("Found %s in '%s'", filename, path)
|
if verbose: logging.info("Found %s in '%s'", filename, path)
|
||||||
return open(path, mode)
|
return open(path, mode)
|
||||||
|
|
||||||
if verbose: logging.info("Did not find the file in overviewer executable directory")
|
if verbose: logging.info("Did not find the file in overviewer executable directory")
|
||||||
if verbose: logging.info("Looking for installed minecraft jar files...")
|
if verbose: logging.info("Looking for installed minecraft jar files...")
|
||||||
|
|
||||||
# we've sucessfully loaded something from here before, so let's quickly try
|
|
||||||
# this before searching again
|
|
||||||
if self.jar is not None:
|
|
||||||
for jarfilename in search_zip_paths:
|
|
||||||
try:
|
|
||||||
self.jar.getinfo(jarfilename)
|
|
||||||
if verbose: logging.info("Found (cached) %s in '%s'", jarfilename, self.jarpath)
|
|
||||||
return self.jar.open(jarfilename)
|
|
||||||
except (KeyError, IOError) as e:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Find an installed minecraft client jar and look in it for the texture
|
# Find an installed minecraft client jar and look in it for the texture
|
||||||
# file we need.
|
# file we need.
|
||||||
versiondir = ""
|
versiondir = ""
|
||||||
@@ -308,14 +280,13 @@ class Textures(object):
|
|||||||
|
|
||||||
if os.path.isfile(jarpath):
|
if os.path.isfile(jarpath):
|
||||||
jar = zipfile.ZipFile(jarpath)
|
jar = zipfile.ZipFile(jarpath)
|
||||||
for jarfilename in search_zip_paths:
|
try:
|
||||||
try:
|
jar.getinfo(filename)
|
||||||
jar.getinfo(jarfilename)
|
if verbose: logging.info("Found %s in '%s'", filename, jarpath)
|
||||||
if verbose: logging.info("Found %s in '%s'", jarfilename, jarpath)
|
self.jar, self.jarpath = jar, jarpath
|
||||||
self.jar, self.jarpath = jar, jarpath
|
return jar.open(filename)
|
||||||
return jar.open(jarfilename)
|
except (KeyError, IOError) as e:
|
||||||
except (KeyError, IOError) as e:
|
pass
|
||||||
pass
|
|
||||||
|
|
||||||
if verbose: logging.info("Did not find file {0} in jar {1}".format(filename, jarpath))
|
if verbose: logging.info("Did not find file {0} in jar {1}".format(filename, jarpath))
|
||||||
|
|
||||||
@@ -326,14 +297,14 @@ class Textures(object):
|
|||||||
# believe that's not true, but we still have a few files distributed
|
# believe that's not true, but we still have a few files distributed
|
||||||
# with overviewer.
|
# with overviewer.
|
||||||
if verbose: logging.info("Looking for texture in overviewer_core/data/textures")
|
if verbose: logging.info("Looking for texture in overviewer_core/data/textures")
|
||||||
path = search_dir(os.path.join(programdir, "overviewer_core", "data", "textures"))
|
path = os.path.join(programdir, "overviewer_core", "data", "textures", filename)
|
||||||
if path:
|
if os.path.isfile(path):
|
||||||
if verbose: logging.info("Found %s in '%s'", filename, path)
|
if verbose: logging.info("Found %s in '%s'", filename, path)
|
||||||
return open(path, mode)
|
return open(path, mode)
|
||||||
elif hasattr(sys, "frozen") or imp.is_frozen("__main__"):
|
elif hasattr(sys, "frozen") or imp.is_frozen("__main__"):
|
||||||
# windows special case, when the package dir doesn't exist
|
# windows special case, when the package dir doesn't exist
|
||||||
path = search_dir(os.path.join(programdir, "textures"))
|
path = os.path.join(programdir, "textures", filename)
|
||||||
if path:
|
if os.path.isfile(path):
|
||||||
if verbose: logging.info("Found %s in '%s'", filename, path)
|
if verbose: logging.info("Found %s in '%s'", filename, path)
|
||||||
return open(path, mode)
|
return open(path, mode)
|
||||||
|
|
||||||
@@ -380,67 +351,40 @@ class Textures(object):
|
|||||||
|
|
||||||
|
|
||||||
def load_water(self):
|
def load_water(self):
|
||||||
"""Special-case function for loading water, handles
|
"""Special-case function for loading water."""
|
||||||
MCPatcher-compliant custom animated water."""
|
|
||||||
watertexture = getattr(self, "watertexture", None)
|
watertexture = getattr(self, "watertexture", None)
|
||||||
if watertexture:
|
if watertexture:
|
||||||
return watertexture
|
return watertexture
|
||||||
try:
|
watertexture = self.load_image_texture("assets/minecraft/textures/block/water_still.png")
|
||||||
# try the MCPatcher case first
|
|
||||||
watertexture = self.load_image("custom_water_still.png")
|
|
||||||
watertexture = watertexture.crop((0, 0, watertexture.size[0], watertexture.size[0]))
|
|
||||||
except TextureException:
|
|
||||||
watertexture = self.load_image_texture("assets/minecraft/textures/block/water_still.png")
|
|
||||||
self.watertexture = watertexture
|
self.watertexture = watertexture
|
||||||
return watertexture
|
return watertexture
|
||||||
|
|
||||||
def load_lava(self):
|
def load_lava(self):
|
||||||
"""Special-case function for loading lava, handles
|
"""Special-case function for loading lava."""
|
||||||
MCPatcher-compliant custom animated lava."""
|
|
||||||
lavatexture = getattr(self, "lavatexture", None)
|
lavatexture = getattr(self, "lavatexture", None)
|
||||||
if lavatexture:
|
if lavatexture:
|
||||||
return lavatexture
|
return lavatexture
|
||||||
try:
|
lavatexture = self.load_image_texture("assets/minecraft/textures/block/lava_still.png")
|
||||||
# try the MCPatcher lava first, in case it's present
|
|
||||||
lavatexture = self.load_image("custom_lava_still.png")
|
|
||||||
lavatexture = lavatexture.crop((0, 0, lavatexture.size[0], lavatexture.size[0]))
|
|
||||||
except TextureException:
|
|
||||||
lavatexture = self.load_image_texture("assets/minecraft/textures/block/lava_still.png")
|
|
||||||
self.lavatexture = lavatexture
|
self.lavatexture = lavatexture
|
||||||
return lavatexture
|
return lavatexture
|
||||||
|
|
||||||
def load_fire(self):
|
def load_fire(self):
|
||||||
"""Special-case function for loading fire, handles
|
"""Special-case function for loading fire."""
|
||||||
MCPatcher-compliant custom animated fire."""
|
|
||||||
firetexture = getattr(self, "firetexture", None)
|
firetexture = getattr(self, "firetexture", None)
|
||||||
if firetexture:
|
if firetexture:
|
||||||
return firetexture
|
return firetexture
|
||||||
try:
|
fireNS = self.load_image_texture("assets/minecraft/textures/block/fire_0.png")
|
||||||
# try the MCPatcher case first
|
fireEW = self.load_image_texture("assets/minecraft/textures/block/fire_1.png")
|
||||||
firetextureNS = self.load_image("custom_fire_n_s.png")
|
firetexture = (fireNS, fireEW)
|
||||||
firetextureNS = firetextureNS.crop((0, 0, firetextureNS.size[0], firetextureNS.size[0]))
|
|
||||||
firetextureEW = self.load_image("custom_fire_e_w.png")
|
|
||||||
firetextureEW = firetextureEW.crop((0, 0, firetextureEW.size[0], firetextureEW.size[0]))
|
|
||||||
firetexture = (firetextureNS,firetextureEW)
|
|
||||||
except TextureException:
|
|
||||||
fireNS = self.load_image_texture("assets/minecraft/textures/block/fire_0.png")
|
|
||||||
fireEW = self.load_image_texture("assets/minecraft/textures/block/fire_1.png")
|
|
||||||
firetexture = (fireNS, fireEW)
|
|
||||||
self.firetexture = firetexture
|
self.firetexture = firetexture
|
||||||
return firetexture
|
return firetexture
|
||||||
|
|
||||||
def load_portal(self):
|
def load_portal(self):
|
||||||
"""Special-case function for loading portal, handles
|
"""Special-case function for loading portal."""
|
||||||
MCPatcher-compliant custom animated portal."""
|
|
||||||
portaltexture = getattr(self, "portaltexture", None)
|
portaltexture = getattr(self, "portaltexture", None)
|
||||||
if portaltexture:
|
if portaltexture:
|
||||||
return portaltexture
|
return portaltexture
|
||||||
try:
|
portaltexture = self.load_image_texture("assets/minecraft/textures/block/nether_portal.png")
|
||||||
# try the MCPatcher case first
|
|
||||||
portaltexture = self.load_image("custom_portal.png")
|
|
||||||
portaltexture = portaltexture.crop((0, 0, portaltexture.size[0], portaltexture.size[1]))
|
|
||||||
except TextureException:
|
|
||||||
portaltexture = self.load_image_texture("assets/minecraft/textures/block/nether_portal.png")
|
|
||||||
self.portaltexture = portaltexture
|
self.portaltexture = portaltexture
|
||||||
return portaltexture
|
return portaltexture
|
||||||
|
|
||||||
@@ -459,13 +403,13 @@ class Textures(object):
|
|||||||
def load_grass_color(self):
|
def load_grass_color(self):
|
||||||
"""Helper function to load the grass color texture."""
|
"""Helper function to load the grass color texture."""
|
||||||
if not hasattr(self, "grasscolor"):
|
if not hasattr(self, "grasscolor"):
|
||||||
self.grasscolor = list(self.load_image("grass.png").getdata())
|
self.grasscolor = list(self.load_image("assets/minecraft/textures/colormap/grass.png").getdata())
|
||||||
return self.grasscolor
|
return self.grasscolor
|
||||||
|
|
||||||
def load_foliage_color(self):
|
def load_foliage_color(self):
|
||||||
"""Helper function to load the foliage color texture."""
|
"""Helper function to load the foliage color texture."""
|
||||||
if not hasattr(self, "foliagecolor"):
|
if not hasattr(self, "foliagecolor"):
|
||||||
self.foliagecolor = list(self.load_image("foliage.png").getdata())
|
self.foliagecolor = list(self.load_image("assets/minecraft/textures/colormap/foliage.png").getdata())
|
||||||
return self.foliagecolor
|
return self.foliagecolor
|
||||||
|
|
||||||
#I guess "watercolor" is wrong. But I can't correct as my texture pack don't define water color.
|
#I guess "watercolor" is wrong. But I can't correct as my texture pack don't define water color.
|
||||||
@@ -2091,12 +2035,12 @@ def chests(self, blockid, data):
|
|||||||
# ancilData = 2,3,4,5 are used for this blockids
|
# ancilData = 2,3,4,5 are used for this blockids
|
||||||
|
|
||||||
if data & 24 == 0:
|
if data & 24 == 0:
|
||||||
if blockid == 130: t = self.load_image("ender.png")
|
if blockid == 130: t = self.load_image("assets/minecraft/textures/entity/chest/ender.png")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
t = self.load_image("normal.png")
|
t = self.load_image("assets/minecraft/textures/entity/chest/normal.png")
|
||||||
except (TextureException, IOError):
|
except (TextureException, IOError):
|
||||||
t = self.load_image("chest.png")
|
t = self.load_image("assets/minecraft/textures/entity/chest/chest.png")
|
||||||
|
|
||||||
# the textures is no longer in terrain.png, get it from
|
# the textures is no longer in terrain.png, get it from
|
||||||
# item/chest.png and get by cropping all the needed stuff
|
# item/chest.png and get by cropping all the needed stuff
|
||||||
@@ -2151,7 +2095,7 @@ def chests(self, blockid, data):
|
|||||||
# large chest
|
# large chest
|
||||||
# the textures is no longer in terrain.png, get it from
|
# the textures is no longer in terrain.png, get it from
|
||||||
# item/chest.png and get all the needed stuff
|
# item/chest.png and get all the needed stuff
|
||||||
t = self.load_image("normal_double.png")
|
t = self.load_image("assets/minecraft/textures/entity/chest/normal_double.png")
|
||||||
if t.size != (128,64): t = t.resize((128,64), Image.ANTIALIAS)
|
if t.size != (128,64): t = t.resize((128,64), Image.ANTIALIAS)
|
||||||
# top
|
# top
|
||||||
top = t.crop((14,0,44,14))
|
top = t.crop((14,0,44,14))
|
||||||
|
|||||||
Reference in New Issue
Block a user