예제 #1
0
def load():
    session.query(Emoticon).delete()
    print("emoticons")

    print("- loading emoticons from scripts")
    # load all of the item scripts data information
    data = valve_readfile(config.vpk_path,
                          paths['emoticon_scripts_file'],
                          "kv",
                          encoding="UTF-16")["emoticons"]
    for emoticonid in data:
        if int(emoticonid) >= 1000:
            continue  # These are team emoticons
        emoticon = Emoticon()
        emoticon.id = int(emoticonid)
        emoticon.name = data[emoticonid]['aliases']['0']
        emoticon.ms_per_frame = data[emoticonid]['ms_per_frame']
        emoticon.url = paths['emoticon_image_path'] + data[emoticonid][
            'image_name']
        try:
            img = Image.open(config.vpk_path + emoticon.url)
            emoticon.frames = int(img.size[0] / img.size[1])
        except:
            # Error loading this image, so dont add it to the database
            continue

        session.add(emoticon)

    session.commit()
예제 #2
0
def load():
    session.query(ChatWheelMessage).delete()
    print("chat_wheel")

    print("- loading chat_wheel stuff from scripts")
    # load all of the item scripts data information
    data = valve_readfile(config.vpk_path,
                          paths['chat_wheel_scripts_file'],
                          "kv",
                          encoding="utf-8")["chat_wheel"]
    for key in data["messages"]:
        msg_data = data["messages"][key]

        message = ChatWheelMessage()
        message.id = int(msg_data["message_id"])
        message.name = key
        message.label = msg_data.get("label")
        message.message = msg_data.get("message")
        message.sound = msg_data.get("sound")
        message.image = msg_data.get("image")
        message.all_chat = msg_data.get("all_chat") == "1"
        if message.sound:
            if message.sound == "soundboard.crash":
                message.sound = "soundboard.crash_burn"
            message.sound = f"/sounds/misc/soundboard/{message.sound.replace('soundboard.', '')}.wav"
        if message.image:
            message.image = f"/panorama/images/{message.image}"

        session.add(message)

    for category in data["categories"]:
        for msg in data["categories"][category]["messages"]:
            for message in session.query(ChatWheelMessage).filter_by(name=msg):
                if message.category is not None:
                    raise ValueError(
                        f"More than one category for chatwheel: {message.name}"
                    )
                message.category = category

    print("- loading chat wheel data from dota_english")
    # Load additional information from the dota_english.txt file
    data = valve_readfile(config.vpk_path,
                          paths['dota_english_file'],
                          "kv",
                          encoding="UTF-16")["lang"]["Tokens"]
    for message in session.query(ChatWheelMessage):
        if message.label is None or message.message is None:
            continue
        if message.label.startswith("#") and message.label[1:] in data:
            message.label = data[message.label[1:]]
        if message.message.startswith("#") and message.message[1:] in data:
            message.message = data[message.message[1:]]
        if message.id in [71, 72]:
            message.message = message.message.replace("%s1", "A hero")

    session.commit()
예제 #3
0
def load():
	session.query(ChatWheelMessage).delete()
	print("chat_wheel")

	print("- loading chat_wheel stuff from scripts")
	# load sounds info from vsndevts file
	sounds_data = valve_readfile(config.vpk_path, paths['chat_wheel_vsndevts_file'], "vsndevts")
	# load all of the item scripts data information
	data = valve_readfile(config.vpk_path, paths['chat_wheel_scripts_file'], "kv", encoding="utf-8")["chat_wheel"]
	for key in data["messages"]:
		msg_data = data["messages"][key]

		message = ChatWheelMessage()
		message.id = int(msg_data["message_id"])
		message.name = key
		message.label = msg_data.get("label")
		message.message = msg_data.get("message")
		message.sound = msg_data.get("sound")
		message.image = msg_data.get("image")
		message.all_chat = msg_data.get("all_chat") == "1"
		if message.sound:
			if message.sound not in sounds_data:
				printerr(f"Couldn't find vsndevts entry for {message.sound}, skipping")
				continue
			if "vsnd_files" not in sounds_data[message.sound]:
				printerr(f"no associated vsnd files found for {message.sound}, skipping")
				continue
			message.sound = "/" + sounds_data[message.sound]["vsnd_files"][0].replace(".vsnd", ".wav")
			if not os.path.exists(config.vpk_path + message.sound):
				printerr(f"Missing file: {message.sound}")
		if message.image:
			message.image = f"/panorama/images/{message.image}"

		session.add(message)

	for category in data["categories"]:
		for msg in data["categories"][category]["messages"]:
			for message in session.query(ChatWheelMessage).filter_by(name=msg):
				if message.category is not None:
					raise ValueError(f"More than one category for chatwheel: {message.name}")
				message.category = category

	print("- loading chat wheel data from dota_english")
	# Load additional information from the dota_english.txt file
	data = valve_readfile(config.vpk_path, paths['dota_english_file'], "kv", encoding="UTF-8")["lang"]["Tokens"]
	for message in session.query(ChatWheelMessage):
		if message.label is None or message.message is None:
			continue
		if message.label.startswith("#") and message.label[1:] in data:
			message.label = data[message.label[1:]]
		if message.message.startswith("#") and message.message[1:] in data:
			message.message = data[message.message[1:]]
		if message.id in [ 71, 72 ]:
			message.message = message.message.replace("%s1", "A hero")

	session.commit()
예제 #4
0
def load():
	session.query(Item).delete()
	print("items")

	print("- loading items from item scripts")
	# load all of the item scripts data information
	data = valve_readfile(config.vpk_path, paths['item_scripts_file'], "kv")["DOTAAbilities"]
	for itemname in data:
		if itemname == "Version":
			continue
		item_data = data[itemname]
		item = Item()

		item.name = itemname
		item.id = item_data['ID']
		item.cost = item_data.get('ItemCost')
		item.aliases = "|".join(item_data.get("ItemAliases", "").split(";"))
		item.quality = item_data.get("ItemQuality")
		item.mana_cost = clean_values(item_data.get('AbilityManaCost'))
		item.cooldown = clean_values(item_data.get('AbilityCooldown'))
		item.base_level = item_data.get("ItemBaseLevel")
		item.ability_special = json.dumps(get_ability_special(item_data.get("AbilitySpecial"), itemname), indent=4)

		item.json_data = json.dumps(item_data, indent=4)

		session.add(item)

	print("- loading item data from dota_english")
	# Load additional information from the dota_english.txt file
	data = valve_readfile(config.vpk_path, paths['localization_abilities'], "kv", encoding="UTF-16")["lang"]["Tokens"]
	for item in session.query(Item):
		item_tooltip = "DOTA_Tooltip_Ability_" + item.name 
		item_tooltip2 = "DOTA_Tooltip_ability_" + item.name 
		item.localized_name = data.get(item_tooltip, item.name)
		item.description = data.get(item_tooltip + "_Description", data.get(item_tooltip2 + "_Description", ""))
		item.lore = data.get(item_tooltip + "_Lore", data.get(item_tooltip2 + "_Lore", ""))

		ability_special = json.loads(item.ability_special, object_pairs_hook=OrderedDict)
		ability_special = ability_special_add_header(ability_special, data, item.name)
		item.ability_special = json.dumps(ability_special, indent=4)
		item.description = clean_description(item.description, ability_special, base_level=item.base_level)

	print("- adding item icon files")
	# Add img files to item
	for item in session.query(Item):
		if os.path.isfile(config.vpk_path + paths['item_img_path'] + item.name.replace("item_", "") + ".png"):
			item.icon = paths['item_img_path'] + item.name.replace("item_", "") + ".png"
		else:
			if "recipe" in item.name:
				item.icon = paths['item_img_path'] + "recipe.png"
			else:
				print(f"icon file not found for {item.name}")

	session.commit()
예제 #5
0
def load():
    session.query(Voice).delete()
    print("Voices")

    print("- loading from heroes")
    for hero in session.query(Hero):
        voice = Voice()

        voice.id = hero.id
        voice.name = hero.localized_name
        voice.icon = hero.icon
        voice.image = hero.portrait
        voice.url = name_to_url(hero.localized_name) + "/Responses"
        voice.criteria = None

        voice.media_name = vsndevts_to_media_name(
            json.loads(hero.json_data).get("VoiceFile"))
        voice.hero_id = hero.id

        session.add(voice)

    print("- loading cosmetics file (takes a bit)")
    items_game = ItemsGame()

    custom_urls = {
        "Announcer: Tuskar": "Announcer:_Tusk",
        "Default Announcer": "Announcer_responses",
        "Default Mega-Kill Announcer": "Announcer_responses",
        "Announcer: Bristleback": "Bristleback_Announcer_Pack",
        "Mega-Kills: Bristleback": "Bristleback_Announcer_Pack"
    }
    custom_media_name = {
        "Default Announcer": "announcer",
        "Default Mega-Kill Announcer": "announcer_killing_spree"
    }

    print("- loading from announcers")
    for announcer in items_game.by_prefab["announcer"]:
        voice = Voice()

        # the first announcer has id = 586, so this will not interfere with hero ids
        voice.id = int(announcer["id"])
        voice.name = announcer["name"]
        voice.icon = "/panorama/images/icon_announcer_psd.png"
        voice.image = f"/panorama/images/{announcer['image_inventory']}_png.png"
        voice.criteria = None

        if voice.name in custom_urls:
            voice.url = custom_urls[voice.name]
        else:
            voice.url = name_to_url(announcer["name"])

        if voice.name in custom_media_name:
            voice.media_name = custom_media_name[voice.name]
        else:
            ass_mod = items_game.get_asset_modifier(announcer, "announcer")
            if ass_mod:
                voice.media_name = ass_mod.asset.replace("npc_dota_hero_", "")

        session.add(voice)

    added_names = []
    print("- loading from hero cosmetics")
    for item in items_game.by_prefab["wearable"]:
        criteria = []
        for ass_mod in items_game.get_asset_modifiers(item,
                                                      "response_criteria"):
            criteria.append(ass_mod.asset)
        if len(criteria) == 0:
            continue
        criteria = "|".join(map(lambda c: f"customresponse:{c}", criteria))
        icon = None
        for ass_mod in items_game.get_asset_modifiers(
                item, "icon_replacement_hero_minimap"):
            icon = f"/panorama/images/heroes/icons/{ass_mod.modifier}_png.png"
        skip = False
        for pack in items_game.by_prefab["bundle"]:
            if item["name"] not in pack["bundle"]:
                continue
            for item_name in pack["bundle"]:
                if item_name in added_names:
                    voice = session.query(Voice).filter_by(
                        name=item_name).first()
                    voice.criteria += f"|{criteria}"
                    skip = True
                if not icon:
                    related_item = items_game.item_name_dict[item_name]
                    for ass_mod in items_game.get_asset_modifiers(
                            related_item, "icon_replacement_hero_minimap"):
                        icon = f"/panorama/images/heroes/icons/{ass_mod.modifier}_png.png"
                        break
        if skip:
            continue

        voice = Voice()
        voice.id = int(item["id"])
        voice.name = item["name"]
        voice.image = f"/panorama/images/{item['image_inventory']}_png.png"
        voice.icon = icon
        voice.criteria = criteria
        voice.media_name = None

        for hero_name in item.get("used_by_heroes", {}):
            hero = session.query(Hero).filter_by(full_name=hero_name).first()
            if hero:
                voice.hero_id = hero.id
                if not voice.icon:
                    voice.icon = hero.icon

        added_names.append(voice.name)
        session.add(voice)

    print("- associating announcer packs")
    for pack in items_game.by_prefab["bundle"]:
        if pack.get("name") == "Assembly of Announcers Pack":
            continue
        for name in pack.get("bundle", []):
            for voice in session.query(Voice).filter_by(name=name):
                voice.url = name_to_url(pack["name"])

    data = read_json("builderdata/voice_actors.json")
    print("- adding voice actors")
    for voice in session.query(Voice):
        if str(voice.id) in data:
            voice.voice_actor = data[str(voice.id)]

    session.commit()
예제 #6
0
def load():
    session.query(LoadingScreen).delete()
    print("loadingscreens")

    items_data = valve_readfile(config.vpk_path,
                                paths['cosmetics_scripts_file'],
                                "kv_nocomment",
                                encoding="UTF-8")["items_game"]["items"]

    custom_paths = {
        "Default Loading Screen":
        "/panorama/images/loadingscreens/default/startup_background_logo_png.png"
    }

    # this will be used later for assigning category
    couriers = []

    print("- loading loadingscreens from items_game")
    # load all of the item scripts data information
    for key in items_data:
        data = items_data[key]
        if data.get("prefab") == "courier":
            couriers.append(data.get("name"))
        if data.get("prefab") != "loading_screen":
            continue  # These are team loadingscreens
        loadingscreen = LoadingScreen()
        loadingscreen.id = int(key)
        loadingscreen.name = data.get("name")
        date_array = list(map(int, data.get("creation_date").split("-")))
        loadingscreen.creation_date = datetime.date(date_array[0],
                                                    date_array[1],
                                                    date_array[2])
        loadingscreen.category = "other"

        if loadingscreen.name in custom_paths:
            loadingscreen.image = custom_paths[loadingscreen.name]
        else:
            for asset in data["visuals"]:
                asset_data = data["visuals"][asset]
                if not isinstance(asset_data, str) and asset_data.get(
                        "type") == "loading_screen":
                    image_path = asset_data["asset"]
                    if ".vtex" in image_path:
                        image_path = image_path.replace(".vtex", "")
                    else:
                        image_path += "_tga"
                    loadingscreen.image = f"/panorama/images/{image_path}.png"

        loadingscreen.thumbnail = os.path.dirname(
            loadingscreen.image) + "/thumbnail.png"

        if not os.path.exists(config.vpk_path + loadingscreen.image):
            continue  # skip this loadingscreen because it doesn't exist

        session.add(loadingscreen)

    progress = ProgressBar(session.query(LoadingScreen).count(),
                           title="- making thumbnails and retrieving colors")
    for loadingscreen in session.query(LoadingScreen):
        progress.tick()

        if not os.path.exists(config.vpk_path + loadingscreen.thumbnail):
            image = Image.open(config.vpk_path + loadingscreen.image)
            image.thumbnail((128, 64), Image.ANTIALIAS)
            image.save(config.vpk_path + loadingscreen.thumbnail, format="PNG")

        colors = colorgram.extract(config.vpk_path + loadingscreen.thumbnail,
                                   5)

        loadingscreen.color = "#{0:02x}{1:02x}{2:02x}".format(*colors[0].rgb)
        hsv = rgb_to_hsv(colors[0].rgb)
        loadingscreen.hue = hsv[0]
        loadingscreen.saturation = hsv[1]
        loadingscreen.value = hsv[2]

    ## Categories:
    # hero_set
    # hud_skin
    # tournament
    # courier
    # other

    item_type_to_category = {
        "#DOTA_WearableType_Hud_Skin_Bundle": "hud_skin",
        "#DOTA_WearableType_Tournament_Bundle": "tournament"
    }

    print("- associating item packs")
    for key in items_data:
        data = items_data[key]
        if data.get("prefab") != "bundle":
            continue
        for name in data.get("bundle", []):
            for loadingscreen in session.query(LoadingScreen).filter_by(
                    name=name):
                heroes = data.get("used_by_heroes", {})
                for hero_name in heroes:
                    hero = session.query(Hero).filter_by(
                        full_name=hero_name).first()
                    if hero:
                        loadingscreen.hero_ids = str(hero.id)
                        loadingscreen.category = "hero_set"
                if loadingscreen.category == "hero_set":
                    continue
                category = item_type_to_category.get(
                    data.get("item_type_name"))
                if category:
                    loadingscreen.category = category
                    continue
                if any(x in couriers for x in data.get("bundle", [])):
                    loadingscreen.category = "courier"
                    continue

    print("- linking heroes")
    data = read_json("builderdata/loadingscreen_heroes.json")
    for screen in session.query(LoadingScreen):
        if screen.name in data:
            heroes = []
            if screen.hero_ids:
                heroes.append(screen.hero_ids)
            for heroname in data[screen.name]:
                hero = session.query(Hero).filter_by(name=heroname).first()
                heroes.append(str(hero.id))
            screen.hero_ids = "|".join(heroes)

    session.commit()
예제 #7
0
def load():
    session.query(Item).delete()
    print("items")

    added_ids = []

    item_name_fixes = {"item_trident1": "item_trident"}
    print("- loading items from item scripts")
    # load all of the item scripts data information
    data = valve_readfile(config.vpk_path, paths['item_scripts_file'],
                          "kv")["DOTAAbilities"]
    for itemname in data:
        if itemname == "Version":
            continue
        item_data = data[itemname]
        if item_data.get('IsObsolete') == "1":
            continue  # ignore obsolete items
        item = Item()

        item.name = item_name_fixes.get(itemname, itemname)
        item.id = int(item_data['ID'])
        item.cost = item_data.get('ItemCost')
        item.aliases = "|".join(item_data.get("ItemAliases", "").split(";"))
        item.quality = item_data.get("ItemQuality")
        item.mana_cost = clean_values(item_data.get('AbilityManaCost'))
        item.cooldown = clean_values(item_data.get('AbilityCooldown'))
        item.cast_range = clean_values(item_data.get('AbilityCastRange'))
        item.base_level = item_data.get("ItemBaseLevel")
        item.secret_shop = item_data.get("SecretShop") == "1"
        item.ability_special = json.dumps(get_ability_special(
            item_data.get("AbilitySpecial"), item.name),
                                          indent=4)

        item.json_data = json.dumps(item_data, indent=4)

        if item.id in added_ids:
            print(f"duplicate id on: {itemname}")
            continue
        added_ids.append(item.id)

        session.add(item)

    print("- loading item data from dota_english")
    # Load additional information from the dota_english.txt file
    data = valve_readfile(config.vpk_path,
                          paths['localization_abilities'],
                          "kv",
                          encoding="UTF-8")["lang"]["Tokens"]
    for item in session.query(Item):
        item_tooltip = "DOTA_Tooltip_Ability_" + item.name
        item_tooltip2 = "DOTA_Tooltip_ability_" + item.name
        item.localized_name = data.get(item_tooltip, item.name)
        item.description = data.get(
            item_tooltip + "_Description",
            data.get(item_tooltip2 + "_Description", ""))
        item.lore = data.get(item_tooltip + "_Lore",
                             data.get(item_tooltip2 + "_Lore", ""))

        ability_special = json.loads(item.ability_special,
                                     object_pairs_hook=OrderedDict)
        ability_special = ability_special_add_header(ability_special, data,
                                                     item.name)
        item.ability_special = json.dumps(ability_special, indent=4)
        item.description = clean_description(item.description,
                                             build_replacements_dict(item),
                                             base_level=item.base_level)

    print("- adding neutral item data")
    data = valve_readfile(config.vpk_path, paths['neutral_item_scripts_file'],
                          "kv")["neutral_items"]
    item_tier_map = {}
    for tier in data:
        for name in data[tier]["items"]:
            item_tier_map[name] = tier
    for item in session.query(Item):
        if item.name in item_tier_map:
            item.neutral_tier = item_tier_map[item.name]

    print("- linking recipes")
    for recipe in session.query(Item):
        json_data = json.loads(recipe.json_data)
        if json_data.get("ItemRecipe", "0") != "0":
            components = list(
                json_data.get("ItemRequirements", {
                    "01": None
                }).values())[0]
            if components is None:
                continue
            components = components.replace(";", " ").strip().split(" ")
            if recipe.cost != 0:
                components.append(recipe.name)
            crafted_item_name = json_data.get("ItemResult")
            crafted_item = session.query(Item).filter_by(
                name=crafted_item_name).first()
            if not crafted_item:
                raise ValueError(
                    f"Can't find crafted item {crafted_item_name}")
            crafted_item.recipe = "|".join(components)
            if recipe.neutral_tier is not None:  # stuff like trident
                crafted_item.neutral_tier = recipe.neutral_tier

            if recipe.cost == 0 and not json_data.get("ItemIsNeutralDrop"):
                session.delete(recipe)

    print("- adding item icon files")
    # Add img files to item
    for item in session.query(Item):
        iconpath = paths['item_img_path'] + item.name.replace("item_",
                                                              "") + "_png.png"
        if os.path.isfile(config.vpk_path + iconpath):
            item.icon = iconpath
        else:
            if "recipe" in item.name:
                item.icon = paths['item_img_path'] + "recipe.png"
            else:
                printerr(f"icon file not found for {item.name}", flush=True)

    session.commit()
예제 #8
0
def load():
	session.query(Response).delete()
	session.query(Criterion).delete()
	print("Responses")

	progress = ProgressBar(session.query(Voice).count(), title="- loading from vsnd files:")
	for voice in session.query(Voice):
		progress.tick()

		if not voice.media_name:
			continue

		vsndevts_path = f"/soundevents/voscripts/game_sounds_vo_{voice.media_name}.vsndevts"
		vsndevts_data = valve_readfile(config.vpk_path, vsndevts_path, "vsndevts")
		captionsFilename = f"{config.vpk_path}/resource/subtitles/subtitles_{voice.media_name}_english.dat"
		if os.path.exists(captionsFilename):
			captionsFile = ClosedCaptionFile(captionsFilename)
		else:
			printerr(f"missing {captionsFilename}")
			captionsFile = None

		for key in vsndevts_data:
			data = vsndevts_data[key]
			filename = "/" + data["vsnd_files"][0].replace("vsnd", "mp3")
			
			response = Response()
			response.fullname = key
			response.name = os.path.basename(filename).replace(".mp3", "")

			for ext in file_types:
				newname = filename.replace(".mp3", f".{ext}")
				if os.path.exists(config.vpk_path + newname):
					filename = newname
					break

			if not os.path.exists(config.vpk_path + filename):
				printerr(f"Missing file: {filename}")

			response.mp3 = filename
			response.voice_id = voice.id
			response.hero_id = voice.hero_id
			response.criteria = ""

			if captionsFile:
				text = captionsFile.lookup(response.fullname)
				if text:
					response.text = text
					response.text_simple = text.replace("...", " ")
					response.text_simple = " " + re.sub(r'[^a-z^0-9^A-Z^\s]', r'', response.text_simple).lower() + " "
					response.text_simple = re.sub(r'\s+', r' ', response.text_simple)
				else:
					response.text = ""

			session.add(response)

	print("- loading criteria")
	rules = {}
	groups = {}
	criteria = {}
	# Load response_rules
	for root, dirs, files in os.walk(config.vpk_path + paths['response_rules_path']):
		for file in files:
			data = valve_readfile(config.vpk_path, paths['response_rules_path'] + file, "rules")
			for key in data:
				if key.startswith("rule_"):
					rules[key[5:]] = data[key]
				elif key.startswith("response_"):
					groups[key[9:]] = data[key]
				elif key.startswith("criterion_"):
					criteria[key[10:]] = data[key]

	for key in criteria:
		criterion = Criterion()
		criterion.name = key
		vals = criteria[key].split(" ")
		criterion.matchkey = vals[0]
		criterion.matchvalue = vals[1]
		if "weight" in vals:
			criterion.weight = float(vals[vals.index("weight") + 1])
		else:
			criterion.weight = 1.0
		criterion.required = "required" in vals
		session.add(criterion)

	voice_linker = {}

	
	custom_voice_criteria = { # because valve did customresponse:arcana for 2 things
		"Tempest Helm of the Thundergod": "IsZeusEconArcana"
	}
	# fix up voice.criteria
	for voice in session.query(Voice):
		if voice.criteria:
			if voice.name in custom_voice_criteria:
				voice.criteria = custom_voice_criteria[voice.name]
				continue
			crits = []
			for crit in voice.criteria.split("|"):
				key, value = crit.split(":")
				realcrit = session.query(Criterion).filter_by(matchkey=key).filter_by(matchvalue=value).first()
				if realcrit:
					crits.append(realcrit.name)
			voice.criteria = "|".join(crits)
			pattern = f"(^|\|| ){voice.criteria}($|\|| )"
			voice_linker[pattern] = voice

	progress = ProgressBar(len(rules) + session.query(Response).count(), title="- linking rules:")
	pre_responses = {}
	for key in rules:
		progress.tick()
		response_criteria = rules[key]['criteria'].rstrip()
		for fullname in groups[rules[key]['response']]:
			if fullname not in pre_responses:
				pre_responses[fullname] = response_criteria
			else:
				pre_responses[fullname] += "|" + response_criteria

	for response in session.query(Response):
		progress.tick()
		if response.fullname in pre_responses:
			response.criteria = pre_responses[response.fullname]
			for pattern, voice in voice_linker.items():
				if re.search(pattern, response.criteria):
					response.voice_id = voice.id

	print("- generating pretty criteria")
	criteria_sentancing.load_pretty_criteria(session)

	session.commit()
예제 #9
0
def load():
    session.query(Ability).delete()
    print("Abilities")

    added_ids = []

    print("- loading abilities from ability scripts")
    # load all of the ability scripts data information
    data = valve_readfile(config.vpk_path, paths['ability_scripts_file'],
                          "kv")["DOTAAbilities"]
    for abilityname in data:
        if (abilityname == "Version" or abilityname == "ability_deward"
                or abilityname == "dota_base_ability"
                or not data[abilityname]['ID'].isdigit()):
            continue

        ability_data = data[abilityname]
        ability = Ability()

        def get_val(key, default_base=False):
            if key in ability_data:
                val = ability_data[key]
                if ' ' in val and all(x == val.split(' ')[0]
                                      for x in val.split(' ')):
                    return val.split(' ')[0]
                return val
            elif default_base:
                return data["ability_base"][key]
            else:
                return None

        ability.name = abilityname
        ability.id = int(ability_data['ID'])
        ability.type = get_val('AbilityType', default_base=True)
        ability.behavior = get_val('AbilityBehavior', default_base=True)
        ability.cast_range = clean_values(get_val('AbilityCastRange'))
        ability.cast_point = clean_values(get_val('AbilityCastPoint'))
        ability.channel_time = clean_values(get_val('AbilityChannelTime'))
        ability.cooldown = clean_values(get_val('AbilityCooldown'))
        ability.duration = clean_values(get_val('AbilityDuration'))
        ability.damage = clean_values(get_val('AbilityDamage'))
        ability.mana_cost = clean_values(get_val('AbilityManaCost'))
        ability.ability_special = json.dumps(get_ability_special(
            ability_data.get("AbilitySpecial"), abilityname),
                                             indent=4)

        # link talents
        link_fixes = {
            "axe_counter_culling_blade":
            "axe_culling_blade",
            "troll_warlord_whirling_axes":
            "troll_warlord_whirling_axes_ranged troll_warlord_whirling_axes_melee",
            "invoker_sunstrike":
            "invoker_sun_strike",
            "morphling_adaptive_strike":
            "morphling_adaptive_strike_agi morphling_adaptive_strike_str"
        }
        for special in ability_data.get("AbilitySpecial", {}).values():
            link = special.get("ad_linked_ability")
            if link:
                if link in ["multi_linked_ability", "multi_linked_or_ability"]:
                    link = special["linked_ad_abilities"].split(" ")[0]
                if link in ["special_bonus_inherent"]:
                    continue  # doesn't link to a different ability
                if link in link_fixes:
                    link = link_fixes[link]
                link = link.replace(" ", "|")
                ability.linked_abilities = link

        if ability.id in added_ids:
            print(f"duplicate id on: {abilityname}")
            continue
        added_ids.append(ability.id)

        def get_enum_val(key, prefix):
            value = get_val(key)
            if value:
                return re.sub(prefix, "", value).lower().replace(" ", "")
            else:
                return value

        ability.behavior = get_enum_val('AbilityBehavior',
                                        "DOTA_ABILITY_BEHAVIOR_")
        ability.damage_type = get_enum_val('AbilityUnitDamageType',
                                           "DAMAGE_TYPE_")
        ability.spell_immunity = get_enum_val(
            'SpellImmunityType', "SPELL_IMMUNITY_(ENEMIES|ALLIES)_")
        ability.target_team = get_enum_val('AbilityUnitTargetTeam',
                                           "DOTA_UNIT_TARGET_TEAM_")
        ability.dispellable = get_enum_val('SpellDispellableType',
                                           "SPELL_DISPELLABLE_")

        ability.json_data = json.dumps(ability_data, indent=4)

        session.add(ability)

    print("- loading ability data from dota_english")
    # Load additional information from the dota_english.txt file
    data = valve_readfile(config.vpk_path,
                          paths['localization_abilities'],
                          "kv",
                          encoding="UTF-8")["lang"]["Tokens"]
    for ability in session.query(Ability):
        ability_tooltip = "DOTA_Tooltip_ability_" + ability.name
        ability.localized_name = data.get(ability_tooltip, ability.name)
        ability.description = data.get(ability_tooltip + "_Description", "")
        ability.lore = data.get(ability_tooltip + "_Lore", "")
        ability.aghanim = data.get(ability_tooltip + "_aghanim_description",
                                   "")
        notes = []
        for i in range(8):
            key = f"{ability_tooltip}_Note{i}"
            if key in data:
                notes.append(data[key])
        ability.note = "" if len(notes) == 0 else "\n".join(notes)

        ability_special = json.loads(ability.ability_special,
                                     object_pairs_hook=OrderedDict)
        ability_special = ability_special_add_talent(ability_special,
                                                     session.query(Ability))
        ability_special = ability_special_add_header(ability_special, data,
                                                     ability.name)
        ability.ability_special = json.dumps(ability_special, indent=4)

        replacements_dict = build_replacements_dict(ability)
        ability.localized_name = clean_description(ability.localized_name,
                                                   replacements_dict,
                                                   value_bolding=False)
        ability.description = clean_description(ability.description,
                                                replacements_dict)
        ability.note = clean_description(ability.note, replacements_dict)
        ability.aghanim = clean_description(ability.aghanim, replacements_dict)

        if ability.localized_name.startswith(": "):
            ability.localized_name = ability.localized_name[2:]

    print("- adding ability icon files")
    # Add img files to ability
    for ability in session.query(Ability):
        iconpath = paths['ability_icon_path'] + ability.name + "_png.png"
        if os.path.isfile(config.vpk_path + iconpath):
            ability.icon = iconpath
        else:
            ability.icon = paths['ability_icon_path'] + "wisp_empty1_png.png"

    session.commit()
