Files
my-botty/src/config.py
T
RB-Developmentandmgleed 5ae6194d23 gambling bugfix (#519)
* Update ui_manager.py

Fix for gambling issue. Looks like self._config.char["gamble_items"] always returns true. Therefore im checking if the first entry is empty and go for a not.
not self._config.char["gamble_items"][0]==""

* simplify

Co-authored-by: mgleed <[email protected]>
2022-02-06 12:09:50 -05:00

373 lines
18 KiB
Python

import configparser
import threading
import numpy as np
import os
import re
from dataclasses import dataclass
from logger import Logger
config_lock = threading.Lock()
@dataclass
class ItemProps:
pickit_type: int = 0
include: list[str] = None
exclude: list[str] = None
include_type: str = "OR"
exclude_type: str = "OR"
class Config:
data_loaded = False
# all configparser objects
_config = None
_game_config = None
_pickit_config = None
_shop_config = None
_transmute_config = None
_custom = None
# config data
general = {}
advanced_options = {}
gamble = {}
ui_roi = {}
ui_pos = {}
dclone = {}
routes = {}
routes_order = []
char = {}
items = {}
colors = {}
shop = {}
path = {}
blizz_sorc = {}
light_sorc = {}
nova_sorc = {}
hammerdin = {}
trapsin = {}
barbarian = {}
necro = {}
basic = {}
basic_ranged = {}
def __init__(self):
with config_lock:
if not Config.data_loaded:
Config.data_loaded = True
Config.load_data()
@staticmethod
def _select_val(section: str, key: str = None):
if section in Config._custom and key in Config._custom[section]:
return Config._custom[section][key]
elif section in Config._config:
return Config._config[section][key]
elif section in Config._pickit_config:
return Config._pickit_config[section][key]
elif section in Config._shop_config:
return Config._shop_config[section][key]
else:
return Config._game_config[section][key]
@staticmethod
def parse_item_config_string(key: str = None) -> ItemProps:
string = Config._select_val("items", key).upper()
return Config.string_to_item_prop (string)
@staticmethod
def string_to_item_prop (string: str) -> ItemProps:
item_props = ItemProps()
brk_on = 0
brk_off = 0
section = 0
counter = 0
start_section = 0
start_item = 0
include_list = []
exclude_list = []
for char in string:
new_section = False
counter+=1
if char == "(":
brk_on +=1
elif char == ")":
brk_off += 1
if ((char == "," and brk_on==brk_off)):
new_section = True
if (counter == len (string)):
string_section = string [start_section:counter]
else:
string_section = string [start_section:counter-1]
if section == 0:
item_props.pickit_type = int (string_section)
section +=1
start_section = counter
if ((char == "," and (brk_on==brk_off+1)) or new_section or counter == len (string)):
if new_section:
section -=1
if start_item ==0:
start_item = start_section
if (counter == len (string)):
item = string [start_item:counter]
else:
item = string [start_item:counter-1]
if section == 0 and counter == len (string):
item_props.pickit_type = int (item)
pass
if section ==1:
include_list.append (item)
start_item = counter +1
elif section ==2:
exclude_list.append (item)
start_item = counter +1
if new_section:
section +=1
if (len (include_list)>0 and (len (include_list[0]) >=6)):
if ("AND" in include_list[0][0: 6] and not ")" in include_list[0]):
item_props.include_type = "AND"
else:
item_props.include_type = "OR"
if (len (exclude_list)>0 and (len (exclude_list[0]) >=6)):
if ("AND" in exclude_list[0][0:6] and not ")" in include_list[0]):
item_props.exclude_type = "AND"
else:
item_props.exclude_type = "OR"
for i in range (len(include_list)):
include_list[i] = include_list[i].replace (" ","").replace ("OR(","").replace ("AND(", "").replace ("(", "").replace (")","")
include_list[i] = include_list[i].split (",")
for l in range (len (exclude_list)):
exclude_list[l] = exclude_list[l].replace (" ","").replace ("OR(","").replace ("AND(", "").replace ("(", "").replace (")","")
exclude_list[l] = exclude_list[l].split (",")
item_props.include = include_list
item_props.exclude = exclude_list
return item_props
@staticmethod
def turn_off_goldpickup():
with config_lock:
Config.char["stash_gold"] = False
Config.items["misc_gold"].pickit_type = 0
@staticmethod
def load_data():
Logger.info("Loading Config Data")
Config._config = configparser.ConfigParser()
Config._config.read('config/params.ini')
Config._game_config = configparser.ConfigParser()
Config._game_config.read('config/game.ini')
Config._pickit_config = configparser.ConfigParser()
Config._pickit_config.read('config/pickit.ini')
Config._shop_config = configparser.ConfigParser()
Config._shop_config.read('config/shop.ini')
Config._custom = configparser.ConfigParser()
if os.environ.get('RUN_ENV') != "test" and os.path.exists('config/custom.ini'):
Config._custom.read('config/custom.ini')
Config.general = {
"saved_games_folder": Config._select_val("general", "saved_games_folder"),
"name": Config._select_val("general", "name"),
"max_game_length_s": float(Config._select_val("general", "max_game_length_s")),
"max_consecutive_fails": int(Config._select_val("general", "max_consecutive_fails")),
"randomize_runs": bool(int(Config._select_val("general", "randomize_runs"))),
"difficulty": Config._select_val("general", "difficulty"),
"message_api_type": Config._select_val("general", "message_api_type"),
"custom_message_hook": Config._select_val("general", "custom_message_hook"),
"discord_status_count": False if not Config._select_val("general", "discord_status_count") else int(Config._select_val("general", "discord_status_count")),
"discord_status_condensed": bool(int(Config._select_val("general", "discord_status_condensed"))),
"info_screenshots": bool(int(Config._select_val("general", "info_screenshots"))),
"loot_screenshots": bool(int(Config._select_val("general", "loot_screenshots"))),
"d2r_path": Config._select_val("general", "d2r_path"),
"restart_d2r_when_stuck": bool(int(Config._select_val("general", "restart_d2r_when_stuck"))),
}
# Added for dclone ip hunting
Config.dclone = {
"region_ips": Config._select_val("dclone", "region_ips"),
"dclone_hotip": Config._select_val("dclone", "dclone_hotip"),
}
Config.routes = {}
order_str = Config._select_val("routes", "order").replace("run_eldritch", "run_shenk")
Config.routes_order = [x.strip() for x in order_str.split(",")]
del Config._config["routes"]["order"]
for key in Config._config["routes"]:
Config.routes[key] = bool(int(Config._select_val("routes", key)))
Config.char = {
"type": Config._select_val("char", "type"),
"show_items": Config._select_val("char", "show_items"),
"inventory_screen": Config._select_val("char", "inventory_screen"),
"stand_still": Config._select_val("char", "stand_still"),
"force_move": Config._select_val("char", "force_move"),
"num_loot_columns": int(Config._select_val("char", "num_loot_columns")),
"take_health_potion": float(Config._select_val("char", "take_health_potion")),
"take_mana_potion": float(Config._select_val("char", "take_mana_potion")),
"take_rejuv_potion_health": float(Config._select_val("char", "take_rejuv_potion_health")),
"take_rejuv_potion_mana": float(Config._select_val("char", "take_rejuv_potion_mana")),
"heal_merc": float(Config._select_val("char", "heal_merc")),
"heal_rejuv_merc": float(Config._select_val("char", "heal_rejuv_merc")),
"chicken": float(Config._select_val("char", "chicken")),
"merc_chicken": float(Config._select_val("char", "merc_chicken")),
"tp": Config._select_val("char", "tp"),
"belt_rows": int(Config._select_val("char", "belt_rows")),
"show_belt": Config._select_val("char", "show_belt"),
"potion1": Config._select_val("char", "potion1"),
"potion2": Config._select_val("char", "potion2"),
"potion3": Config._select_val("char", "potion3"),
"potion4": Config._select_val("char", "potion4"),
"belt_rejuv_columns": int(Config._select_val("char", "belt_rejuv_columns")),
"belt_hp_columns": int(Config._select_val("char", "belt_hp_columns")),
"belt_mp_columns": int(Config._select_val("char", "belt_mp_columns")),
"stash_gold": bool(int(Config._select_val("char", "stash_gold"))),
"gold_trav_only": bool(int(Config._select_val("char", "gold_trav_only"))),
"use_merc": bool(int(Config._select_val("char", "use_merc"))),
"id_items": bool(int(Config._select_val("char", "id_items"))),
"open_chests": bool(int(Config._select_val("char", "open_chests"))),
"fill_shared_stash_first": bool(int(Config._select_val("char", "fill_shared_stash_first"))),
"pre_buff_every_run": bool(int(Config._select_val("char", "pre_buff_every_run"))),
"cta_available": bool(int(Config._select_val("char", "cta_available"))),
"weapon_switch": Config._select_val("char", "weapon_switch"),
"battle_orders": Config._select_val("char", "battle_orders"),
"battle_command": Config._select_val("char", "battle_command"),
"casting_frames": int(Config._select_val("char", "casting_frames")),
"atk_len_arc": float(Config._select_val("char", "atk_len_arc")),
"atk_len_trav": float(Config._select_val("char", "atk_len_trav")),
"atk_len_pindle": float(Config._select_val("char", "atk_len_pindle")),
"atk_len_eldritch": float(Config._select_val("char", "atk_len_eldritch")),
"atk_len_shenk": float(Config._select_val("char", "atk_len_shenk")),
"atk_len_nihlathak": float(Config._select_val("char", "atk_len_nihlathak")),
"atk_len_diablo_vizier": float(Config._select_val("char", "atk_len_diablo_vizier")),
"atk_len_diablo_deseis": float(Config._select_val("char", "atk_len_diablo_deseis")),
"atk_len_diablo_infector": float(Config._select_val("char", "atk_len_diablo_infector")),
"atk_len_diablo": float(Config._select_val("char", "atk_len_diablo")),
"atk_len_cs_trashmobs": float(Config._select_val("char", "atk_len_cs_trashmobs")),
"kill_cs_trash": float(Config._select_val("char", "kill_cs_trash")),
"runs_per_repair": False if not Config._select_val("char", "runs_per_repair") else int(Config._select_val("char", "runs_per_repair")),
"gamble_items": False if not Config._select_val("char", "gamble_items") else Config._select_val("char", "gamble_items").replace(" ","").split(","),
}
# Sorc base config
sorc_base_cfg = dict(Config._config["sorceress"])
if "sorceress" in Config._custom:
sorc_base_cfg.update(dict(Config._custom["sorceress"]))
# blizz sorc
Config.blizz_sorc = dict(Config._config["blizz_sorc"])
if "blizz_sorc" in Config._custom:
Config.blizz_sorc.update(dict(Config._custom["blizz_sorc"]))
Config.blizz_sorc.update(sorc_base_cfg)
# light sorc
Config.light_sorc = dict(Config._config["light_sorc"])
if "light_sorc" in Config._custom:
Config.light_sorc.update(dict(Config._custom["light_sorc"]))
Config.light_sorc.update(sorc_base_cfg)
# nova sorc
Config.nova_sorc = dict(Config._config["nova_sorc"])
if "nova_sorc" in Config._custom:
Config.nova_sorc.update(dict(Config._custom["nova_sorc"]))
Config.nova_sorc.update(sorc_base_cfg)
# Palandin config
Config.hammerdin = Config._config["hammerdin"]
if "hammerdin" in Config._custom:
Config.hammerdin.update(Config._custom["hammerdin"])
# Assasin config
Config.trapsin = Config._config["trapsin"]
if "trapsin" in Config._custom:
Config.trapsin.update(Config._custom["trapsin"])
# Barbarian config
Config.barbarian = Config._config["barbarian"]
if "barbarian" in Config._custom:
Config.barbarian.update(Config._custom["barbarian"])
Config.barbarian = dict(Config.barbarian)
Config.barbarian["cry_frequency"] = float(Config.barbarian["cry_frequency"])
# Basic config
Config.basic = Config._config["basic"]
if "basic" in Config._custom:
Config.basic.update(Config._custom["basic"])
# Basic Ranged config
Config.basic_ranged = Config._config["basic_ranged"]
if "basic_ranged" in Config._custom:
Config.basic_ranged.update(Config._custom["basic_ranged"])
# Necro config
Config.necro = Config._config["necro"]
if "necro" in Config._custom:
Config.necro.update(Config._custom["necro"])
Config.advanced_options = {
"pathing_delay_factor": min(max(int(Config._select_val("advanced_options", "pathing_delay_factor")), 1), 10),
"message_headers": Config._select_val("advanced_options", "message_headers"),
"message_body_template": Config._select_val("advanced_options", "message_body_template"),
"graphic_debugger_layer_creator": bool(int(Config._select_val("advanced_options", "graphic_debugger_layer_creator"))),
"logg_lvl": Config._select_val("advanced_options", "logg_lvl"),
"exit_key": Config._select_val("advanced_options", "exit_key"),
"resume_key": Config._select_val("advanced_options", "resume_key"),
"auto_settings_key": Config._select_val("advanced_options", "auto_settings_key"),
"restore_settings_from_backup_key": Config._select_val("advanced_options", "restore_settings_from_backup_key"),
"settings_backup_key": Config._select_val("advanced_options", "settings_backup_key"),
"graphic_debugger_key": Config._select_val("advanced_options", "graphic_debugger_key"),
}
Config.items = {}
for key in Config._pickit_config["items"]:
try:
Config.items[key] = Config.parse_item_config_string(key)
if Config.items[key].pickit_type and not os.path.exists(f"./assets/items/{key}.png"):
print(f"Warning: You activated {key} in pickit, but there is no img available in assets/items")
except ValueError as e:
print(f"Error with pickit config: {key} ({e})")
Config.colors = {}
for key in Config._game_config["colors"]:
Config.colors[key] = np.split(np.array([int(x) for x in Config._select_val("colors", key).split(",")]), 2)
Config.ui_pos = {}
for key in Config._game_config["ui_pos"]:
Config.ui_pos[key] = int(Config._select_val("ui_pos", key))
Config.ui_roi = {}
for key in Config._game_config["ui_roi"]:
Config.ui_roi[key] = np.array([int(x) for x in Config._select_val("ui_roi", key).split(",")])
Config.path = {}
for key in Config._game_config["path"]:
Config.path[key] = np.reshape(np.array([int(x) for x in Config._select_val("path", key).split(",")]), (-1, 2))
Config.shop = {
"shop_trap_claws": bool(int(Config._select_val("claws", "shop_trap_claws"))),
"shop_melee_claws": bool(int(Config._select_val("claws", "shop_melee_claws"))),
"shop_3_skills_ias_gloves": bool(int(Config._select_val("gloves", "shop_3_skills_ias_gloves"))),
"shop_2_skills_ias_gloves": bool(int(Config._select_val("gloves", "shop_2_skills_ias_gloves"))),
"trap_min_score": int(Config._select_val("claws", "trap_min_score")),
"melee_min_score": int(Config._select_val("claws", "melee_min_score")),
"shop_hammerdin_scepters": bool(int(Config._select_val("scepters", "shop_hammerdin_scepters"))),
"speed_factor": float(Config._select_val("scepters", "speed_factor")),
"apply_pather_adjustment": bool(int(Config._select_val("scepters", "apply_pather_adjustment"))),
}
stash_destination_str = Config._select_val("transmute","stash_destination")
Config._transmute_config = {
"stash_destination": [int(x.strip()) for x in stash_destination_str.split(",")],
"transmute_every_x_game": Config._select_val("transmute","transmute_every_x_game"),
}
if __name__ == "__main__":
from copy import deepcopy
config = Config()
# Check if any added items miss templates
for k in config.items:
if not os.path.exists(f"./assets/items/{k}.png"):
print(f"Template not found: {k}")
# Check if any item templates miss a config
for filename in os.listdir(f'assets/items'):
filename = filename.lower()
if filename.endswith('.png'):
item_name = filename[:-4]
blacklist_item = item_name.startswith("bl__")
if item_name not in config.items and not blacklist_item:
print(f"Config not found for: " + filename)