Created
June 26, 2025 07:05
-
-
Save murphyslaw/6ffdb9558206bc01a38aec9a8f33c332 to your computer and use it in GitHub Desktop.
EVE Frontier Icon Extractor (Windows)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
EVE Frontier icon extractor. | |
This script copies all icon image files from the EVE Frontier (Windows) game | |
client to a given output directory. Only icons for types that are either inputs | |
or outputs of a blueprint are considered. The possible blueprints are determined | |
by a list of EVE Frontier structure ids. | |
The script is based on the output of the Phobos project JSON files. See | |
https://github.com/pyfa-org/Phobos for more details and instructions. | |
In particular, the Phobos executable needs to be run with at least: | |
--list="types, typelist, blueprints, iconids" | |
The same JSON path given to the Phobos project (--json) for its output, should | |
be used for the --phobos command line option. | |
Hint: The list of relevant EVE Frontier structure ids can be adjusted in the | |
'structure_ids' variable definition. All available structure ids can be found in | |
the 'typelist.json' file in the output directory of the Phobos project. | |
Warning: The path given in the --output argument is emptied, so make sure to not | |
rely on its content. | |
Example Usage: | |
python frontier_icon_extractor.py --output="C:\\Users\\johndoe\\Downloads\\frontier-icons" --eve="C:\\Program Files\\EVE Frontier" --phobos="C:\\Users\\johndoe\\Downloads" | |
""" | |
import os | |
import argparse | |
import json | |
import shutil | |
from pathlib import Path | |
class ArgumentError(Exception): | |
'''Raised when command line arguments are missing.''' | |
pass | |
def parse_json_file(path): | |
'''Parse file as JSON.''' | |
with open(path, encoding='utf-8') as file: | |
return json.load(file) | |
def empty_path(path): | |
'''Delete all files and folders in a given directory.''' | |
if not os.path.isdir(path): | |
return | |
for filename in os.listdir(path): | |
file_path = os.path.join(path, filename) | |
try: | |
if os.path.isfile(file_path) or os.path.islink(file_path): | |
os.unlink(file_path) | |
elif os.path.isdir(file_path): | |
shutil.rmtree(file_path) | |
except Exception as e: | |
print('Failed to delete %s. Reson: %s' % (file_path, e)) | |
# Initialize command line argument parser | |
parser = argparse.ArgumentParser( | |
description='This script extracts EVE Frontier types icon files from the EVE Frontier (Windows) game client and copies them into an output directory.' | |
) | |
parser.add_argument('-e', '--eve', required=True, help = 'Path to EVE client\'s folder') | |
parser.add_argument('-p', '--phobos', required=True, help='Input folder for Phobos files') | |
parser.add_argument('-o', '--output', required=True, help='Output folder for the icon files') | |
parser.add_argument('-s', '--server', default='stillness', help='Server to pull data from. Default is "stillness"', choices=('stillness')) | |
args = parser.parse_args() | |
# Initialize path variables | |
path_eve = os.path.expanduser(args.eve) | |
path_output = os.path.expanduser(args.output) | |
path_phobos = os.path.expanduser(args.phobos) | |
path_res = os.path.join(path_eve, 'ResFiles') | |
# Initialize file variables | |
res_file_index_file = os.path.join(path_eve, args.server, 'resfileindex.txt') | |
types_file = os.path.join(path_phobos, 'fsd_binary', 'types.json') | |
icon_ids_file = os.path.join(path_phobos, 'fsd_binary', 'iconIds.json') | |
typelist_file = os.path.join(path_phobos, 'fsd_binary', 'typelist.json') | |
blueprints_file = os.path.join(path_phobos, 'fsd_lite', 'blueprints.json') | |
# Pare JSON files | |
types_json = parse_json_file(types_file) | |
icon_ids_json = parse_json_file(icon_ids_file) | |
typelist_json = parse_json_file(typelist_file) | |
blueprints_json = parse_json_file(blueprints_file) | |
# List of EVE Frontier structure ids | |
structure_ids = [814, 815, 816, 836, 837, 838, 840, 841, 842, 843, 844] | |
# Collect all structure blueprint ids | |
blueprint_ids = [] | |
for typelist_id, typelist in typelist_json.items(): | |
try: | |
included_type_ids = typelist['includedTypeIDs'] | |
if int(typelist_id) in structure_ids: | |
blueprint_ids.extend(included_type_ids) | |
except KeyError: | |
continue | |
# Collect all blueprint input and output type ids | |
types = [] | |
for blueprint_id in blueprint_ids: | |
blueprint = blueprints_json[str(blueprint_id)] | |
manufacturing = blueprint['activities']['manufacturing'] | |
for description in manufacturing['materials']: | |
types.append(description['typeID']) | |
for description in manufacturing['products']: | |
types.append(description['typeID']) | |
# Collect all type icon ids | |
icons = {} | |
for type_id in types: | |
try: | |
type = types_json[str(type_id)] | |
icon_id = type['iconID'] | |
icons[icon_ids_json[str(icon_id)]['iconFile'].lower()] = type_id | |
except KeyError: | |
continue | |
# Clear output location | |
empty_path(path_output) | |
# Parse resource index file and copy selected icons | |
file = open(res_file_index_file, encoding='utf-8') | |
for line in file: | |
# Only consider png image files | |
if not '.png' in line: | |
continue | |
# Retrieve source and target location | |
target_location, source_location, *_ = line.split(',') | |
# Only consider selected icons | |
try: | |
type_id = icons[target_location] | |
except KeyError: | |
continue | |
# Name the target file by their type id | |
target_file = f'type-{type_id}.png' | |
source = os.path.join(path_res, *source_location.split('/')) | |
target = os.path.join(path_output, target_file) | |
# Create required output directory if necessary | |
Path(path_output).mkdir(parents=True, exist_ok=True) | |
# Copy the image file to the output directory | |
print('Copy %s to %s' % (source, target)) | |
shutil.copy(source, target) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment