Skip to content

Instantly share code, notes, and snippets.

@rodolpheh
Created April 27, 2019 15:30
Show Gist options
  • Save rodolpheh/b044300ab0477ca5e713f4b55a10f600 to your computer and use it in GitHub Desktop.
Save rodolpheh/b044300ab0477ca5e713f4b55a10f600 to your computer and use it in GitHub Desktop.
Killing Floor 2 map configuration generator
#!/usr/bin/python3
'''
# This is the example configuration given by the wiki :
[KF-Default KFMapSummary]
MapName=KF-Default
ScreenshotPathName=UI_MapPreview_TEX.UI_MapPreview_Placeholder
# This is the default GameMapCycles found in DefaultGame.ini configuration file :
GameMapCycles=(Maps=("KF-Airship","KF-Bioticslab","KF-BlackForest","KF-BurningParis","KF-Catacombs","KF-ContainmentStation","KF-DieSector","KF-EvacuationPoint","KF-Farmhouse","KF-HostileGrounds","KF-InfernalRealm","KF-KrampusLair","KF-Lockdown","KF-MonsterBall","KF-Nightmare","KF-Nuked","KF-Outpost","KF-PowerCore_Holdout","KF-Prison","KF-Santasworkshop","KF-ShoppingSpree", "KF-Spillway", "KF-TheDescent","KF-TragicKingdom","KF-VolterManor","KF-ZedLanding"))
'''
import os
import argparse
import configparser
game_map_prefix = 'GameMapCycles=(Maps=("KF-Airship","KF-Bioticslab","KF-BlackForest","KF-BurningParis","KF-Catacombs","KF-ContainmentStation","KF-DieSector","KF-EvacuationPoint","KF-Farmhouse","KF-HostileGrounds","KF-InfernalRealm","KF-KrampusLair","KF-Lockdown","KF-MonsterBall","KF-Nightmare","KF-Nuked","KF-Outpost","KF-PowerCore_Holdout","KF-Prison","KF-Santasworkshop","KF-ShoppingSpree", "KF-Spillway", "KF-TheDescent","KF-TragicKingdom","KF-VolterManor","KF-ZedLanding"'
game_map_suffix = '))'
workshop_folder = os.path.expanduser('~/.steam/steamapps/workshop/content/232090')
class MapConfig:
def __init__(self, name=None, screenshot_path=None, association=None):
self.name = name
self.screenshot_path = screenshot_path
self.association = association
@staticmethod
def generate_config(map_name, scr_path=None, assoc=None):
ret = ""
ret += "[{} KFMapSummary]\n".format(map_name)
ret += "MapName={}\n".format(map_name)
if scr_path is not None:
ret += "ScreenshotPathName={}\n".format(scr_path)
if assoc is not None:
ret += "MapAssociation={}\n".format(assoc)
return ret
@staticmethod
def generate_dict(map_name, scr_path=None, assoc=None):
ret = {}
ret['section'] = "{} KFMapSummary".format(map_name)
ret['options'] = []
option = {'option': 'MapName'}
option['value'] = map_name
ret['options'].append(option)
if scr_path is not None:
option = {'option': 'ScreenshotPathName'}
option['value'] = scr_path
ret['options'].append(option)
if assoc is not None:
option = {'option': 'MapAssociation'}
option['value'] = assoc
ret['options'].append(option)
return ret
def __str__(self):
return MapConfig.generate_config(self.name, self.screenshot_path, self.association)
def to_dict(self):
return MapConfig.generate_dict(self.name, self.screenshot_path, self.association)
def get_map_name(path):
return path.split('/')[-1].split('.')[0]
def search_kfm(folder, files=None):
if files is None:
files = []
ls = os.listdir(folder)
for element in ls:
element = folder + "/" + element
if os.path.isfile(element):
if element.split('.')[-1] == "kfm":
files.append(element.split('/')[-1])
elif os.path.isdir(element):
search_kfm(element, files)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Generate Killing Floor 2 maps configuration for self-hosted servers')
parser.add_argument('--base', dest='base_folder', action='store', default=workshop_folder,
help='The workshop folder where we\'ll search for the maps')
parser.add_argument('--dump', dest='dump', action='store_true')
parser.add_argument('-c', dest='config_file', action='store', default="DefaultGame.ini")
args = parser.parse_args()
files = []
search_kfm(args.base_folder, files)
maps = []
game_map = game_map_prefix
for file in files:
map_name = get_map_name(file)
game_map += ",\"{}\"".format(map_name)
map_obj = MapConfig(map_name)
maps.append(map_obj)
game_map += game_map_suffix
if args.dump:
for map_obj in maps:
print(map_obj)
print(game_map)
exit(0)
print("\n=============================================================")
print("Editing configuration file")
print("=============================================================\n")
config = configparser.ConfigParser(comment_prefixes=('#', ';', '!', '+'), strict=False)
config.optionxform = str
try:
config.read(args.config_file)
except configparser.DuplicateOptionError as DuplicateError:
print("Uhoh ! There is a duplicate ! Aaaaaargh !")
print(DuplicateError.lineno)
for map_obj in maps:
print("Do you want to add the map {} ? [Y/n]".format(map_obj.name), end=' ')
choice = input()
if choice == "n":
continue
map_dict = map_obj.to_dict()
config.add_section(map_dict['section'])
for option in map_dict['options']:
config[map_dict['section']][option['option']] = option['value']
config["KFGame.KFGameInfo"]["GameMapCycles"] = game_map
with open('out.ini', 'w') as configfile:
config.write(configfile)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment