ogri-la / strongbox

a World of Warcraft Addon Manager aimed at Linux players
GNU Affero General Public License v3.0
169 stars 7 forks source link

CurseForge allows mixing retail with classic #63

Closed layday closed 5 years ago

layday commented 5 years ago

CurseForge will let you mark a file as being compatible both with a retail and classic version of the game, meaning that you can't rely on gameVersionFlavor to reflect compatibility, see e.g. Elkano's BuffBars (API response). The practical implication is that an older version might be installed for a selected track - as of writing, wowman will install Elkano's BuffBars version '2.5.2 - r193' as opposed to '2.6.0 - r196', which is supposed to be the latest version for retail. I thought flavour-mixing might've been an oversight on CurseForge's part - gameVersionFlavor being a string would imply that it is - but this is what the file upload interface looks like:

Screen Shot 2019-10-04 at 04 52 05 copy

torkus commented 5 years ago

cheers, @layday , taking a look

torkus commented 5 years ago

ah - if you look at a release's gameVersion and sortableGameVersion keys you can see which game tracks it belongs to. This is what wowman is seeing and will pick either wow_classic or wow_retail depending on the selected game track:

{"wow_classic"
 [{:gameVersionFlavor "wow_classic",
   :gameVersionId 7350,
   :releaseType 1,
   :parentProjectFileId nil,
   :fileLegacyMappingId nil,
   :installMetadata nil,
   :restrictProjectFileAccess 1,
   :isServerPack false,
   :displayName "2.6.0 - r196",
   :modules
   [{:foldername "ElkBuffBars", :fingerprint 3680507189, :type 3}],
   :fileName "ElkBuffBars-r196-alpha.zip",
   :changelog nil,
   :hasInstallScript false,
   :serverPackFileId nil,
   :projectStatus 4,
   :fileLength 234519,
   :exposeAsAlternative nil,
   :fileStatus 4,
   :fileTypeId nil,
   :parentFileLegacyMappingId nil,
   :id 2780935,
   :gameVersionDateReleased "2001-01-01T00:00:00Z",
   :packageFingerprintId 354370370,
   :categorySectionPackageType 1,
   :isAlternate false,
   :projectId 2398,
   :downloadUrl
   "https://edge.forgecdn.net/files/2780/935/ElkBuffBars-r196-alpha.zip",
   :renderCacheId 1647466,
   :isCompatibleWithClient true,
   :isAvailable true,
   :gameId 1,
   :packageFingerprint 2468563366,
   :gameVersionMappingId 1926988,
   :alternateFileId 2780936,
   :dependencies
   [{:id 31536963, :addonId 13376, :type 1, :fileId 2780935}
    {:id 31536967, :addonId 15552, :type 1, :fileId 2780935}
    {:id 31536966, :addonId 20113, :type 4, :fileId 2780935}
    {:id 31536972, :addonId 32855, :type 1, :fileId 2780935}
    {:id 31536970, :addonId 14320, :type 1, :fileId 2780935}
    {:id 31536964, :addonId 13380, :type 1, :fileId 2780935}
    {:id 31536971, :addonId 14328, :type 1, :fileId 2780935}
    {:id 31536969, :addonId 15487, :type 1, :fileId 2780935}
    {:id 31536965, :addonId 15049, :type 1, :fileId 2780935}
    {:id 31536968, :addonId 19651, :type 1, :fileId 2780935}],
   :sortableGameVersion
   [{:gameVersionPadded "0000000001.0000000013.0000000002",
     :gameVersion "1.13.2",
     :gameVersionReleaseDate "2001-01-01T00:00:00Z",
     :gameVersionName "1.13.2"}
    {:gameVersionPadded "0000000008.0000000002.0000000005",
     :gameVersion "8.2.5",
     :gameVersionReleaseDate "2019-09-23T00:00:00Z",
     :gameVersionName "8.2.5"}],
   :fileDate "2019-09-08T12:13:45.507Z",
   :gameVersion ["1.13.2" "8.2.5"]}],

 "wow_retail"
 [{:gameVersionFlavor "wow_retail",
   :gameVersionId 7003,
   :releaseType 1,
   :parentProjectFileId nil,
   :fileLegacyMappingId nil,
   :installMetadata nil,
   :restrictProjectFileAccess 1,
   :isServerPack false,
   :displayName "2.5.2 - r193",
   :modules
   [{:foldername "ElkBuffBars", :fingerprint 3496813571, :type 3}],
   :fileName "ElkBuffBars-r193-alpha.zip",
   :changelog nil,
   :hasInstallScript false,
   :serverPackFileId nil,
   :projectStatus 4,
   :fileLength 232751,
   :exposeAsAlternative nil,
   :fileStatus 4,
   :fileTypeId nil,
   :parentFileLegacyMappingId nil,
   :id 2606182,
   :gameVersionDateReleased "2018-07-17T00:00:00Z",
   :packageFingerprintId 260249662,
   :categorySectionPackageType 1,
   :isAlternate false,
   :projectId 2398,
   :downloadUrl
   "https://edge.forgecdn.net/files/2606/182/ElkBuffBars-r193-alpha.zip",
   :renderCacheId 1434554,
   :isCompatibleWithClient true,
   :isAvailable true,
   :gameId 1,
   :packageFingerprint 895503176,
   :gameVersionMappingId 1649012,
   :alternateFileId 2606183,
   :dependencies
   [{:id 19293166, :addonId 15487, :type 1, :fileId 2606182}
    {:id 19293167, :addonId 14320, :type 1, :fileId 2606182}
    {:id 19293169, :addonId 32855, :type 1, :fileId 2606182}
    {:id 19293163, :addonId 20113, :type 4, :fileId 2606182}
    {:id 19293168, :addonId 14328, :type 1, :fileId 2606182}
    {:id 19293165, :addonId 19651, :type 1, :fileId 2606182}
    {:id 19293162, :addonId 15049, :type 1, :fileId 2606182}
    {:id 19293161, :addonId 13380, :type 1, :fileId 2606182}
    {:id 19293160, :addonId 13376, :type 1, :fileId 2606182}
    {:id 19293164, :addonId 15552, :type 1, :fileId 2606182}],
   :sortableGameVersion
   [{:gameVersionPadded "0000000008.0000000000.0000000001",
     :gameVersion "8.0.1",
     :gameVersionReleaseDate "2018-07-17T00:00:00Z",
     :gameVersionName "8.0.1"}],
   :fileDate "2018-08-20T16:22:31.837Z",
   :gameVersion ["8.0.1"]}]}

