def modify_types(directory): with open( pathlib.Path(resourcesdir.get(), 'modifications/server/types_config.json')) as f: type_config = json.load(f) for action in type_config: log.info(action.get('description')) matching = action.get('matching') if action['action'] == 'remove': process_type = remove elif action['action'] == 'ratio': process_type = ratio else: process_type = modify for m in matching: process_type(matching=m, modification=action.get('modification', dict())) with open( pathlib.Path(resourcesdir.get(), 'modifications/server/types_universal.json')) as f: type_universal_config = json.load(f) ratio_modifier = type_universal_config.get('ratio', 1) matching = {"nominal": "^[^0]"} m = matching_model.Match(matching) count = 0 for t in types.get().getroot(): if m.match(t) and t.find('nominal') is not None: count += 1 t.find('nominal').text = str( max(1, int(ratio_modifier * int(t.find('nominal').text)))) t.find('min').text = str( max(1, int(ratio_modifier * int(t.find('min').text)))) log.info('modified {} items with ratio {}'.format(count, ratio_modifier))
def server_dz_config(directory): file_writing.copy( pathlib.Path(resourcesdir.get(), 'modifications/server/serverDZ.cfg'), pathlib.Path(directory, 'serverDZ.cfg')) file_writing.copy( pathlib.Path(resourcesdir.get(), 'modifications/server/serverDZ.cfg'), pathlib.Path(directory, 'serverDZ.cfg.active'))
def trader_objects_config(directory): to = objects.Config() with open( pathlib.Path(resourcesdir.get(), 'modifications/mods/trader/locations.json')) as f: locations = json.load(f) with open( pathlib.Path(resourcesdir.get(), 'modifications/mods/trader/outfits.json')) as f: outfits = json.load(f) for name, l_config in locations.items(): log.info('processing {}'.format(name)) for trader_name, t in l_config.items(): new_trader = objects.Trader(t.get('marker'), t.get('location'), t.get('safezone', 200)) new_object = objects.Object( outfits.get(trader_name).get('class'), t.get('location'), t.get('o')) for attachment in outfits.get(trader_name).get('attachments'): new_object.attachments.append(objects.Attachment(attachment)) if 'vehicle' in t: raw_vehicle = t.get('vehicle') new_trader.set_vehicle( objects.Vehicle(raw_vehicle.get('location'), raw_vehicle.get('o'))) to.objects.extend( get_cones_for_vehicle(raw_vehicle.get('location'), raw_vehicle.get('o'))) to.traders.append(new_trader) to.objects.append(new_object) with file_writing.f_open(pathlib.Path(directory, 'TraderObjects.txt'), mode='w') as f: f.write(to.generate())
def trader_items(directory): with open( pathlib.Path(resourcesdir.get(), 'modifications/mods/trader/inventory.json')) as f: inventory = json.load(f) traders_config = config.Config() trader_names = [ TraderName.AUTO, TraderName.CLOTHING, TraderName.FOOD, TraderName.WEAPONS, TraderName.ACCESSORIES, TraderName.TOOLS, TraderName.BM ] traders = {} for trader_name in trader_names: categories = inventory.get(trader_name, list()) current_trader = config.Trader(trader_name) traders[trader_name] = current_trader traders_config.traders.append(current_trader) for category in categories: new_category = config.Category(category.get('category')) current_trader.categories.append(new_category) build_category(new_category, category) log.info('added {} items to {}'.format(len( new_category.items), (trader_name, new_category.name))) add_dynamic(traders) with file_writing.f_open(pathlib.Path(directory, 'TraderConfig.txt'), mode='w') as f: f.write(traders_config.generate())
def spawnable_types_config(directory): """ This configuration operates in an overriding fashion. That is, if a preset or list of items is specified for a type in the config, any existing entries for that type with the same tag and attribute will be erased. """ p = pathlib.Path(deploydir.get(), 'mpmissions', mission.get(), 'cfgspawnabletypes.xml') with open(p) as f: # The parser in ElementTree was having trouble with the comments in the xml file # So, we're removing them manually beforehand raw = f.read() raw = re.sub(r'<!--.*-->', '', raw) spawnable_xml = ElementTree.fromstring(raw) with open(pathlib.Path(resourcesdir.get(), 'modifications/server/spawnable_types.json')) as f: spawnable_modifications = json.load(f) for type_config in spawnable_modifications: if len(db_types.get().getroot().findall('.//type[@name="{}"]'.format(type_config.get('type')))) == 0: continue types = spawnable_xml.findall('.//type[@name="{}"]'.format(type_config.get('type'))) if len(types) == 0: new_type = ElementTree.SubElement(spawnable_xml, 'type', dict(name=type_config.get('type'))) types = [new_type] for t in types: if 'cargo_presets' in type_config: handle_presets(t, 'cargo', type_config.get('cargo_presets')) if 'attachments_presets' in type_config: handle_presets(t, 'attachments', type_config.get('attachments_presets')) if 'cargo_items' in type_config: handle_items(t, 'cargo', type_config.get('cargo_items')) if 'attachments' in type_config: handle_items(t, 'attachments', type_config.get('attachments')) with file_writing.f_open(pathlib.Path(directory, 'cfgspawnabletypes.xml'), mode='w') as f: f.write(file_writing.convert_to_string(spawnable_xml))
def remove_spawns_outside_radius(directory): with open( pathlib.Path(resourcesdir.get(), 'modifications/server/types_universal.json')) as f: type_universal_config = json.load(f) radius = type_universal_config.get('limit_spawn_locations_radius', 0) if radius <= 0: return p = pathlib.Path(deploydir.get(), 'mpmissions', mission.get(), 'mapgrouppos.xml') count = 0 areas = list(mark[1] for mark in locations.marks[:4]) mapgroups = ElementTree.parse(p).getroot() for group in mapgroups.findall('.//group'): raw = group.get('pos') # log.info('{} {}'.format(group.get('name'), raw)) x, y, z = (float(i) for i in raw.split(' ')) is_good = False for position in areas: if locations.overlaps(position, radius, x, z, 1): is_good = True if not is_good: mapgroups.remove(group) count += 1 log.debug('removed group {}, {}, {}'.format( group.get('name'), x, z)) if count > 0: log.info('removed {} groups from {}'.format(count, p.name)) with file_writing.f_open(pathlib.Path(directory, p.name), mode='w') as f: f.write(file_writing.convert_to_string(mapgroups))
def random_presets_config(directory): p = pathlib.Path(deploydir.get(), 'mpmissions', mission.get(), 'cfgrandompresets.xml') with open(p) as f: # The parser in ElementTree was having trouble with the comments in the xml file # So, we're removing them manually beforehand raw = f.read() raw = re.sub(r'<!--.*-->', '', raw) presets_xml = ElementTree.fromstring(raw) with open( pathlib.Path(resourcesdir.get(), 'modifications/server/random_presets.json')) as f: presets_modifications = json.load(f) for entry in presets_modifications: if 'cargo' in entry: cargo = entry.get('cargo') if 'chance' in entry: for preset in presets_xml.findall( f'.//cargo[@name="{cargo}"]'): preset.set('chance', entry.get('chance')) for item in entry.get('items'): for preset in presets_xml.findall( './/cargo[@name="{}"]//item[@name="{}"]'.format( cargo, item.get('name'))): preset.set('chance', item.get('chance')) if 'attachments' in entry: attachments = entry.get('attachments') for item in entry.get('items'): for preset in presets_xml.findall( './/attachments[@name="{}"]//item[@name="{}"]'.format( attachments, item.get('name'))): preset.set('chance', item.get('chance')) with file_writing.f_open(pathlib.Path(directory, 'cfgrandompresets.xml'), mode='w') as f: f.write(file_writing.convert_to_string(presets_xml))
def add_dynamic(traders): with open( pathlib.Path( resourcesdir.get(), 'modifications/mods/trader/inventory_dynamic.json')) as f: trader_config = json.load(f) temp_traders = {} for entry in trader_config: current_traders = entry.get('trader') if not isinstance(current_traders, list): current_traders = [current_traders] for trader_name in current_traders: if trader_name not in temp_traders: temp_traders[trader_name] = list() category_name = entry.get('category') log.info('processing {}'.format((trader_name, category_name))) categories = {} temp_traders[trader_name].append(categories) for item in entry.get('items'): expanded = {} matching = item.get('matching') buy = item.get('buy') sell = item.get('sell') quantity = item.get('quantity', None) item_type = get_item_type_for_name(item.get('item_class')) if matching is not None: match = matching_model.Match(matching) for t in types.get().getroot(): result = match.match(t) if result: items = expanded.get(result.groups.get('captured'), list()) items.append( item_type(t.get('name'), buy, sell, quantity)) expanded[result.groups.get('captured')] = items else: name = item.get('name') expanded[None] = [item_type(name, buy, sell, quantity)] for key in expanded: current_cat_name = category_name.format(captured=key) current_cat = categories.get( current_cat_name, config.Category(current_cat_name)) if quantity is not None: current_cat.items += [ item_type(i.name, buy, sell, quantity) for i in expanded[key] if i not in current_cat ] else: current_cat.items += [ item_type(i.name, buy, sell) for i in expanded[key] if i not in current_cat ] categories[current_cat_name] = current_cat for key in temp_traders: for cat_set in temp_traders[key]: for c in cat_set.values(): log.info('added {} dynamic items to {}'.format( len(c.items), (key, c.name))) traders[key].categories += cat_set.values()
def initialize(): with open( pathlib.Path(resourcesdir.get(), 'modifications/server/locations.json')) as f: location_data = json.load(f) global marks marks = [(l.get('name'), Position(l.get('x'), l.get('z'))) for l in location_data]
def globals_config(directory): globals_xml = ElementTree.parse( pathlib.Path(deploydir.get(), 'mpmissions', mission.get(), 'db/globals.xml')) with open(pathlib.Path(resourcesdir.get(), 'modifications/server/globals.json')) as f: globals_modifications = json.load(f) for k, v in globals_modifications.items(): item = globals_xml.getroot().find('.//var[@name="{}"]'.format(k)) item.set('value', str(v)) with file_writing.f_open(pathlib.Path(directory, 'globals.xml'), mode='w') as f: f.write(file_writing.convert_to_string(globals_xml.getroot()))
def omega_config(directory): with open( pathlib.Path(resourcesdir.get(), 'modifications/omega/omega.json')) as f: cfg = json.load(f) cfg['cftools']['service_api_key'] = auth.get()['cf']['service_api_key'] cfg['cftools']['service_id'] = auth.get()['cf']['service_id'] cfg['general']['pre_execution_script'] = { 'enabled': True, 'execution_time_limit': 10, 'path': auth.get()['preexec']['path'] } with open(pathlib.Path(resourcesdir.get(), 'modifications/omega/mods.json')) as f: mods_config = json.load(f) cfg['mods'] = mods_config with file_writing.f_open(pathlib.Path(directory, 'omega.cfg'), mode='w') as f: json.dump(cfg, f, indent=2)
def main(): parser = argparse.ArgumentParser(description='Automate configuration') parser.add_argument('-c', dest='clean', action='store_true', help='clean generated') parser.add_argument('-d', dest='deploy', required=True, help='deploy directory containing the original dayz server files') parser.add_argument('-a', dest='auth', required=True, help='auth config file') parser.add_argument('-o', dest='output', help='output destination directory', default=outdir.get()) parser.add_argument('-v', dest='verbosity', help='verbosity of the output', action='count', default=0) parser.add_argument('-r', dest='resources', help='resources directory to use', default=resourcesdir.get()) parser.add_argument('-m', dest='mission', help='mission name', default=mission.get()) args = parser.parse_args() log_level = logging.INFO if args.verbosity > 0: log_level = logging.DEBUG logging.basicConfig(level=log_level, format='%(asctime)s %(levelname)s %(name)s - %(message)s') log = logging.getLogger(__name__) if args.clean: clean() # Initialize all the global resources outdir.set(args.output) deploydir.set(args.deploy) resourcesdir.set(args.resources) mission.set(args.mission) types.set(ElementTree.parse(pathlib.Path(deploydir.get(), 'mpmissions', mission.get(), 'db/types.xml'))) auth.set(json.load(open(args.auth))) locations.initialize() with open(pathlib.Path(resourcesdir.get(), 'modifications/omega/mods.json')) as f: mods_config = json.load(f) for mod in mods_config: mods.add(mod.get('directory')) # Scan the configurations and apply them configuration.scan() for c in configs.get(): c() # Unregistered configurations that have a special order requirement from carim.configuration.mods.trader import trader from carim.configuration.server import missions from carim.configuration.server import types as modify_types modify_types.modify_types() missions.sort_and_write_types_config() trader.trader_items() log.info('errors {}'.format(len(errors.get()))) for e in errors.get(): log.error(e) log.info('processed {} registered configurations'.format(len(configs.get()))) log.info('skipped {} configurations'.format(configs.get_skipped())) log.debug('order: {}'.format(json.dumps([f.__name__ for f in configs.get()], indent=2))) log.info('complete')
def omega_manager(directory): cfg = None with file_writing.f_open( pathlib.Path(resourcesdir.get(), 'modifications/omega/manager.cfg')) as f: cfg = json.load(f) cfg['steam'] = { 'username': auth.get()['steam']['username'], 'api_key': auth.get()['steam']['api_key'], 'password': auth.get()['steam']['password'], 'mobile_authenticator': False } with file_writing.f_open(pathlib.Path(directory, 'manager.cfg'), mode='w') as f: json.dump(cfg, f, indent=2)
def simple_base_profile(directory): with open('resources/original-mod-files/Simple Base/types.xml') as f: raw = '<types>' + f.read() + '</types>' new_types = ElementTree.fromstring(raw) types.get().getroot().extend(new_types) with open('resources/original-mod-files/Simple Base/ServerProfileFolder/SimpleBase/config.txt') as f: lines = f.readlines() config = model.Config() config.parse_defaults(lines) with open(pathlib.Path(resourcesdir.get(), 'modifications/mods/simple_base/config.json')) as f: changes = json.load(f) for k, v in changes.items(): config.set(k, v) with file_writing.f_open(pathlib.Path(directory, 'config.txt'), mode='w') as f: f.write(config.generate())
def territory_config(directory): with open(pathlib.Path(resourcesdir.get(), 'modifications/server/territories.json')) as f: territories_modifications = json.load(f) for p in pathlib.Path(deploydir.get(), 'mpmissions', mission.get(), 'env').glob('*.xml'): filename = p.name territory = ElementTree.parse(p).getroot() if filename in territories_modifications.get('ratio', dict()): ratio = territories_modifications.get('ratio').get(filename) log.info('applying ratio of {} to {}'.format(ratio, filename)) for zone in territory.findall('.//zone'): dmin = zone.get('dmin') dmax = zone.get('dmax') zone.set('dmin', str(math.floor(int(dmin) * ratio))) zone.set('dmax', str(math.floor(int(dmax) * ratio))) if filename in territories_modifications.get('radius_ratio', dict()): ratio = territories_modifications.get('radius_ratio').get(filename) log.info('applying radius ratio of {} to {}'.format(ratio, filename)) for zone in territory.findall('.//zone'): r = zone.get('r') zone.set('r', str(math.floor(float(r) * ratio))) if filename in territories_modifications.get('blanket', dict()): params = territories_modifications.get('blanket').get(filename) new_territory = ElementTree.Element('territory', attrib=dict(color='1910952871')) count = 0 for x in range(500, 12600, 1000): for z in range(3750, 14850, 1000): count += 1 ElementTree.SubElement(new_territory, 'zone', attrib={ 'name': params.get('name'), 'smin': '0', 'smax': '0', 'dmin': params.get('dmin'), 'dmax': params.get('dmax'), 'x': str(x), 'z': str(z), 'r': '500' }) territory.append(new_territory) log.info('added {} zones in a blanket to {}'.format(count, filename)) if '@Trader' in mods.get(): remove_zones_if_near_traders(territory, filename) with file_writing.f_open(pathlib.Path(directory, filename), mode='w') as f: f.write(file_writing.convert_to_string(territory))
def events_config(directory): events_xml = ElementTree.parse( pathlib.Path(deploydir.get(), 'mpmissions', mission.get(), 'db/events.xml')) with open(pathlib.Path(resourcesdir.get(), 'modifications/server/events.json')) as f: events_modifications = json.load(f) for mod in events_modifications: name_re = re.compile(mod.get('name')) for event in events_xml.getroot(): if name_re.match(event.get('name')): ratio = mod.get('ratio') if ratio > 0: event.find('active').text = '1' for item in ('nominal',): i = event.find(item) i.text = str(math.floor(max(1, int(i.text)) * ratio)) else: event.find('active').text = '0' with file_writing.f_open(pathlib.Path(directory, 'events.xml'), mode='w') as f: f.write(file_writing.convert_to_string(events_xml.getroot()))
def airdrop(directory): with open('resources/original-mod-files/Airdrop/AirdropSettings.json') as f: airdrop_settings = json.load(f) with open(pathlib.Path(resourcesdir.get(), 'modifications/mods/airdrop/modifications.json')) as f: airdrop_setting_modifications = json.load(f) # http://games.digiacom.com/Airdrop_Server_Guide.pdf for setting in ('Controls', 'Map', 'Aircraft', 'Messages', 'Container'): for k, v in airdrop_setting_modifications.get(setting).items(): airdrop_settings[setting][k] = v drops = [] drop_defaults = airdrop_setting_modifications.get('DropZoneDefaults') for drop in airdrop_setting_modifications.get('DropZones'): drops.append({**drop, **drop_defaults}) airdrop_settings['DropZones'] = drops drop_types = [] drop_type_defaults = airdrop_setting_modifications.get('DropTypeDefaults') for drop_type in airdrop_setting_modifications.get('DropTypes'): drop_types.append({**drop_type, **drop_type_defaults}) airdrop_settings['DropTypes'] = drop_types with file_writing.f_open(pathlib.Path(directory, 'AirdropSettings.json'), mode='w') as f: json.dump(airdrop_settings, f, indent=2)
def map_config(directory): replacement = pathlib.Path(resourcesdir.get(), 'modifications/server/areaflags.map') if replacement.exists(): file_writing.copy(replacement, pathlib.Path(directory, 'areaflags.map'))
def server_panel_coniguration(directory): file_writing.copy( pathlib.Path(resourcesdir.get(), 'modifications/mods/server_panel/config.json'), pathlib.Path(directory, 'ServerPanel.json'))