Add support for un/"supported_games" in mod.conf

This commit is contained in:
rubenwardy 2022-06-24 23:55:44 +01:00
parent f22911b4a0
commit d6887d7b46
4 changed files with 43 additions and 14 deletions

@ -37,6 +37,8 @@ ContentDB understands the following information:
and for mods only: and for mods only:
* `name` - the mod technical name. * `name` - the mod technical name.
* `supported_games` - List of supported game technical names.
* `unsupported_games` - List of not supported game technical names. Useful to override game support detection.
## .cdb.json ## .cdb.json

@ -17,7 +17,7 @@
import sys import sys
from typing import List, Dict, Optional, Iterator, Iterable from typing import List, Dict, Optional, Iterator, Iterable, Tuple
from app.logic.LogicError import LogicError from app.logic.LogicError import LogicError
from app.models import Package, MetaPackage, PackageType, PackageState, PackageGameSupport, db from app.models import Package, MetaPackage, PackageType, PackageState, PackageGameSupport, db
@ -167,25 +167,23 @@ class GameSupportResolver:
db.session.add(support) db.session.add(support)
""" """
Add supported game to a package, given the confidence. Update game supported package on a package, given the confidence.
Higher confidences outweigh lower ones. Higher confidences outweigh lower ones.
""" """
def add_supported(self, package: Package, supported_games: PackageSet, confidence: int): def set_supported(self, package: Package, game_is_supported: List[Tuple[Package, bool]], confidence: int):
previous_supported: Dict[str, PackageGameSupport] = {} previous_supported: Dict[int, PackageGameSupport] = {}
for support in package.supported_games.all(): for support in package.supported_games.all():
db.session.merge(support.game) db.session.merge(support.game)
previous_supported[support.game.getId()] = support previous_supported[support.game.id] = support
for game in supported_games: for game, supports in game_is_supported:
assert game lookup = previous_supported.pop(game.id, None)
lookup = previous_supported.pop(game.getId(), None)
if lookup is None: if lookup is None:
support = PackageGameSupport(package, game, confidence) support = PackageGameSupport(package, game, confidence)
db.session.add(support) db.session.add(support)
elif lookup.confidence <= confidence: elif lookup.confidence <= confidence:
lookup.supports = True lookup.supports = supports
lookup.confidence = confidence lookup.confidence = confidence
db.session.merge(lookup) db.session.merge(lookup)
@ -195,4 +193,9 @@ class GameSupportResolver:
def update(self, package: Package) -> None: def update(self, package: Package) -> None:
retval = self.resolve(package, []) retval = self.resolve(package, [])
self.add_supported(package, retval, 1)
game_is_supported = []
for game in retval:
game_is_supported.append((game, True))
self.set_supported(package, game_is_supported, 1)

@ -507,8 +507,8 @@ class Package(db.Model):
return self.getSortedDependencies(False) return self.getSortedDependencies(False)
def getSortedSupportedGames(self): def getSortedSupportedGames(self):
supported = self.supported_games.all() supported = self.supported_games.filter_by(supports=True).all()
supported.sort(key=lambda x: -x.game.score) supported.sort(key=lambda x: -(x.game.score + 100000*x.confidence))
return supported return supported
def getAsDictionaryKey(self): def getAsDictionaryKey(self):

@ -20,6 +20,7 @@ from zipfile import ZipFile
from git import GitCommandError from git import GitCommandError
from git_archive_all import GitArchiver from git_archive_all import GitArchiver
from kombu import uuid from kombu import uuid
from sqlalchemy import or_, and_
from app.models import * from app.models import *
from app.tasks import celery, TaskError from app.tasks import celery, TaskError
@ -27,7 +28,7 @@ from app.utils import randomString, post_bot_message, addSystemNotification, add
from app.utils.git import clone_repo, get_latest_tag, get_latest_commit, get_temp_dir from app.utils.git import clone_repo, get_latest_tag, get_latest_commit, get_temp_dir
from .minetestcheck import build_tree, MinetestCheckError, ContentType from .minetestcheck import build_tree, MinetestCheckError, ContentType
from ..logic.LogicError import LogicError from ..logic.LogicError import LogicError
from ..logic.game_support import GameSupportResolver from ..logic.game_support import GameSupportResolver, PackageSet
from ..logic.packages import do_edit_package, ALIASES from ..logic.packages import do_edit_package, ALIASES
from ..utils.image import get_image_size from ..utils.image import get_image_size
@ -73,6 +74,20 @@ def getMeta(urlstr, author):
return result return result
def get_games_from_csv(csv: str) -> List[Package]:
retval = []
supported_games_raw = csv.split(",")
for game_name in supported_games_raw:
game_name = game_name.strip()
if game_name.endswith("_game"):
game_name = game_name[:-5]
games = Package.query.filter(and_(Package.state==PackageState.APPROVED, Package.type==PackageType.GAME,
or_(Package.name==game_name, Package.name==game_name + "_game"))).all()
retval.extend(games)
return retval
def postReleaseCheckUpdate(self, release: PackageRelease, path): def postReleaseCheckUpdate(self, release: PackageRelease, path):
try: try:
tree = build_tree(path, expected_type=ContentType[release.package.type.name], tree = build_tree(path, expected_type=ContentType[release.package.type.name],
@ -118,6 +133,15 @@ def postReleaseCheckUpdate(self, release: PackageRelease, path):
# Update game supports # Update game supports
if package.type == PackageType.MOD: if package.type == PackageType.MOD:
resolver = GameSupportResolver() resolver = GameSupportResolver()
game_is_supported = []
if "supported_games" in tree.meta:
for game in get_games_from_csv(tree.meta["supported_games"]):
game_is_supported.append((game, True))
if "unsupported_games" in tree.meta:
for game in get_games_from_csv(tree.meta["unsupported_games"]):
game_is_supported.append((game, False))
resolver.set_supported(package, game_is_supported, 10)
resolver.update(package) resolver.update(package)
# Update min/max # Update min/max