예제 #10
0
def load():
    session.query(Response).delete()
    session.query(Criterion).delete()
    print("Responses")

    progress = ProgressBar(session.query(Voice).count(),
                           title="- loading from vsnd files:")
    for voice in session.query(Voice):
        progress.tick()

        if not voice.vsndevts_path:
            continue

        vsndevts_data = valve_readfile(config.vpk_path, voice.vsndevts_path,
                                       "vsndevts")

        for key in vsndevts_data:
            data = vsndevts_data[key]
            filename = "/" + data["vsnd_files"][0].replace("vsnd", "mp3")

            response = Response()
            response.fullname = key
            response.name = os.path.basename(filename).replace(".mp3", "")

            for ext in file_types:
                newname = filename.replace(".mp3", f".{ext}")
                if os.path.exists(config.vpk_path + newname):
                    filename = newname
                    break

            if not os.path.exists(config.vpk_path + filename):
                print(f"Missing file: {filename}")

            response.mp3 = filename
            response.voice_id = voice.id
            response.hero_id = voice.hero_id
            response.criteria = ""
            session.add(response)

    fulldata = valve_readfile(paths['scraped_responses_dir'],
                              paths['scraped_responses_file'],
                              "scrapedresponses")
    progress = ProgressBar(len(fulldata), title="- loading response texts")
    for voiceid in fulldata:
        progress.tick()
        voice = session.query(Voice).filter_by(id=int(voiceid)).first()
        data = fulldata[voiceid]

        for response in session.query(Response).filter_by(voice_id=voice.id):
            text = ""

            # these to help with some weird shit
            fullname = re.sub(r'^announcer_', '', response.fullname)
            fullname = re.sub(r'defensegrid', 'defense_grid', fullname)
            fullname = re.sub(r'techies_tech_ann', 'tech_ann', fullname)
            fullname = re.sub(r'dlc_tusk_tusk_ann', 'greevling_tusk_ann',
                              fullname)
            if voice.id == 49:  # dragon knight
                fullname = f"dk_{response.name}"

            if response.fullname in data:
                text = data[response.fullname]
            elif fullname in data:
                text = data[fullname]
            elif response.name in data:
                text = data[response.name]

            if text != "":
                text = re.sub(r'<!--.*-->', r'', text)
                text = re.sub(r'{{Tooltip\|([^|]+)\|(.*)}}', r'\1 (\2)', text)
                text = re.sub(r'{{tooltip\|\?\|(.*)}}', r'(\1)', text)
                text = re.sub(r'{{.*}}', r'', text)
                response.text = text
                response.text_simple = text.replace("...", " ")
                response.text_simple = " " + re.sub(
                    r'[^a-z^0-9^A-Z^\s]', r'',
                    response.text_simple).lower() + " "
                response.text_simple = re.sub(r'\s+', r' ',
                                              response.text_simple)
            else:
                response.text = ""

    print("- loading criteria")
    rules = {}
    groups = {}
    criteria = {}
    # Load response_rules
    for root, dirs, files in os.walk(config.vpk_path +
                                     paths['response_rules_path']):
        for file in files:
            data = valve_readfile(config.vpk_path,
                                  paths['response_rules_path'] + file, "rules")
            for key in data:
                if key.startswith("rule_"):
                    rules[key[5:]] = data[key]
                elif key.startswith("response_"):
                    groups[key[9:]] = data[key]
                elif key.startswith("criterion_"):
                    criteria[key[10:]] = data[key]

    for key in criteria:
        criterion = Criterion()
        criterion.name = key
        vals = criteria[key].split(" ")
        criterion.matchkey = vals[0]
        criterion.matchvalue = vals[1]
        criterion.weight = vals[3] if "weight" in vals else 1.0
        criterion.required = "required" in vals
        session.add(criterion)

    progress = ProgressBar(len(rules), title="- linking rules:")
    for key in rules:
        response_criteria = rules[key]['criteria'].rstrip()
        progress.tick()

        for fullname in groups[rules[key]['response']]:
            response = session.query(Response).filter_by(
                fullname=fullname).first()
            if response is not None:
                if response.criteria == "":
                    response.criteria = response_criteria
                else:
                    response.criteria += "|" + response_criteria

    print("- generating pretty criteria")
    criteria_sentancing.load_pretty_criteria(session)

    session.commit()
