1
+ import filecmp
1
2
import json
2
3
import re
3
4
import shutil
@@ -266,7 +267,7 @@ class PluginDefaultSettings:
266
267
plugin_name : str
267
268
settings : Mapping [str , mobase .MoVariant ]
268
269
269
- def is_plugin_enabled (self ):
270
+ def is_plugin_enabled (self ) -> bool :
270
271
return self .organizer .isPluginEnabled (self .plugin_name )
271
272
272
273
def apply (self ) -> bool :
@@ -280,7 +281,7 @@ def apply(self) -> bool:
280
281
class Cyberpunk2077Game (BasicGame ):
281
282
Name = "Cyberpunk 2077 Support Plugin"
282
283
Author = "6788, Zash"
283
- Version = "2.2.2 "
284
+ Version = "2.2.3 "
284
285
285
286
GameName = "Cyberpunk 2077"
286
287
GameShortName = "cyberpunk2077"
@@ -389,6 +390,14 @@ def settings(self) -> list[mobase.PluginSetting]:
389
390
"Deploy redmod before game launch if necessary" ,
390
391
True ,
391
392
),
393
+ mobase .PluginSetting (
394
+ "clear_cache_after_game_update" ,
395
+ (
396
+ 'Clears "overwrite/r6/cache/*" if the original game files changed'
397
+ " (after update)"
398
+ ),
399
+ True ,
400
+ ),
392
401
mobase .PluginSetting (
393
402
"configure_RootBuilder" ,
394
403
"Configures RootBuilder for Cyberpunk if installed and enabled" ,
@@ -536,17 +545,52 @@ def _map_cache_files(self):
536
545
overwritten game files.
537
546
"""
538
547
data_path = Path (self .dataDirectory ().absolutePath ())
539
- if unmapped_cache_files := self ._unmapped_cache_files (data_path ):
540
- qInfo ('Copying "r6/cache/*" to overwrite (to catch file overwrites)' )
541
- overwrite_path = Path (self ._organizer .overwritePath ())
542
- for file in unmapped_cache_files :
543
- dst = overwrite_path / file .relative_to (data_path )
544
- dst .parent .mkdir (parents = True , exist_ok = True )
545
- shutil .copy2 (file , dst )
546
-
547
- def _unmapped_cache_files (self , data_path : Path ) -> list [Path ]:
548
- return [
549
- path
550
- for file in self ._organizer .findFiles ("r6/cache" , "*" )
551
- if (path := Path (file ).absolute ()).is_relative_to (data_path )
552
- ]
548
+ overwrite_path = Path (self ._organizer .overwritePath ())
549
+ cache_files = list (data_path .glob ("r6/cache/*" ))
550
+ if self ._get_setting ("clear_cache_after_game_update" ) and any (
551
+ self ._is_cache_file_updated (file .relative_to (data_path ), data_path )
552
+ for file in cache_files
553
+ ):
554
+ qInfo ('Updated game files detected, clearing "overwrite/r6/cache/*"' )
555
+ shutil .rmtree (overwrite_path / "r6/cache" )
556
+ new_cache_files = cache_files
557
+ else :
558
+ new_cache_files = list (self ._unmapped_cache_files (data_path ))
559
+ for file in new_cache_files :
560
+ qInfo (f'Copying "{ file } " to overwrite (to catch file overwrites)' )
561
+ dst = overwrite_path / file
562
+ dst .parent .mkdir (parents = True , exist_ok = True )
563
+ shutil .copy2 (data_path / file , dst )
564
+
565
+ def _is_cache_file_updated (self , file : Path , data_path : Path ) -> bool :
566
+ """Checks if a cache file is updated (in game dir).
567
+
568
+ Args:
569
+ file: Relative to data dir.
570
+ """
571
+ game_file = data_path .absolute () / file
572
+ mapped_files = self ._organizer .findFiles (file .parent , file .name )
573
+ return bool (
574
+ mapped_files
575
+ and (mapped_file := mapped_files [0 ])
576
+ and not (
577
+ game_file .samefile (mapped_file )
578
+ or filecmp .cmp (game_file , mapped_file )
579
+ or ( # different backup file
580
+ (
581
+ backup_files := self ._organizer .findFiles (
582
+ file .parent , f"{ file .name } .bk"
583
+ )
584
+ )
585
+ and filecmp .cmp (game_file , backup_files [0 ])
586
+ )
587
+ )
588
+ )
589
+
590
+ def _unmapped_cache_files (self , data_path : Path ) -> Iterable [Path ]:
591
+ """Yields unmapped cache files relative to `data_path`."""
592
+ for file in self ._organizer .findFiles ("r6/cache" , "*" ):
593
+ try :
594
+ yield Path (file ).absolute ().relative_to (data_path )
595
+ except ValueError :
596
+ continue
0 commit comments