but as you point out, we can see the older 2.5.2 doesn't have any mention of a 1.13.x version and 2.6.0 has both.

Version 0.10 of wowman is nearing release. I can find a fix and include it in that

layday commented 5 years ago

If wowman is using the gameVersion array that raises another issue:

>>> len([f for a in data for f in a['latestFiles'] if not f['gameVersion']])                                                                                                
72

I am rather convinced the CurseForge API was designed by a madman.

torkus commented 5 years ago

I never managed to wrap my head around those nested list comprehensions in python :confused:

if not f['gameVersion']

so we can't count on gameVersion always being present?

layday commented 5 years ago

They read left to right. That list comprehension is the equivalent of:

for a in data:
    for f in a['latestFiles']:
        if not f['gameVersion']:
            yield f

so we can't count on gameVersion always being present?

It is present but empty, for all of these:

>>> {(f['gameVersionFlavor'], a['slug']) for a in data for f in a['latestFiles'] if not f['gameVersion'] and not f['exposeAsAlternative']}                                  
{('wow_classic', 'broker-classictracking'),
 ('wow_classic', 'classicauradurations'),
 ('wow_classic', 'classicgearset'),
 ('wow_classic', 'ema-classic'),
 ('wow_classic', 'fast-guild-invite'),
 ('wow_classic', 'galvins-unitbars-classic'),
 ('wow_classic', 'greyhandling'),
 ('wow_classic', 'guidelime_dungeonquests'),
 ('wow_classic', 'guildhelperclassic'),
 ('wow_classic', 'leatrix-maps-classic'),
 ('wow_classic', 'leatrix-plus-classic'),
 ('wow_classic', 'lfg-classic'),
 ('wow_classic', 'mobinfo2-classic'),
 ('wow_classic', 'mychatalert'),
 ('wow_classic', 'pally-power'),
 ('wow_classic', 'project-2289'),
 ('wow_classic', 'questlogexperience'),
 ('wow_classic', 'radar'),
 ('wow_classic', 'rosterfilter'),
 ('wow_classic', 'simpleautocombatlog'),
 ('wow_classic', 'simpleenergybar'),
 ('wow_classic', 'skillet-classic'),
 ('wow_retail', 'astral-keys'),
 ('wow_retail', 'autogear'),
 ('wow_retail', 'battle_pet_breedid'),
 ('wow_retail', 'broker-lootspec'),
 ('wow_retail', 'broker_digicam'),
 ('wow_retail', 'collectionshop'),
 ('wow_retail', 'dressingroomfunctions'),
 ('wow_retail', 'elkfriends'),
 ('wow_retail', 'elvui-enhanced-again'),
 ('wow_retail', 'enhanced-raid-frames'),
 ('wow_retail', 'experiencer'),
 ('wow_retail', 'fps-counter'),
 ('wow_retail', 'galvins-unitbars'),
 ('wow_retail', 'gearhelper'),
 ('wow_retail', 'greyhandling'),
 ('wow_retail', 'kkthnxui'),
 ('wow_retail', 'leatrix-maps'),
 ('wow_retail', 'leatrix-plus'),
 ('wow_retail', 'magic-marker'),
 ('wow_retail', 'method-dungeon-tools'),
 ('wow_retail', 'neatplates'),
 ('wow_retail', 'quiktells'),
 ('wow_retail', 'raider-io-lod-database-eu-alliance'),
 ('wow_retail', 'raider-io-lod-database-eu-alliance-raid'),
 ('wow_retail', 'raider-io-lod-database-eu-horde'),
 ('wow_retail', 'raider-io-lod-database-eu-horde-raid'),
 ('wow_retail', 'raider-io-lod-database-kr-alliance'),
 ('wow_retail', 'raider-io-lod-database-kr-alliance-raid'),
 ('wow_retail', 'raider-io-lod-database-kr-horde'),
 ('wow_retail', 'raider-io-lod-database-kr-horde-raid'),
 ('wow_retail', 'raider-io-lod-database-tw-alliance'),
 ('wow_retail', 'raider-io-lod-database-tw-alliance-raid'),
 ('wow_retail', 'raider-io-lod-database-tw-horde'),
 ('wow_retail', 'raider-io-lod-database-tw-horde-raid'),
 ('wow_retail', 'raider-io-lod-database-us-alliance'),
 ('wow_retail', 'raider-io-lod-database-us-alliance-raid'),
 ('wow_retail', 'raider-io-lod-database-us-horde'),
 ('wow_retail', 'raider-io-lod-database-us-horde-raid'),
 ('wow_retail', 'raiderio')}
torkus commented 5 years ago

yeah, getting some dejavu now. I remember encountering empty gameVersion lists initially.

I think what I'll do with wowman is use gameVersion if it exists to potentially avoid installing older releases and then fall back to the current method if gameVersion is empty.

Makes you wonder if gameVersion is even accurate when present.

torkus commented 5 years ago

working happening here: https://github.com/ogri-la/wowman/pull/64

torkus commented 5 years ago

fixed. will be part of release 0.10.0

thanks @layday , I appreciate the bugs