Browse Source

finished u_skin adder

master
poikilos 9 years ago
committed by Jacob Gustafson
parent
commit
cc4b51c3e0
  1. 9
      README.md
  2. 5
      minetestinfo.py
  3. 246
      u_skin_adder.py

9
README.md

@ -81,6 +81,15 @@ To avoid this problem, instead derive the paths from the parent paths using your
if minetestinfo.contains("primary_world_path"): if minetestinfo.contains("primary_world_path"):
world_path = minetestinfo.get_var("primary_world_path") world_path = minetestinfo.get_var("primary_world_path")
world_name = os.path.basename(world_path) world_name = os.path.basename(world_path)
#region alternative method:
gameid = None
game_path = None
if world_path is not None and os.path.isdir(world_path):
gameid=get_world_var("gameid")
if gameid is not None and games_path is not None:
game_path = os.path.join(games_path, gameid)
#endregion alternative method:
``` ```
* Keep in mind that gameid (in game.conf in a subgame folder, and world.mt in a world folder) is NOT case-sensitive: for example, minetest_game has the gameid 'Minetest' (first letter capitalized) but the worlds generated by Minetest client have the gameid 'minetest' (lowercase) in their world.mt * Keep in mind that gameid (in game.conf in a subgame folder, and world.mt in a world folder) is NOT case-sensitive: for example, minetest_game has the gameid 'Minetest' (first letter capitalized) but the worlds generated by Minetest client have the gameid 'minetest' (lowercase) in their world.mt

5
minetestinfo.py

@ -8,6 +8,8 @@ from expertmm import *
#config_path #config_path
#profile_path #profile_path
profile_path = None
worldgen_mod_list = list() worldgen_mod_list = list()
worldgen_mod_list.append("caverealms") worldgen_mod_list.append("caverealms")
worldgen_mod_list.append("ethereal") worldgen_mod_list.append("ethereal")
@ -281,6 +283,7 @@ def get_game_path_from_gameid(gameid):
def init_minetestinfo(): def init_minetestinfo():
global dict_entries_modified_count global dict_entries_modified_count
global profile_path
if not minetestinfo.contains("www_minetest_path"): if not minetestinfo.contains("www_minetest_path"):
default_www_minetest_path = "/var/www/html/minetest" default_www_minetest_path = "/var/www/html/minetest"
if os_name=="windows": if os_name=="windows":
@ -305,7 +308,7 @@ def init_minetestinfo():
minetestinfo.prepare_var("www_minetest_path", default_www_minetest_path, "your web server directory (or other folder where minetest website features and data should be placed)") minetestinfo.prepare_var("www_minetest_path", default_www_minetest_path, "your web server directory (or other folder where minetest website features and data should be placed)")
profile_path = None
if os_name=="windows": if os_name=="windows":
profile_path = os.environ['USERPROFILE'] profile_path = os.environ['USERPROFILE']
else: else:

246
u_skin_adder.py

@ -3,23 +3,52 @@ import os
from expertmm import * from expertmm import *
from minetestinfo import * #paths and FLAG_EMPTY_HEXCOLOR = "#010000" from minetestinfo import * #paths and FLAG_EMPTY_HEXCOLOR = "#010000"
from PIL import Image, ImageDraw, ImageFont, ImageColor from PIL import Image, ImageDraw, ImageFont, ImageColor
import shutil
u_skins_mod_path = "C:\\Users\\jgustafson\\Desktop\\Backup\\fcalocal\\usr\\local\\share\\minetest\\games\\fca_game_a\\mods\\u_skins\\u_skins" u_skins_mod_path = os.path.join(profile_path,"Desktop\\Backup\\fcalocal\\usr\\local\\share\\minetest\\games\\fca_game_a\\mods\\u_skins\\u_skins")
games_path = os.path.join(minetestinfo.get_var("shared_minetest_path"), "games")
verbose_enable = True
image_size = (64,32)
preview_size = (16,32)
visual_debug_enable = False
dump_path = os.path.join(u_skins_mod_path, "debug") # only created or used if visual_debug_enable
world_path = None
world_name = None
if minetestinfo.contains("primary_world_path"):
world_path = minetestinfo.get_var("primary_world_path")
world_name = os.path.basename(world_path)
print("Using world '"+world_name+"'")
#game_name = game_path_from_gameid_dict(
gameid = None
game_path = None
mods_path = None
if not os.path.isdir(u_skins_mod_path): if not os.path.isdir(u_skins_mod_path):
if world_path is not None and os.path.isdir(world_path):
gameid=get_world_var("gameid")
print("Using game '"+str(gameid)+"'")
if gameid is not None and games_path is not None:
game_path = os.path.join(games_path, gameid)
mods_path=os.path.join(game_path, "mods")
print("Using mods_path '"+mods_path+"'")
print("Looking for u_skins mod in u_skins modpack...") print("Looking for u_skins mod in u_skins modpack...")
u_skins_mod_path = os.path.join( os.path.join( os.path.join(game_path, "mods"), "u_skins" ), "u_skins" ) # get the u_skins mod in the u_skins modpack #u_skins_mod_path = os.path.join( os.path.join( os.path.join(game_path, "mods"), "u_skins" ), "u_skins" ) # get the u_skins mod in the u_skins modpack
print(" trying '"+u_skins_mod_path+"'") #print(" trying '"+u_skins_mod_path+"'")
u_skins_modpack_path = os.path.join(mods_path, "u_skins")
u_skins_mod_path = os.path.join(u_skins_modpack_path, "u_skins")
else:
print("Unknown world, so can't detect game.")
meta_path = os.path.join(u_skins_mod_path,"meta") meta_path = os.path.join(u_skins_mod_path,"meta")
textures_path = os.path.join(u_skins_mod_path,"textures") textures_path = os.path.join(u_skins_mod_path,"textures")
in_path = "C:\\Users\\jgustafson\\Downloads\\skins-to-add"
image_prefix = "character_" image_prefix = "character_"
preview_suffix = "_preview" preview_suffix = "_preview"
default_license = "CC BY-SA 3.0" default_license_string = "CC BY-SA 3.0"
if not os.path.isdir(in_path):
in_path = "."
print("Looking for new textures in current directory")
png_count = 0 png_count = 0
@ -44,8 +73,6 @@ rect_trans_list.append(RectTransferInfo((4,20,4,12),(8,20,4,12),False)) # leg.l
rect_trans_list.append(RectTransferInfo((4,20,4,12),(4,20,4,12),True)) # leg.r (True since on legs, right one must be flipped manually) rect_trans_list.append(RectTransferInfo((4,20,4,12),(4,20,4,12),True)) # leg.r (True since on legs, right one must be flipped manually)
#yes, the flipping is different for leg vs arm #yes, the flipping is different for leg vs arm
image_size = (64,32)
preview_size = (16,32)
class USkinInfo: class USkinInfo:
author_string = None author_string = None
@ -60,16 +87,18 @@ class USkinInfo:
pass pass
def set_from_skindb_skin_file_path(self, file_path, license_name_string): def set_from_skindb_skin_file_path(self, file_path, license_name_string):
self.author_string = None
self.name_string = None
self.license_name_string=license_name_string
self.source_image_path = file_path self.source_image_path = file_path
file_name = os.path.basename(self.source_image_path) file_name = os.path.basename(self.source_image_path)
self.license_name_string=license_name_string
noext_name = file_name noext_name = file_name
dot_index = file_name.rfind(".") dot_index = file_name.rfind(".")
if dot_index>=0: if dot_index>=0:
noext_name = file_name[:dot_index] noext_name = file_name[:dot_index]
by_string = "_by_" by_string = "_by_"
by_index = noext_name.rfind(by_string) by_index = noext_name.rfind(by_string)
print("noext_name:"+noext_name) #print("noext_name:"+noext_name)
if by_index>=0: if by_index>=0:
self.author_string = noext_name[by_index+len(by_string):] self.author_string = noext_name[by_index+len(by_string):]
self.name_string = noext_name[:by_index] self.name_string = noext_name[:by_index]
@ -77,24 +106,56 @@ class USkinInfo:
self.author_string = "<unknown>" self.author_string = "<unknown>"
self.name_string = noext_name self.name_string = noext_name
def set_from_metadata_path(self, metadata_file_path):
is_ok = False
self.name_string = None
self.author_string = None
self.license_name_string = None
if os.path.isfile(metadata_file_path):
ins = open(metadata_file_path, 'r')
line = True
counting_number = 1
while line:
participle = "reading line "+str(counting_number)
line = ins.readline()
if line:
line_strip = line.strip()
if len(line_strip)>0:
if self.name_string is None:
self.name_string = line_strip
elif self.author_string is None:
self.author_string = line_strip
is_ok = True
elif self.license_name_string is None:
self.license_name_string = line_strip
counting_number += 1
ins.close()
if not is_ok:
raw_input("ERROR: Did not find line 2 for name_string in '"+metadata_file_path+"'")
else:
raw_input("Missing '"+metadata_file_path+"' -- press enter to continue...")
return is_ok
def print_dump(self, min_indent): def print_dump(self, min_indent):
print(min_indent+"author_string:"+self.author_string)
print(min_indent+"name_string:"+self.name_string) print(min_indent+"name_string:"+self.name_string)
print(min_indent+"author_string:"+self.license_name_string) print(min_indent+"author_string:"+self.author_string)
print(min_indent+"license_name_string:"+self.license_name_string)
def _save_metadata(self, metadata_file_path): def _save_metadata(self, metadata_file_path):
outs = open(metadata_file_path, 'w') outs = open(metadata_file_path, 'w')
outs.write(self.author_string+"\n")
outs.write(self.name_string+"\n") outs.write(self.name_string+"\n")
outs.write(self.author_string+"\n")
outs.write(self.license_name_string+"\n") outs.write(self.license_name_string+"\n")
outs.close() outs.close()
def push_next_skin_file(self): def push_next_skin_file_if_self_is_new(self):
result = False
os.listdir(textures_path) os.listdir(textures_path)
this_index = 1 this_index = 1
while os.path.isfile( get_png_path_from_index(this_index) ): while os.path.isfile( get_png_path_from_index(this_index) ):
this_index += 1 this_index += 1
if not skin_exists(self.name_string, self.author_string):
#image_name = get_png_name_from_index(this_index) #image_name = get_png_name_from_index(this_index)
image_path = get_png_path_from_index(this_index) image_path = get_png_path_from_index(this_index)
metadata_name = get_metadata_name_from_index(this_index) metadata_name = get_metadata_name_from_index(this_index)
@ -102,12 +163,14 @@ class USkinInfo:
#preview_name = get_preview_name_from_index(this_index) #preview_name = get_preview_name_from_index(this_index)
preview_path = get_preview_path_from_index(this_index) preview_path = get_preview_path_from_index(this_index)
print("saving to image_path:"+image_path) print("saving to image_path:"+image_path)
print("saving to preview_path:"+preview_path)
print("saving to metadata_path:"+metadata_path) print("saving to metadata_path:"+metadata_path)
self._save_metadata(metadata_path)
#actually save the skin and metadata files: #actually save the skin and metadata files:
print("Not yet implemented.") print("saving to preview_path:"+preview_path)
self.print_dump(" ") self.print_dump(" ")
shutil.copy(self.source_image_path, image_path)
result = True
preview_im = Image.new("RGBA", preview_size, "#000000") preview_im = Image.new("RGBA", preview_size, "#000000")
fill_image_with_transparency(preview_im) fill_image_with_transparency(preview_im)
skin_im = Image.open(open(self.source_image_path, 'rb')) # double-open to make sure file is finished writing skin_im = Image.open(open(self.source_image_path, 'rb')) # double-open to make sure file is finished writing
@ -117,13 +180,80 @@ class USkinInfo:
#im.load() # make sure PIL has read the data #im.load() # make sure PIL has read the data
#fp.close() #fp.close()
for rect_trans in rect_trans_list: for rect_trans in rect_trans_list:
partial_im = skin_im.crop(rect_trans.source_rect_tuple) source_left, source_top, source_right, source_bottom = rect_trans.source_rect_tuple
left, top, right, bottom = rect_trans.dest_rect_tuple source_right+=source_left
preview_im.paste(partial_im, (left, top)) source_bottom+=source_top
pil_source_rect_tuple = source_left, source_top, source_right, source_bottom
partial_im = skin_im.crop(pil_source_rect_tuple)
dest_left, dest_top, dest_right, dest_bottom = rect_trans.dest_rect_tuple
dest_right+=dest_left
dest_bottom+=dest_top
pil_dest_rect_tuple = dest_left, dest_top, dest_right, dest_bottom
preview_im.paste(partial_im, (dest_left, dest_top))
debug_img_name="debug "+str(pil_source_rect_tuple)+".png"
if visual_debug_enable:
#if visual_debug_enable:
#raw_input("Press enter to save temp cropping images to '"+dump_path+"'")
if not os.path.isdir(dump_path):
os.makedirs(dump_path)
debug_img_path = os.path.join(dump_path, debug_img_name)
#if not os.path.isfile(debug_img_path):
print(" saving "+debug_img_path)
print(" (after pasting to destination rect "+str(pil_dest_rect_tuple)+")")
partial_im.save(debug_img_path)
preview_im.save(preview_path) preview_im.save(preview_path)
print("Saved preview to '"+preview_path+"'") print("Saved preview to '"+preview_path+"'")
print("") print("")
else:
print("Skin already exists: "+self.name_string+" by "+self.author_string)
def get_png_path_from_index(this_index):
return os.path.join(textures_path, get_png_name_from_index(this_index))
def get_png_name_from_index(this_index):
return image_prefix+str(this_index)+".png"
def get_preview_path_from_index(this_index):
return os.path.join(textures_path, get_preview_name_from_index(this_index))
def get_preview_name_from_index(this_index):
return image_prefix+str(this_index)+preview_suffix+".png"
def get_metadata_name_from_index(this_index):
return image_prefix+str(this_index)+".txt"
def get_metadata_path_from_index(this_index):
return os.path.join(meta_path, get_metadata_name_from_index(this_index))
print("Loading existing skin metadata to avoid duplication (but ignoring metadata files that do not have pngs)")
si_list = list()
this_index = 1
while os.path.isfile( get_png_path_from_index(this_index) ):
existing_metadata_path = get_metadata_path_from_index(this_index)
this_si = USkinInfo()
is_ok=this_si.set_from_metadata_path(get_metadata_path_from_index(this_index))
if is_ok:
#if not skin_exists(this_si.name_string, this_si.author_string):
si_list.append(this_si)
#if verbose_enable:
# print("Added skin metadata:")
# this_si.print_dump(" ")
this_index += 1
print(" Found metadata for "+str(len(si_list))+" png file(s).")
print(" The functions in "+__file__+" are now ready.")
print(" * These functions mark destination as '"+default_license_string+"' license unless you")
print(" first change the global default_license_string variable")
print(" in your program that has:")
print(" from u_skin_adder import *")
print(" * Skin filename should include _by_ (with underscores) to specify author.")
print(" * Examples:")
print(" load_new_skins_from_folder(folder_path)")
print(" add_skin_if_new(file_path)")
def fill_image_with_transparency(im): def fill_image_with_transparency(im):
#modified version of: unutbu. "Python PIL: how to make area transparent in PNG? (answer 7 Dec 2010 at 19:08)" <http://stackoverflow.com/questions/4379978/python-pil-how-to-make-area-transparent-in-png>. 7 Dec 2010. 8 Apr 2016. #modified version of: unutbu. "Python PIL: how to make area transparent in PNG? (answer 7 Dec 2010 at 19:08)" <http://stackoverflow.com/questions/4379978/python-pil-how-to-make-area-transparent-in-png>. 7 Dec 2010. 8 Apr 2016.
@ -141,38 +271,80 @@ def fill_image_with_transparency(im):
im.putalpha(mask) im.putalpha(mask)
#im.save('/tmp/output.png') #im.save('/tmp/output.png')
def get_png_path_from_index(this_index):
return os.path.join(textures_path, get_png_name_from_index(this_index))
def get_png_name_from_index(this_index): show_no_dest_warnings = True
return image_prefix+str(this_index)+".png" def skin_exists(name_string, author_string):
global show_no_dest_warnings
#global si_list
result = False
count = 0
#if verbose_enable:
# print(" Checking for existing "+name_string+" by "+author_string+":")
for si in si_list:
if si.name_string==name_string and si.author_string==author_string:
result = True
break
#else:
# if verbose_enable:
# print(" "+si.name_string+" by "+si.author_string+" is not it.")
count += 1
if not result:
if count<1:
#if show_no_dest_warnings:
raw_input("WARNING: 0 skins during skin_exists check. Press enter to continue...")
#show_no_dest_warnings = False
return result
def get_preview_path_from_index(this_index):
return os.path.join(textures_path, get_preview_name_from_index(this_index))
def get_preview_name_from_index(this_index):
return image_prefix+str(this_index)+preview_suffix+".png"
def get_metadata_name_from_index(this_index): #if os.path.isdir(meta_path):
return image_prefix+str(this_index)+".txt" #
#accepts CC BY 3.0 skins, and looks for _by_ in name, followed by author (otherwise puts <unknown> on author line of metadata txt file in u_skin/meta folder)
def add_skin_if_new(sub_path):
this_usi = USkinInfo()
this_usi.set_from_skindb_skin_file_path(sub_path, default_license_string)
return this_usi.push_next_skin_file_if_self_is_new()
if os.path.isdir(meta_path): def load_new_skins_from_folder(in_path):
#in_path = os.path.join(profile_path,"Downloads\\skins-to-add")
#if not os.path.isdir(in_path):
# in_path = "."
# print("Looking for new textures in current directory")
if not skin_exists("Sam 0","Jordach"):
print("")
print("WARNING: Missing 'Sam 0' by 'Jordach'")
print(" among "+str(len(si_list))+" skin(s).")
print(" Only continue if you expected that skin to not be there.")
raw_input(" Press enter to continue...")
if os.path.isdir(meta_path):
if os.path.isdir(textures_path): if os.path.isdir(textures_path):
if os.path.isdir(in_path): if os.path.isdir(in_path):
folder_path = in_path folder_path = in_path
new_count = 0
found_count = 0
old_count = 0
for sub_name in os.listdir(folder_path): for sub_name in os.listdir(folder_path):
sub_path = os.path.join(folder_path,sub_name) sub_path = os.path.join(folder_path,sub_name)
if os.path.isfile(sub_path): if os.path.isfile(sub_path):
if (sub_name[:1]!="."): if (sub_name[:1]!="."):
if len(sub_name)>4 and sub_name[-4:]==".png": if len(sub_name)>4 and sub_name[-4:]==".png":
this_usi = USkinInfo() found_count += 1
this_usi.set_from_skindb_skin_file_path(sub_path, default_license) if add_skin_if_new(sub_path):
this_usi.push_next_skin_file() new_count += 1
else:
old_count += 1
print("Added "+str(new_count)+" new skins(s) among "+str(found_count)+" discovered in specified source folder.")
if old_count>0:
print(" "+str(old_count)+" (with matching author and title) were already in destination.")
else: else:
print("ERROR: Failed to get new texture files since in_path does not exist:'"+in_path+"'") print("ERROR: Failed to get new texture files since in_path does not exist:'"+in_path+"'")
else: else:
print("ERROR: missing textures_path (tried '"+textures_path+"')") print("ERROR: missing textures_path (tried '"+textures_path+"')")
else: else:
print("ERROR: missing meta_path (tried '"+meta_path+"')") print("ERROR: missing meta_path (tried '"+meta_path+"')")
input("Press return to exit.") #raw_input("Press return to exit.")

Loading…
Cancel
Save