Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions tf2utilities/.claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"permissions": {
"allow": [
"Read(//mnt/c/Users/vytal/OneDrive/Desktop/Liquid GH/python-tf2-utilities/**)"
],
"deny": [],
"ask": []
}
}
128 changes: 82 additions & 46 deletions tf2utilities/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import requests.exceptions
from tf2utilities.schema import Schema
from threading import Thread
import time
import logging

# Configure logging
logger = logging.getLogger(__name__)


class TF2:
Expand All @@ -22,55 +27,86 @@ def updater(self):
time.sleep(self.updateTime)


# Gets the schema from the TF2 API
# Gets the schema from the TF2 API with backup fallback
def getSchema(self):
if self.apiKey is not None:
raw = {
"schema": Schema.getOverview(self.apiKey) | {"items": Schema.getItems(self.apiKey), "paintkits": Schema.getPaintKits()},
"items_game": Schema.getItemsGame()
}
maxAttempts = 3
lastError = None

for attempt in range(maxAttempts):
try:
logger.info(f"Fetching schema from API (attempt {attempt + 1}/{maxAttempts})...")

raw = {
"schema": Schema.getOverview(self.apiKey) | {"items": Schema.getItems(self.apiKey), "paintkits": Schema.getPaintKits()},
"items_game": Schema.getItemsGame()
}

if self.lite:
del raw["schema"]["originNames"]
del raw["schema"]["item_sets"]
del raw["schema"]["item_levels"]
del raw["schema"]["string_lookups"]

del raw["items_game"]["game_info"]
del raw["items_game"]["qualities"]
del raw["items_game"]["colors"]
del raw["items_game"]["rarities"]
del raw["items_game"]["equip_regions_list"]
del raw["items_game"]["equip_conflicts"]
del raw["items_game"]["quest_objective_conditions"]
del raw["items_game"]["item_series_types"]
del raw["items_game"]["item_collections"]
del raw["items_game"]["operations"]
del raw["items_game"]["prefabs"]
del raw["items_game"]["attributes"]
del raw["items_game"]["item_criteria_templates"]
del raw["items_game"]["random_attribute_templates"]
del raw["items_game"]["lootlist_job_template_definitions"]
del raw["items_game"]["item_sets"]
del raw["items_game"]["client_loot_lists"]
del raw["items_game"]["revolving_loot_lists"]
del raw["items_game"]["recipes"]
del raw["items_game"]["achievement_rewards"]
del raw["items_game"]["attribute_controlled_attached_particles"]
del raw["items_game"]["armory_data"]
del raw["items_game"]["item_levels"]
del raw["items_game"]["kill_eater_score_types"]
del raw["items_game"]["mvm_maps"]
del raw["items_game"]["mvm_tours"]
del raw["items_game"]["matchmaking_categories"]
del raw["items_game"]["maps"]
del raw["items_game"]["master_maps_list"]
del raw["items_game"]["steam_packages"]
del raw["items_game"]["community_market_item_remaps"]
del raw["items_game"]["war_definitions"]

schema = {"time": time.time(), "raw": raw}
if isinstance(schema, dict):
self.schema = Schema(schema)
# Save successful schema as backup
Schema.saveBackup(schema)
logger.info("Schema fetched successfully from API")
return
else:
raise Exception("Schema is not a dict.")

if self.lite:
del raw["schema"]["originNames"]
del raw["schema"]["item_sets"]
del raw["schema"]["item_levels"]
del raw["schema"]["string_lookups"]
except Exception as e:
lastError = e
logger.error(f"Failed to fetch schema (attempt {attempt + 1}/{maxAttempts}): {str(e)}")
if attempt < maxAttempts - 1:
delay = 10 * (attempt + 1)
logger.info(f"Retrying in {delay} seconds...")
time.sleep(delay)

del raw["items_game"]["game_info"]
del raw["items_game"]["qualities"]
del raw["items_game"]["colors"]
del raw["items_game"]["rarities"]
del raw["items_game"]["equip_regions_list"]
del raw["items_game"]["equip_conflicts"]
del raw["items_game"]["quest_objective_conditions"]
del raw["items_game"]["item_series_types"]
del raw["items_game"]["item_collections"]
del raw["items_game"]["operations"]
del raw["items_game"]["prefabs"]
del raw["items_game"]["attributes"]
del raw["items_game"]["item_criteria_templates"]
del raw["items_game"]["random_attribute_templates"]
del raw["items_game"]["lootlist_job_template_definitions"]
del raw["items_game"]["item_sets"]
del raw["items_game"]["client_loot_lists"]
del raw["items_game"]["revolving_loot_lists"]
del raw["items_game"]["recipes"]
del raw["items_game"]["achievement_rewards"]
del raw["items_game"]["attribute_controlled_attached_particles"]
del raw["items_game"]["armory_data"]
del raw["items_game"]["item_levels"]
del raw["items_game"]["kill_eater_score_types"]
del raw["items_game"]["mvm_maps"]
del raw["items_game"]["mvm_tours"]
del raw["items_game"]["matchmaking_categories"]
del raw["items_game"]["maps"]
del raw["items_game"]["master_maps_list"]
del raw["items_game"]["steam_packages"]
del raw["items_game"]["community_market_item_remaps"]
del raw["items_game"]["war_definitions"]
# All attempts failed, try loading from backup
logger.warning(f"All {maxAttempts} attempts to fetch schema from API failed. Trying backup schema...")
backupSchema = Schema.loadBackup()

schema = {"time": time.time(), "raw": raw}
if isinstance(schema, dict):
self.schema = Schema(schema)
if backupSchema is not None:
logger.info("Using backup schema")
self.schema = Schema(backupSchema)
else:
raise Exception("Schema is not a dict.")
# No backup available, raise the error
logger.error("No backup schema available. Cannot initialize TF2 library.")
raise Exception(f"Failed to fetch schema after {maxAttempts} attempts and no backup available. Last error: {str(lastError)}")
Loading