예제 #11
0
def load():
    session.query(Ability).delete()
    print("Abilities")

    print("- loading abilities from ability scripts")
    # load all of the ability scripts data information
    data = valve_readfile(config.vpk_path, paths['ability_scripts_file'],
                          "kv")["DOTAAbilities"]
    for abilityname in data:
        if (abilityname == "Version" or abilityname == "ability_deward"
                or abilityname == "dota_base_ability"):
            continue

        ability_data = data[abilityname]
        ability = Ability()

        def get_val(key, default_base=False):
            if key in ability_data:
                val = ability_data[key]
                if ' ' in val and all(x == val.split(' ')[0]
                                      for x in val.split(' ')):
                    return val.split(' ')[0]
                return val
            elif default_base:
                return data["ability_base"][key]
            else:
                return None

        ability.name = abilityname
        ability.id = ability_data['ID']
        ability.type = get_val('AbilityType', default_base=True)
        ability.behavior = get_val('AbilityBehavior', default_base=True)
        ability.cast_range = clean_values(get_val('AbilityCastRange'))
        ability.cast_point = clean_values(get_val('AbilityCastPoint'))
        ability.channel_time = clean_values(get_val('AbilityChannelTime'))
        ability.cooldown = clean_values(get_val('AbilityCooldown'))
        ability.duration = clean_values(get_val('AbilityDuration'))
        ability.damage = clean_values(get_val('AbilityDamage'))
        ability.mana_cost = clean_values(get_val('AbilityManaCost'))
        ability.ability_special = json.dumps(get_ability_special(
            ability_data.get("AbilitySpecial"), abilityname),
                                             indent=4)

        def get_enum_val(key, prefix):
            value = get_val(key)
            if value:
                return re.sub(prefix, "", value).lower().replace(" ", "")
            else:
                return value

        ability.behavior = get_enum_val('AbilityBehavior',
                                        "DOTA_ABILITY_BEHAVIOR_")
        ability.damage_type = get_enum_val('AbilityUnitDamageType',
                                           "DAMAGE_TYPE_")
        ability.spell_immunity = get_enum_val(
            'SpellImmunityType', "SPELL_IMMUNITY_(ENEMIES|ALLIES)_")
        ability.target_team = get_enum_val('AbilityUnitTargetTeam',
                                           "DOTA_UNIT_TARGET_TEAM_")
        ability.dispellable = get_enum_val('SpellDispellableType',
                                           "SPELL_DISPELLABLE_")

        ability.json_data = json.dumps(ability_data, indent=4)

        session.add(ability)

    print("- loading ability data from dota_english")
    # Load additional information from the dota_english.txt file
    data = valve_readfile(config.vpk_path,
                          paths['localization_abilities'],
                          "kv",
                          encoding="UTF-16")["lang"]["Tokens"]
    for ability in session.query(Ability):
        ability_tooltip = "DOTA_Tooltip_ability_" + ability.name
        ability.localized_name = data.get(ability_tooltip, ability.name)
        ability.description = data.get(ability_tooltip + "_Description", "")
        ability.lore = data.get(ability_tooltip + "_Lore", "")
        ability.aghanim = data.get(ability_tooltip + "_aghanim_description",
                                   "")
        notes = []
        for i in range(8):
            key = f"{ability_tooltip}_Note{i}"
            if key in data:
                notes.append(data[key])
        ability.note = "" if len(notes) == 0 else "\n".join(notes)

        ability_special = json.loads(ability.ability_special,
                                     object_pairs_hook=OrderedDict)
        ability_special = ability_special_add_talent(ability_special,
                                                     session.query(Ability))
        ability_special = ability_special_add_header(ability_special, data,
                                                     ability.name)
        ability.ability_special = json.dumps(ability_special, indent=4)
        ability.description = clean_description(ability.description,
                                                ability_special)

    print("- adding ability icon files")
    # Add img files to ability
    for ability in session.query(Ability):
        if os.path.isfile(config.vpk_path + paths['ability_icon_path'] +
                          ability.name + ".png"):
            ability.icon = paths['ability_icon_path'] + ability.name + ".png"
        else:
            ability.icon = paths['ability_icon_path'] + "wisp_empty1.png"

    session.commit()
예제 #12
0
def load():
    session.query(Hero).delete()
    print("Heroes")

    # load all of the hero scripts data information
    data = valve_readfile(config.vpk_path, paths['hero_scripts_file'],
                          "kv")["DOTAHeroes"]
    progress = ProgressBar(len(data), title="- loading from hero scripts")
    for heroname in data:
        progress.tick()
        if (heroname == "Version" or heroname == "npc_dota_hero_target_dummy"
                or heroname == "npc_dota_hero_base"):
            continue

        hero = Hero()
        hero_data = data[heroname]

        def get_val(key):
            if key in hero_data:
                return hero_data[key]
            else:
                return data["npc_dota_hero_base"].get(key)

        hero.full_name = heroname
        hero.media_name = hero_data['VoiceFile'][37:-9]
        hero.name = heroname.replace("npc_dota_hero_", "")
        hero.id = get_val('HeroID')
        hero.team = get_val('Team')
        hero.base_health_regen = get_val('StatusHealthRegen')
        hero.base_movement = get_val('MovementSpeed')
        hero.turn_rate = get_val('MovementTurnRate')
        hero.base_armor = get_val('ArmorPhysical')
        hero.magic_resistance = get_val('MagicalResistance')
        hero.attack_range = get_val('AttackRange')
        hero.attack_projectile_speed = get_val('ProjectileSpeed')
        hero.attack_damage_min = get_val('AttackDamageMin')
        hero.attack_damage_max = get_val('AttackDamageMax')
        hero.attack_rate = get_val('AttackRate')
        hero.attack_point = get_val('AttackAnimationPoint')
        hero.attr_primary = attribute_dict[get_val('AttributePrimary')]
        hero.attr_strength_base = get_val('AttributeBaseStrength')
        hero.attr_strength_gain = get_val('AttributeStrengthGain')
        hero.attr_intelligence_base = get_val('AttributeBaseIntelligence')
        hero.attr_intelligence_gain = get_val('AttributeIntelligenceGain')
        hero.attr_agility_base = get_val('AttributeBaseAgility')
        hero.attr_agility_gain = get_val('AttributeAgilityGain')
        hero.vision_day = get_val('VisionDaytimeRange')
        hero.vision_night = get_val('VisionNighttimeRange')
        hero.is_melee = get_val(
            'AttackCapabilities') == "DOTA_UNIT_CAP_MELEE_ATTACK"
        hero.material = get_val('GibType')
        hero.roles = hero_data.get('Role', '').replace(',', '|')
        hero.role_levels = hero_data.get('Rolelevels', '').replace(',', '|')
        glow_color = hero_data.get('HeroGlowColor', None)
        if glow_color:
            hero.color = "#{0:02x}{1:02x}{2:02x}".format(
                *map(int, glow_color.split(' ')))

        hero.json_data = json.dumps(hero_data, indent=4)

        talents = []

        # Link abilities and add talents
        for slot in range(1, 30):
            if "Ability" + str(slot) in hero_data:
                ability = session.query(Ability).filter_by(
                    name=hero_data["Ability" + str(slot)]).first()
                if ability.name.startswith("special_bonus"):
                    talents.append(ability.localized_name)
                else:
                    ability.hero_id = hero.id
                    ability.ability_slot = slot
        if len(talents) != 8:
            raise ValueError("{} only has {} talents?".format(
                hero.localized_name, len(talents)))
        hero.talents = "|".join(talents)

        session.add(hero)

    print("- loading hero names from dota_english file")
    # Load hero names from dota_english file
    data = valve_readfile(config.vpk_path,
                          paths['dota_english_file'],
                          "kv",
                          encoding="UTF-16")["lang"]["Tokens"]
    for hero in session.query(Hero):
        hero.localized_name = data[hero.full_name]
        hero.hype = data[hero.full_name + "_hype"]

    print("- loading bio from hero lore file")
    # Load bio from hero lore file
    data = valve_readfile(config.vpk_path,
                          paths['localization_hero_lore'],
                          "kv",
                          encoding="UTF-16")["hero_lore"]
    for hero in session.query(Hero):
        hero.bio = data[hero.full_name + "_bio"].replace("<br>", "\n")

    print("- adding hero image files")
    # Add img files to hero
    for hero in session.query(Hero):
        hero.icon = paths['hero_icon_path'] + hero.name + ".png"
        hero.image = paths['hero_image_path'] + hero.name + ".png"
        hero.portrait = paths['hero_selection_path'] + hero.full_name + ".png"

    print("- adding hero real names")
    data = read_json("builderdata/hero_names.json")
    for hero in session.query(Hero):
        hero.real_name = data.get(hero.name, "")

    print("- adding hero aliases")
    data = read_json("builderdata/hero_aliases.json")
    for hero in session.query(Hero):
        aliases = []
        aliases.append(hero.name.replace("_", " "))
        text = re.sub(r'[^a-z^\s]', r'',
                      hero.localized_name.replace("_", " ").lower())
        if text not in aliases:
            aliases.append(text)
        if hero.real_name != "":
            aliases.append(re.sub(r'[^a-z^\s]', r'', hero.real_name.lower()))
        aliases.extend(data.get(hero.name, []))
        hero.aliases = "|".join(aliases)

    print("- adding hero colors")
    data = read_json("builderdata/hero_colors.json")
    for hero_name in data:
        hero = session.query(Hero).filter_by(name=hero_name).first()
        hero.color = data[hero_name]

    session.commit()
예제 #13
0
def load():
    session.query(Voice).delete()
    print("Voices")

    print("- loading from heroes")
    for hero in session.query(Hero):
        voice = Voice()

        voice.id = hero.id
        voice.name = hero.localized_name
        voice.icon = hero.icon
        voice.image = hero.portrait
        voice.url = name_to_url(hero.localized_name) + "/Responses"

        voice.vsndevts_path = "/" + json.loads(hero.json_data).get("VoiceFile")
        voice.hero_id = hero.id

        session.add(voice)

    print("- loading cosmetics file (takes a bit)")
    data = valve_readfile(config.vpk_path,
                          paths['cosmetics_scripts_file'],
                          "kv_nocomment",
                          encoding="UTF-8")["items_game"]["items"]

    custom_urls = {
        "Announcer: Tuskar": "Announcer:_Tusk",
        "Default Announcer": "Announcer_responses",
        "Default Mega-Kill Announcer": "Announcer_responses",
        "Announcer: Bristleback": "Bristleback_Announcer_Pack",
        "Mega-Kills: Bristleback": "Bristleback_Announcer_Pack"
    }
    custom_vsndevts = {
        "Default Announcer":
        "/soundevents/voscripts/game_sounds_vo_announcer.vsndevts",
        "Default Mega-Kill Announcer":
        "/soundevents/voscripts/game_sounds_vo_announcer_killing_spree.vsndevts",
        "Announcer: Kunkka & Tidehunter":
        "/soundevents/voscripts/game_sounds_vo_announcer_dlc_kunkka_tide.vsndevts",
        "Mega-Kills: Kunkka & Tidehunter":
        "/soundevents/voscripts/game_sounds_vo_announcer_dlc_kunkka_tide_killing_spree.vsndevts"
    }

    print("- loading from announcers")
    for key in data:
        announcer = data[key]
        if announcer.get("prefab") != "announcer":
            continue

        voice = Voice()

        # the first announcer has id = 586, so this will not interfere with hero ids
        voice.id = int(key)
        voice.name = announcer["name"]
        voice.icon = "/panorama/images/icon_announcer_psd.png"
        voice.image = f"/panorama/images/{announcer['image_inventory']}_png.png"

        if voice.name in custom_urls:
            voice.url = custom_urls[voice.name]
        else:
            voice.url = name_to_url(announcer["name"])

        if voice.name in custom_vsndevts:
            voice.vsndevts_path = custom_vsndevts[voice.name]
        else:
            for asset in announcer["visuals"]:
                if announcer["visuals"][asset]["type"] == "announcer":
                    voice.vsndevts_path = "/" + announcer["visuals"][asset][
                        "modifier"]

        session.add(voice)

    print("- associating announcer packs")
    for key in data:
        pack = data[key]
        if pack.get("prefab") != "bundle" or pack.get(
                "name") == "Assembly of Announcers Pack":
            continue
        for name in pack.get("bundle", []):
            for voice in session.query(Voice).filter_by(name=name):
                voice.url = name_to_url(pack["name"])

    data = read_json("builderdata/voice_actors.json")
    print("- adding voice actors")
    for voice in session.query(Voice):
        if str(voice.id) in data:
            voice.voice_actor = data[str(voice.id)]

    session.commit()