From 99ce7d273912f10bcdeb45b1632e84dcf2700b97 Mon Sep 17 00:00:00 2001 From: freyamade Date: Tue, 11 Feb 2025 17:18:10 +0100 Subject: [PATCH 01/12] update xivapi url to v2, and add a user-agent for ack --- backend/api/xivapi_item_search_client.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/api/xivapi_item_search_client.py b/backend/api/xivapi_item_search_client.py index 52d9cd9..d0fa516 100644 --- a/backend/api/xivapi_item_search_client.py +++ b/backend/api/xivapi_item_search_client.py @@ -6,10 +6,11 @@ import requests API_KEY = os.environ.get('XIVAPI_KEY', None) +HEADERS = {'User-Agent': f'savageaim.com'} class XIVAPISearchClient: - url = 'https://beta.xivapi.com/api/1/sheet/Item' + url = 'https://v2.xivapi.com/api/1/sheet/Item' @classmethod def get_item_information(cls, *item_ids: int) -> Dict[str, Dict[str, str]]: From 62793f9579427e6f23e166fe33520a26b77eb471 Mon Sep 17 00:00:00 2001 From: freyamade Date: Wed, 5 Mar 2025 10:31:53 +0100 Subject: [PATCH 02/12] add user-agent to xivapi client, also update url --- backend/api/xivapi_item_search_client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/api/xivapi_item_search_client.py b/backend/api/xivapi_item_search_client.py index d0fa516..9439940 100644 --- a/backend/api/xivapi_item_search_client.py +++ b/backend/api/xivapi_item_search_client.py @@ -6,7 +6,7 @@ import requests API_KEY = os.environ.get('XIVAPI_KEY', None) -HEADERS = {'User-Agent': f'savageaim.com'} +HEADERS = {'User-Agent': 'savageaim.com'} class XIVAPISearchClient: @@ -21,7 +21,7 @@ def get_item_information(cls, *item_ids: int) -> Dict[str, Dict[str, str]]: item_ids = set(item_ids) rows = ','.join(str(item_id) for item_id in item_ids) url = f'{cls.url}?rows={rows}&fields=row_id,LevelItem.value,Name' - response = requests.get(url) + response = requests.get(url, headers=HEADERS) response.raise_for_status() for item in response.json().get('rows', []): From 0e640a2adc4a816a5296470788c97ad9bd6a6529 Mon Sep 17 00:00:00 2001 From: freyamade Date: Wed, 5 Mar 2025 16:29:31 +0100 Subject: [PATCH 03/12] add test for midtier fight purchase issue --- backend/api/tests/test_loot_solver.py | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/backend/api/tests/test_loot_solver.py b/backend/api/tests/test_loot_solver.py index cf00623..0b46dfb 100644 --- a/backend/api/tests/test_loot_solver.py +++ b/backend/api/tests/test_loot_solver.py @@ -1725,3 +1725,35 @@ def test_removed_pop_was_none_bug(self): self.assertEqual(len(expected), len(received), received) for i in range(len(expected)): self.assertDictEqual(expected[i], received[i], f'{i+1}/{len(received)}') + + def test_purchases_are_limited_to_tomes_only_in_midtier_fights(self): + """ + There are some errors in the loot solver for fights 2/3 where it could be expecting armour piece buys for the same price as an augment. + """ + weeks = 2 + second_floor_requirements = { + 'head': [1, 2, 3, 4], + 'hands': [1, 2, 5, 6], + 'feet': [5, 6, 7, 8, 3, 4], + 'tome-accessory-augment': [1, 1, 1, 2, 2, 2, 5, 5, 6, 6], + } + second_floor_prios = { + 5: [1, 2], + 4: [5, 6], + 2: [3, 4], + 1: [7, 8], + } + + expected = [ + {'Head': 1, 'Hands': 2, 'Feet': 5, 'Tome Accessory Augment': 6, 'token': True}, + {'Head': 3, 'Hands': 1, 'Feet': 4, 'Tome Accessory Augment': 2, 'token': False}, + {'Head': 2, 'Hands': 5, 'Feet': 6, 'Tome Accessory Augment': 1, 'token': False}, + {'Head': 4, 'Hands': 6, 'Feet': 7, 'Tome Accessory Augment': 295, 'token': True}, + {'Head': None, 'Hands': None, 'Feet': 8, 'Tome Accessory Augment': None, 'token': False}, + {'Head': None, 'Hands': None, 'Feet': 3, 'Tome Accessory Augment': None, 'token': False}, + ] + received = LootSolver._get_handout_data(LootSolver.SECOND_FLOOR_SLOTS, second_floor_requirements, second_floor_prios, LootSolver.SECOND_FLOOR_TOKENS, weeks, False) + self.assertEqual(len(expected), len(received), received) + for i in range(len(expected)): + self.assertDictEqual(expected[i], received[i], f'{i+1}/{len(received)}') + From fe2c653ea72ca3699c662a737b1ad2ee9b264ef3 Mon Sep 17 00:00:00 2001 From: freyamade Date: Wed, 5 Mar 2025 18:41:23 +0100 Subject: [PATCH 04/12] fix token handouts for mid-tier fights and also fix bug with not rechecking uniqueness after handouts --- backend/api/views/loot_solver.py | 62 ++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/backend/api/views/loot_solver.py b/backend/api/views/loot_solver.py index a392bed..63fde0a 100644 --- a/backend/api/views/loot_solver.py +++ b/backend/api/views/loot_solver.py @@ -417,16 +417,27 @@ def _get_handout_data(slots: List[str], requirements: Requirements, prio_bracket except ValueError: pass - # Now remove the item from everyone else + # Now remove the item from everyone else, and check for any now-unique items for other_member_id, other_member_items in potential_loot_members.items(): try: other_member_items.remove(item) + if len(other_member_items) == 1: + # Put the person and their item into the queue + handout_queue.append((other_member_id, other_member_items[0])) except ValueError: # If the item isn't in the list, that's fine - continue - if len(other_member_items) == 1: - # Put the person and their item into the queue - handout_queue.append((other_member_id, other_member_items[0])) + pass + + # Also recalc if someone now has a unique item that they should get + member_items_set = set(other_member_items) + other_set = set() + for other_other_member_id, other_other_member_items in potential_loot_members.items(): + if other_member_id == other_other_member_id: + continue + other_set |= set(other_other_member_items) + uniques = member_items_set - other_set + for unique_item in uniques: + handout_queue.append((other_member_id, unique_item)) # Then do some checking if we need to re_insert the popped member if re_insert: @@ -436,29 +447,34 @@ def _get_handout_data(slots: List[str], requirements: Requirements, prio_bracket # Add the week data to the handouts list handouts.append(week_data) - # Lastly, if weeks % token_count == 0, reduce everyone's requirement by 1 + # Lastly, if weeks % token_count == 0, reduce everyone's requirement by 1 if they can buy an item if weeks % weeks_per_token == 0: - for priority in sorted(prio_brackets): - prio_brackets[priority - 1] = prio_brackets[priority] - - # Need to also remove a loot item for everyone in the priority bracket to keep the requirements info in check - for member_id in prio_brackets[priority]: - # Reverse slots so that we always pop tokens if possible + # Find the members that can buy something and track what they can buy + member_purchases = {} + for remove_prio in sorted(prio_brackets, reverse=True): + member_ids = prio_brackets[remove_prio] + for member_id in member_ids: for slot in remove_slots: + if member_id in requirements[slot] and member_id not in member_purchases: + member_purchases[member_id] = slot + + for purchaser_id, slot in member_purchases.items(): + # Remove the purchaser_id from the item requirements, reduce their priority by one + requirements[slot].remove(purchaser_id) + for remove_prio in sorted(prio_brackets): + if purchaser_id in prio_brackets[remove_prio]: + prio_brackets[remove_prio].remove(purchaser_id) try: - requirements[slot].remove(member_id) - break - except ValueError: - # Keep searching until we find one - pass + prio_brackets[remove_prio - 1].append(purchaser_id) + except KeyError: + prio_brackets[remove_prio - 1] = [purchaser_id] + break - # Remove the 0 key and the highest key because that will have been duplicated + # Remove 0 key, and any empty lists prio_brackets.pop(0, None) - try: - prio_brackets.pop(max(prio_brackets.keys()), None) - except ValueError: - # 0 is also the max and we removed it? - pass + for priority in list(prio_brackets.keys()): + if prio_brackets[priority] == []: + prio_brackets.pop(priority, None) week_data['token'] = True else: week_data['token'] = False From 206b090ec76dd4a600adb2ae6bd9b02e9379d5dd Mon Sep 17 00:00:00 2001 From: freyamade Date: Wed, 5 Mar 2025 18:41:35 +0100 Subject: [PATCH 05/12] add docker ignore files just in case --- backend/.dockerignore | 5 +++++ frontend/.dockerignore | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 backend/.dockerignore create mode 100644 frontend/.dockerignore diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..99d2df1 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,5 @@ +**/__pycache__ +api/tests +deployment +.coveragerc +.dockerignore diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..639f996 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,4 @@ +node_modules +dist +.editorconfig +.eslintrc.js From 9e1af313c9028efd0c14601d451f761314834d1d Mon Sep 17 00:00:00 2001 From: freyamade Date: Wed, 5 Mar 2025 18:41:52 +0100 Subject: [PATCH 06/12] fix tests that broke due to tweaks in the lootsolver algorithm --- backend/api/tests/test_loot_solver.py | 32 +++++++++++++++++++-------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/backend/api/tests/test_loot_solver.py b/backend/api/tests/test_loot_solver.py index 0b46dfb..d1be3c7 100644 --- a/backend/api/tests/test_loot_solver.py +++ b/backend/api/tests/test_loot_solver.py @@ -809,6 +809,21 @@ def test_whole_view_split_loot(self): def test_solver_sort_overrides(self): """ Ensure that overriding the solver sort order actually affects the way the members are ordered. + + expected = { + 'earrings': [self.tm5.id, self.tm6.id], + 'necklace': [self.tm1.id, self.tm2.id, self.tm3.id, self.tm4.id, self.tm7.id, self.tm8.id], + 'bracelet': [self.tm3.id, self.tm4.id, self.tm5.id, self.tm6.id], + 'ring': [self.tm5.id, self.tm6.id, self.tm7.id, self.tm8.id], + 'head': [self.tm1.id, self.tm2.id, self.tm3.id, self.tm5.id, self.tm7.id, self.tm8.id], + 'hands': [self.tm1.id, self.tm2.id, self.tm7.id], + 'feet': [self.tm3.id, self.tm4.id, self.tm5.id, self.tm6.id, self.tm8.id], + 'tome-accessory-augment': [self.tm1.id, self.tm1.id, self.tm1.id, self.tm2.id, self.tm2.id, self.tm2.id, self.tm3.id, self.tm3.id, self.tm4.id, self.tm4.id, self.tm5.id, self.tm5.id, self.tm6.id, self.tm6.id, self.tm7.id, self.tm7.id, self.tm7.id, self.tm8.id, self.tm8.id, self.tm8.id], + 'body': [self.tm3.id, self.tm4.id, self.tm5.id, self.tm6.id, self.tm8.id], + 'legs': [self.tm1.id, self.tm2.id, self.tm7.id], + 'tome-armour-augment': [self.tm1.id, self.tm1.id, self.tm2.id, self.tm2.id, self.tm3.id, self.tm3.id, self.tm4.id, self.tm4.id, self.tm4.id, self.tm5.id, self.tm5.id, self.tm6.id, self.tm6.id, self.tm6.id, self.tm7.id, self.tm7.id, self.tm8.id, self.tm8.id], + 'mainhand': [self.tm1.id, self.tm2.id, self.tm3.id, self.tm4.id, self.tm5.id, self.tm6.id, self.tm7.id, self.tm8.id], + } """ # First test while the team has no overrides to ensure the list matches what we expect member_order = LootSolver._get_team_solver_sort_order(self.team) @@ -850,8 +865,8 @@ def test_solver_sort_overrides(self): {'token': False, 'Head': self.tm2.id, 'Hands': self.tm7.id, 'Feet': self.tm8.id, 'Tome Accessory Augment': self.tm1.id}, {'token': False, 'Head': self.tm3.id, 'Hands': self.tm2.id, 'Feet': self.tm5.id, 'Tome Accessory Augment': self.tm8.id}, {'token': True, 'Head': self.tm7.id, 'Hands': self.tm1.id, 'Feet': self.tm6.id, 'Tome Accessory Augment': self.tm4.id}, - {'token': False, 'Head': self.tm8.id, 'Hands': None, 'Feet': self.tm3.id, 'Tome Accessory Augment': self.tm2.id}, - {'token': False, 'Head': self.tm5.id, 'Hands': None, 'Feet': self.tm4.id, 'Tome Accessory Augment': self.tm7.id}, + {'token': False, 'Head': self.tm5.id, 'Hands': None, 'Feet': self.tm3.id, 'Tome Accessory Augment': self.tm2.id}, + {'token': False, 'Head': self.tm8.id, 'Hands': None, 'Feet': self.tm4.id, 'Tome Accessory Augment': self.tm7.id}, {'token': True, 'Head': self.tm1.id, 'Hands': None, 'Feet': None, 'Tome Accessory Augment': self.tm6.id}, ] @@ -1671,12 +1686,12 @@ def test_dev_setup_edgecase_bug_solution(self): } expected = [ - {'token': False, 'Head': 4, 'Hands': 2, 'Feet': 4, 'Tome Accessory Augment': 3}, - {'token': False, 'Head': 3, 'Hands': 4, 'Feet': 2, 'Tome Accessory Augment': 2}, - {'token': True, 'Head': 2, 'Hands': 3, 'Feet': None, 'Tome Accessory Augment': 4}, - {'token': False, 'Head': None, 'Hands': None, 'Feet': None, 'Tome Accessory Augment': 4}, + {'token': False, 'Head': 4, 'Hands': 3, 'Feet': 2, 'Tome Accessory Augment': 4}, + {'token': False, 'Head': 3, 'Hands': 2, 'Feet': 4, 'Tome Accessory Augment': 4}, + {'token': True, 'Head': 2, 'Hands': 4, 'Feet': None, 'Tome Accessory Augment': 3}, {'token': False, 'Head': None, 'Hands': None, 'Feet': None, 'Tome Accessory Augment': 2}, - {'token': True, 'Head': None, 'Hands': None, 'Feet': None, 'Tome Accessory Augment': 4}, + {'token': False, 'Head': None, 'Hands': None, 'Feet': None, 'Tome Accessory Augment': 4}, + {'token': True, 'Head': None, 'Hands': None, 'Feet': None, 'Tome Accessory Augment': 2}, ] received = LootSolver._get_handout_data( LootSolver.SECOND_FLOOR_SLOTS, @@ -1748,7 +1763,7 @@ def test_purchases_are_limited_to_tomes_only_in_midtier_fights(self): {'Head': 1, 'Hands': 2, 'Feet': 5, 'Tome Accessory Augment': 6, 'token': True}, {'Head': 3, 'Hands': 1, 'Feet': 4, 'Tome Accessory Augment': 2, 'token': False}, {'Head': 2, 'Hands': 5, 'Feet': 6, 'Tome Accessory Augment': 1, 'token': False}, - {'Head': 4, 'Hands': 6, 'Feet': 7, 'Tome Accessory Augment': 295, 'token': True}, + {'Head': 4, 'Hands': 6, 'Feet': 7, 'Tome Accessory Augment': 1, 'token': True}, {'Head': None, 'Hands': None, 'Feet': 8, 'Tome Accessory Augment': None, 'token': False}, {'Head': None, 'Hands': None, 'Feet': 3, 'Tome Accessory Augment': None, 'token': False}, ] @@ -1756,4 +1771,3 @@ def test_purchases_are_limited_to_tomes_only_in_midtier_fights(self): self.assertEqual(len(expected), len(received), received) for i in range(len(expected)): self.assertDictEqual(expected[i], received[i], f'{i+1}/{len(received)}') - From 878fdaa53b5427e1e101de139bfd9ae5ef64c525 Mon Sep 17 00:00:00 2001 From: freyamade Date: Tue, 25 Mar 2025 12:42:01 +0100 Subject: [PATCH 07/12] populated data for 7.2 --- .../commands/seed_data/gear/7-dt/7.2.yml | 38 +++++++++++++++++++ .../management/commands/seed_data/tiers.yml | 12 ++++++ 2 files changed, 50 insertions(+) create mode 100644 backend/api/management/commands/seed_data/gear/7-dt/7.2.yml diff --git a/backend/api/management/commands/seed_data/gear/7-dt/7.2.yml b/backend/api/management/commands/seed_data/gear/7-dt/7.2.yml new file mode 100644 index 0000000..108ca84 --- /dev/null +++ b/backend/api/management/commands/seed_data/gear/7-dt/7.2.yml @@ -0,0 +1,38 @@ +- has_accessories: True + has_armour: True + has_weapon: True + item_level: 740 + name: 'Ceremonial' +- has_accessories: True + has_armour: True + has_weapon: False + item_level: 740 + name: 'Cruiser' +- has_accessories: False + has_armour: False + has_weapon: True + item_level: 745 + name: 'Queensknight' + extra_import_names: + - Book of Chivalry + - Word of the Knighthood +- has_accessories: True + has_armour: True + has_weapon: True + item_level: 750 + name: 'Historia' +- has_accessories: True + has_armour: True + has_weapon: True + item_level: 760 + name: 'Augmented Historia' +- has_accessories: True + has_armour: True + has_weapon: False + item_level: 760 + name: 'Babyface Champion' +- has_accessories: False + has_armour: False + has_weapon: True + item_level: 765 + name: 'Babyface Champion' diff --git a/backend/api/management/commands/seed_data/tiers.yml b/backend/api/management/commands/seed_data/tiers.yml index 0e6b596..3c4219e 100644 --- a/backend/api/management/commands/seed_data/tiers.yml +++ b/backend/api/management/commands/seed_data/tiers.yml @@ -1,3 +1,15 @@ +# 7.2 +- raid_gear_name: 'Babyface Champion' + tome_gear_name: 'Augmented Historia' + max_item_level: 765 + name: 'AAC Cruiserweight Tier' + fights: + - 'AAC Cruiserweight M1' + - 'AAC Cruiserweight M2' + - 'AAC Cruiserweight M3' + - 'AAC Cruiserweight M4' + + # 7.0 - raid_gear_name: 'Dark Horse Champion' tome_gear_name: 'Augmented Quetzalli' From 6456b0995fff34320d34c21063622beffeaf2247 Mon Sep 17 00:00:00 2001 From: freyamade Date: Tue, 25 Mar 2025 12:42:15 +0100 Subject: [PATCH 08/12] added test for queensknight gear because it's kinda messy --- backend/api/tests/test_import_api_view.py | 49 +++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 backend/api/tests/test_import_api_view.py diff --git a/backend/api/tests/test_import_api_view.py b/backend/api/tests/test_import_api_view.py new file mode 100644 index 0000000..9168284 --- /dev/null +++ b/backend/api/tests/test_import_api_view.py @@ -0,0 +1,49 @@ +from io import StringIO +from django.core.management import call_command +from django.urls import reverse +from rest_framework import status +from api.models import Gear +from api.serializers import GearSerializer +from .test_base import SavageAimTestCase +from ..views.base import ImportAPIView + + +class ImportAPIViewTestSuite(SavageAimTestCase): + """ + Ensure that gear is correctly imported by the view for finding its IDs + """ + + def setUp(self): + """ + Call the Gear seed command to prepopulate the DB + """ + call_command('seed', stdout=StringIO()) + self.selection = Gear.objects.all().values('name', 'id', 'extra_import_classes', 'extra_import_names') + + def test_queensknight_gear(self): + names_to_check = [ + 'Queensknight Falchion', + 'Queensknight Bardiche', + 'Queensknight Faussar', + 'Queensknight Gunblade', + 'Queensknight Spear', + 'Queensknight Scythe', + 'Queensknight Baghnakhs', + 'Queensknight Blade', + 'Queensknight Knives', + 'Queensknight Twinfangs', + 'Queensknight Compound Bow', + 'Queensknight Pistol', + 'Queensknight War Quoits', + 'Queensknight Scepter', + 'Queensknight Foil', + 'Queensknight Flat Brush', + 'Queensknight Cane', + 'Queensknight Astrometer', + 'Queensknight Syrinxi', + 'Book of Chivalry', + 'Word of the Knighthood', + ] + expected_id = Gear.objects.get(name='Queensknight').pk + for name in names_to_check: + self.assertEqual(ImportAPIView._get_gear_id(self.selection, name), expected_id) From 196202d25d0f19570df2d7e69537588fb5dcc73e Mon Sep 17 00:00:00 2001 From: freyamade Date: Tue, 25 Mar 2025 12:43:21 +0100 Subject: [PATCH 09/12] updated changeloy --- frontend/src/components/modals/changelog.vue | 48 ++++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/frontend/src/components/modals/changelog.vue b/frontend/src/components/modals/changelog.vue index 160b6c4..68ffc70 100644 --- a/frontend/src/components/modals/changelog.vue +++ b/frontend/src/components/modals/changelog.vue @@ -12,39 +12,37 @@

{{ version }}

-
expand_more Loot Solver Algorithm Improvement / Bugfix expand_more
-

Improved Loot Solver algorithm to handle newfound edgecase.

-

Also fixed silly bug in the code that was introduced when fixing the previous Loot Solver bug!

- -

{{ version.split('.')[0] }}.2

-
expand_more Team Delete Bugfix expand_more
-

Quick extra push today to deliver a bugfix to a long hidden bug during Team deletion. Sorry for the inconvenience but thank you for catching it!

-

Thankfully it wasn't an issue for deleting anything, just caused an error at the end of the endpoint call!

- -

{{ version.split('.')[0] }}

-
expand_more Character Verify Bugfix expand_more
-

Fixed a bug during the Character Verification process where it couldn't do cleanup, which first occurred yesterday.

-

For an explanation of the bug and what was done to fix it; +

expand_more FFXIV Patch 7.2 expand_more
+

A new Tier, AAC Cruiserweight Tier, has been added. Please ensure to update your Team to the new Tier to have BIS Table colours display correctly, and best of luck!

+

+ All the gear added with Patch 7.2 has been added to the site, please enjoy updating your BIS Lists for the new Tier!

    -
  • Previously, unverified Characters could not be used to make BIS Lists or join Teams or anything, so when you verified a Character the system would delete all the unverified versions of the same Character by Lodestone ID.
  • -
  • Now however, unverified Characters can be used for a week before everything gets deleted, but this caused a bug in the cleanup process where if an unverified version had a BIS List it couldn't be deleted.
  • -
  • Also, any proxies using the same Character get merged into the verified Character, consolidating all BIS Lists and Team Membership into the verified Character.
  • -
  • The fix I have implemented is to do this consolidation for un-verified Characters belonging to the same User as well, and leaving unverified versions owned by other Users to be deleted after the week deadline.
  • +
  • Ceremonial Weapon, Armour and Accessories - Item Level 740
  • +
  • Cruiser Armour and Accessories - Item Level 740
  • +
  • ????? Trial Weapon - Item Level 745 (name hidden in changelog for spoilers sake)
  • +
  • Historia Weapon, Armour and Accessories - Item Level 750
  • +
  • Augmented Historia Weapon, Armour and Accessories - Item Level 760
  • +
  • Babyface Champion Armour and Accessories - Item Level 760
  • +
  • Babyface Champion Weapon - Item Level 765

-

If anyone would like to share feedback / give ideas on this matter, please let me know on Github or in the Discord, or by using the new addition below. Hopefully this is an acceptable solution!

+

The default values for the Item Level filters in BIS pages have been updated to the new range for Cruiserweight. (740 - 765)

-
expand_more Feedback Form expand_more
+
expand_more Loot Solver Bugfixes expand_more

- Added a little Feedback widget for another mechanism of gathering feedback for people not on Github or don't want to join the Discord. + Fixed a bug where the Loot Solver would assume that you could buy armour pieces from 2nd and 3rd fights of a Tier with the same number of clear-tokens as the tome augmentation items.

    -
  • I need to upgrade the website UI from using Vue 2 to Vue 3; I'm aiming to start on this in the downtime after 7.2 drops.
  • -
  • I intend to keep the site as close as possible as how it is to use currently so if you like how it works then don't worry!
  • -
  • However, if there are bugs/issues that I haven't caught, or if there is anything you think is weird or difficult to use, please let me know!
  • -
  • I want to make this site as good as I can, and I want you all to be as happy as possible using it as well, so please help me if there is anything I should know!
  • +
  • As a reminder, the Solver assumes you only buy Tome Augmentation items from the 2nd and 3rd fights!

-

I wasn't planning on releasing this so soon but I wanted the bugfix out ASAP and this was already in the codebase :D

+

Also fixed some other very well hidden bugs, so thank you to everyone for using the Loot page and giving me good data!

+ +
expand_more Work Commencing on SavageAim "v2" expand_more
+

As mentioned before, I need to update some frontend libraries that the site uses for security and updates sakes.

+

If you have any issues with the site, now is definitely the time to make them known, as I'll be trying to fix a bunch of things while keeping the site looking as much the same as possible!

+

Leave your feedback either in the Discord (link at the bottom of the page) or using the nice lil feedback widget at the bottom right of your page!

+

You can track v2 plans at the GitHub Issue here!

+

Thank you all for your continued support, SavageAim wouldn't be half the tool it is without y'all!

From 78c3fbb1b46a1574594f8f41adfe2b7f46f1b242 Mon Sep 17 00:00:00 2001 From: freyamade Date: Tue, 25 Mar 2025 12:44:04 +0100 Subject: [PATCH 10/12] bump --- backend/backend/__init__.py | 2 +- frontend/.env | 2 +- frontend/src/main.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/backend/__init__.py b/backend/backend/__init__.py index c4c2608..4562293 100644 --- a/backend/backend/__init__.py +++ b/backend/backend/__init__.py @@ -2,4 +2,4 @@ from .celery import app as celery_app -VERSION = '20250108.3' +VERSION = '20250325' diff --git a/frontend/.env b/frontend/.env index 00891bd..da332fc 100644 --- a/frontend/.env +++ b/frontend/.env @@ -1 +1 @@ -VUE_APP_VERSION="20250108.3" +VUE_APP_VERSION="20250325" diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 04f74e8..4a96d8c 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -30,7 +30,7 @@ Sentry.init({ Vue, dsn: 'https://06f41b525a40497a848fb726f6d03244@o242258.ingest.sentry.io/6180221', logErrors: true, - release: 'savageaim@20250108.3', + release: 'savageaim@20250325', integrations: [ Sentry.browserTracingIntegration(), Sentry.replayIntegration(), From 094ee85044d7d63f7c2301c3244093c6007658e4 Mon Sep 17 00:00:00 2001 From: freyamade Date: Tue, 25 Mar 2025 13:46:37 +0100 Subject: [PATCH 11/12] linting py file --- backend/api/tests/test_import_api_view.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/api/tests/test_import_api_view.py b/backend/api/tests/test_import_api_view.py index 9168284..43b9cc4 100644 --- a/backend/api/tests/test_import_api_view.py +++ b/backend/api/tests/test_import_api_view.py @@ -1,9 +1,8 @@ from io import StringIO + from django.core.management import call_command -from django.urls import reverse -from rest_framework import status + from api.models import Gear -from api.serializers import GearSerializer from .test_base import SavageAimTestCase from ..views.base import ImportAPIView From 7ed212b68576265d96bba74d36af37de9a173dc2 Mon Sep 17 00:00:00 2001 From: freyamade Date: Tue, 25 Mar 2025 13:52:42 +0100 Subject: [PATCH 12/12] fix xivapi v2 url --- backend/api/xivapi_item_search_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/api/xivapi_item_search_client.py b/backend/api/xivapi_item_search_client.py index 9439940..44a1344 100644 --- a/backend/api/xivapi_item_search_client.py +++ b/backend/api/xivapi_item_search_client.py @@ -10,7 +10,7 @@ class XIVAPISearchClient: - url = 'https://v2.xivapi.com/api/1/sheet/Item' + url = 'https://v2.xivapi.com/api/sheet/Item' @classmethod def get_item_information(cls, *item_ids: int) -> Dict[str, Dict[str, str]]: