mirror of
https://github.com/derrod/legendary.git
synced 2024-12-22 17:55:27 +00:00
[core/utils] Implement save game file filters
This commit is contained in:
parent
e88a369feb
commit
2ba036a654
|
@ -339,15 +339,26 @@ class LegendaryCore:
|
||||||
else:
|
else:
|
||||||
return SaveGameStatus.REMOTE_NEWER, (dt_local, dt_remote)
|
return SaveGameStatus.REMOTE_NEWER, (dt_local, dt_remote)
|
||||||
|
|
||||||
def upload_save(self, app_name, save_dir, local_dt: datetime = None):
|
def upload_save(self, app_name, save_dir, local_dt: datetime = None,
|
||||||
|
disable_filtering: bool = False):
|
||||||
game = self.lgd.get_game_meta(app_name)
|
game = self.lgd.get_game_meta(app_name)
|
||||||
save_path = game.metadata['customAttributes'].get('CloudSaveFolder', {}).get('value')
|
custom_attr = game.metadata['customAttributes']
|
||||||
|
save_path = custom_attr.get('CloudSaveFolder', {}).get('value')
|
||||||
|
|
||||||
|
include_f = exclude_f = None
|
||||||
|
if not disable_filtering:
|
||||||
|
# get file inclusion and exclusion filters if they exist
|
||||||
|
if _include := custom_attr.get('CloudIncludeList', {}).get('value', None) is not None:
|
||||||
|
include_f = _include.split(',')
|
||||||
|
if _exclude := custom_attr.get('CloudExcludeList', {}).get('value', None) is not None:
|
||||||
|
exclude_f = _exclude.split(',')
|
||||||
|
|
||||||
if not save_path:
|
if not save_path:
|
||||||
raise ValueError('Game does not support cloud saves')
|
raise ValueError('Game does not support cloud saves')
|
||||||
|
|
||||||
sgh = SaveGameHelper()
|
sgh = SaveGameHelper()
|
||||||
files = sgh.package_savegame(save_dir, app_name, self.egs.user.get('account_id'),
|
files = sgh.package_savegame(save_dir, app_name, self.egs.user.get('account_id'),
|
||||||
save_path, local_dt)
|
save_path, include_f, exclude_f, local_dt)
|
||||||
|
|
||||||
self.log.debug(f'Packed files: {str(files)}, creating cloud files...')
|
self.log.debug(f'Packed files: {str(files)}, creating cloud files...')
|
||||||
resp = self.egs.create_game_cloud_saves(app_name, list(files.keys()))
|
resp = self.egs.create_game_cloud_saves(app_name, list(files.keys()))
|
||||||
|
@ -630,7 +641,6 @@ class LegendaryCore:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_installation_conditions(analysis: AnalysisResult, install: InstalledGame) -> ConditionCheckResult:
|
def check_installation_conditions(analysis: AnalysisResult, install: InstalledGame) -> ConditionCheckResult:
|
||||||
# ToDo add more checks in the future
|
|
||||||
results = ConditionCheckResult(failures=set(), warnings=set())
|
results = ConditionCheckResult(failures=set(), warnings=set())
|
||||||
|
|
||||||
# if on linux, check for eac in the files
|
# if on linux, check for eac in the files
|
||||||
|
|
|
@ -2,6 +2,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from fnmatch import fnmatch
|
||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from tempfile import TemporaryFile
|
from tempfile import TemporaryFile
|
||||||
|
@ -11,6 +12,26 @@ from legendary.models.manifest import \
|
||||||
Manifest, ManifestMeta, CDL, FML, CustomFields, FileManifest, ChunkPart, ChunkInfo
|
Manifest, ManifestMeta, CDL, FML, CustomFields, FileManifest, ChunkPart, ChunkInfo
|
||||||
|
|
||||||
|
|
||||||
|
def _filename_matches(filename, patterns):
|
||||||
|
"""
|
||||||
|
Helper to determine if a filename matches the filter patterns
|
||||||
|
|
||||||
|
:param filename: name of the file
|
||||||
|
:param patterns: list of patterns to match against
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
for pattern in patterns:
|
||||||
|
if pattern.endswith('/'):
|
||||||
|
# pat is a directory, check if path starts with it
|
||||||
|
if filename.startswith(pattern):
|
||||||
|
return True
|
||||||
|
elif fnmatch(filename, pattern):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class SaveGameHelper:
|
class SaveGameHelper:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.files = dict()
|
self.files = dict()
|
||||||
|
@ -32,12 +53,16 @@ class SaveGameHelper:
|
||||||
|
|
||||||
def package_savegame(self, input_folder: str, app_name: str = '',
|
def package_savegame(self, input_folder: str, app_name: str = '',
|
||||||
epic_id: str = '', cloud_folder: str = '',
|
epic_id: str = '', cloud_folder: str = '',
|
||||||
|
include_filter: list = None,
|
||||||
|
exclude_filter: list = None,
|
||||||
manifest_dt: datetime = None):
|
manifest_dt: datetime = None):
|
||||||
"""
|
"""
|
||||||
:param input_folder: Folder to be packaged into chunks/manifest
|
:param input_folder: Folder to be packaged into chunks/manifest
|
||||||
:param app_name: App name for savegame being stored
|
:param app_name: App name for savegame being stored
|
||||||
:param epic_id: Epic account ID
|
:param epic_id: Epic account ID
|
||||||
:param cloud_folder: Folder the savegame resides in (based on game metadata)
|
:param cloud_folder: Folder the savegame resides in (based on game metadata)
|
||||||
|
:param include_filter: list of patterns for files to include (excludes all others)
|
||||||
|
:param exclude_filter: list of patterns for files to exclude (includes all others)
|
||||||
:param manifest_dt: datetime for the manifest name (optional)
|
:param manifest_dt: datetime for the manifest name (optional)
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
@ -57,7 +82,17 @@ class SaveGameHelper:
|
||||||
files = []
|
files = []
|
||||||
for _dir, _, _files in os.walk(input_folder):
|
for _dir, _, _files in os.walk(input_folder):
|
||||||
for _file in _files:
|
for _file in _files:
|
||||||
files.append(os.path.join(_dir, _file))
|
_file_path = os.path.join(_dir, _file)
|
||||||
|
_file_path_rel = os.path.relpath(_file_path, input_folder).replace('\\', '/')
|
||||||
|
|
||||||
|
if include_filter and not _filename_matches(_file_path_rel, include_filter):
|
||||||
|
self.log.debug(f'Excluding "{_file_path_rel}" (does not match include filter)')
|
||||||
|
continue
|
||||||
|
elif exclude_filter and _filename_matches(_file_path_rel, exclude_filter):
|
||||||
|
self.log.debug(f'Excluding "{_file_path_rel}" (does match exclude filter)')
|
||||||
|
continue
|
||||||
|
|
||||||
|
files.append(_file_path)
|
||||||
|
|
||||||
chunk_num = 0
|
chunk_num = 0
|
||||||
cur_chunk = None
|
cur_chunk = None
|
||||||
|
|
Loading…
Reference in a new issue