Refactor mod
This commit is contained in:
		
							
								
								
									
										259
									
								
								lib/mod.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								lib/mod.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,259 @@
 | 
			
		||||
import 'dart:io';
 | 
			
		||||
 | 
			
		||||
import 'package:rimworld_modman/logger.dart';
 | 
			
		||||
import 'package:xml/xml.dart';
 | 
			
		||||
 | 
			
		||||
XmlElement findCaseInsensitive(XmlElement element, String name) {
 | 
			
		||||
  return element.childElements.firstWhere(
 | 
			
		||||
    (e) => e.name.local.toLowerCase() == name,
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XmlElement findCaseInsensitiveDoc(XmlDocument document, String name) {
 | 
			
		||||
  name = name.toLowerCase();
 | 
			
		||||
  return document.childElements.firstWhere(
 | 
			
		||||
    (e) => e.name.local.toLowerCase() == name,
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Mod {
 | 
			
		||||
  final String name; // ModMetaData.name
 | 
			
		||||
  final String id; // ModMetaData.packageId
 | 
			
		||||
  final String path; // figure it out
 | 
			
		||||
  final List<String> versions; // ModMetaData.supportedVersions
 | 
			
		||||
  final String description; // ModMetaData.description
 | 
			
		||||
  final List<String> hardDependencies; // ModMetaData.modDependencies
 | 
			
		||||
  final List<String> loadAfter; // ModMetaData.loadAfter
 | 
			
		||||
  final List<String> loadBefore; // ModMetaData.loadBefore
 | 
			
		||||
  final List<String> incompatabilities; // ModMetaData.incompatibleWith
 | 
			
		||||
  final bool
 | 
			
		||||
  enabled; // ConfigFile.mods.firstWhere((mod) => mod.id == id).enabled
 | 
			
		||||
  final int size; // Count of files in the mod directory
 | 
			
		||||
  final bool isBaseGame; // Is this the base RimWorld game
 | 
			
		||||
  final bool isExpansion; // Is this a RimWorld expansion
 | 
			
		||||
 | 
			
		||||
  Mod({
 | 
			
		||||
    required this.name,
 | 
			
		||||
    required this.id,
 | 
			
		||||
    required this.path,
 | 
			
		||||
    required this.versions,
 | 
			
		||||
    required this.description,
 | 
			
		||||
    required this.hardDependencies,
 | 
			
		||||
    required this.loadAfter,
 | 
			
		||||
    required this.loadBefore,
 | 
			
		||||
    required this.incompatabilities,
 | 
			
		||||
    required this.enabled,
 | 
			
		||||
    required this.size,
 | 
			
		||||
    this.isBaseGame = false,
 | 
			
		||||
    this.isExpansion = false,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  static Mod fromDirectory(String path, {bool skipFileCount = false}) {
 | 
			
		||||
    final logger = Logger.instance;
 | 
			
		||||
    final stopwatch = Stopwatch()..start();
 | 
			
		||||
 | 
			
		||||
    logger.info('Attempting to load mod from directory: $path');
 | 
			
		||||
    final aboutFile = File('$path/About/About.xml');
 | 
			
		||||
    if (!aboutFile.existsSync()) {
 | 
			
		||||
      logger.error('About.xml file does not exist in $aboutFile');
 | 
			
		||||
      throw Exception('About.xml file does not exist in $aboutFile');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    logger.info('Parsing About.xml file...');
 | 
			
		||||
    final aboutXml = XmlDocument.parse(aboutFile.readAsStringSync());
 | 
			
		||||
    final xmlTime = stopwatch.elapsedMilliseconds;
 | 
			
		||||
 | 
			
		||||
    late final XmlElement metadata;
 | 
			
		||||
    try {
 | 
			
		||||
      metadata = findCaseInsensitiveDoc(aboutXml, 'ModMetaData');
 | 
			
		||||
      logger.info('Successfully found ModMetaData in About.xml');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.error(
 | 
			
		||||
        'Error: ModMetaData element is missing in About.xml ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
      throw Exception(
 | 
			
		||||
        'Error: ModMetaData element is missing in About.xml ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    late final String name;
 | 
			
		||||
    try {
 | 
			
		||||
      name = metadata.findElements('name').first.innerText;
 | 
			
		||||
      logger.info('Mod name found: $name');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.error(
 | 
			
		||||
        'Error: name element is missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
      throw Exception(
 | 
			
		||||
        'Error: name element is missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    late final String id;
 | 
			
		||||
    try {
 | 
			
		||||
      id = metadata.findElements('packageId').first.innerText.toLowerCase();
 | 
			
		||||
      logger.info('Mod ID found: $id');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.error(
 | 
			
		||||
        'Error: packageId element is missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
      throw Exception(
 | 
			
		||||
        'Error: packageId element is missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    late final List<String> versions;
 | 
			
		||||
    try {
 | 
			
		||||
      versions =
 | 
			
		||||
          metadata
 | 
			
		||||
              .findElements('supportedVersions')
 | 
			
		||||
              .first
 | 
			
		||||
              .findElements('li')
 | 
			
		||||
              .map((e) => e.innerText)
 | 
			
		||||
              .toList();
 | 
			
		||||
      logger.info('Supported versions found: ${versions.join(", ")}');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.error(
 | 
			
		||||
        'Error: supportedVersions or li elements are missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
      throw Exception(
 | 
			
		||||
        'Error: supportedVersions or li elements are missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    String description = '';
 | 
			
		||||
    try {
 | 
			
		||||
      description = metadata.findElements('description').first.innerText;
 | 
			
		||||
      logger.info('Mod description found: $description');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.warning(
 | 
			
		||||
        'Description element is missing in ModMetaData ($aboutFile).',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    List<String> hardDependencies = [];
 | 
			
		||||
    try {
 | 
			
		||||
      hardDependencies =
 | 
			
		||||
          metadata
 | 
			
		||||
              .findElements('modDependenciesByVersion')
 | 
			
		||||
              .first
 | 
			
		||||
              .children
 | 
			
		||||
              .whereType<XmlElement>()
 | 
			
		||||
              .last
 | 
			
		||||
              .findElements('li')
 | 
			
		||||
              .map(
 | 
			
		||||
                (e) =>
 | 
			
		||||
                    e.findElements("packageId").first.innerText.toLowerCase(),
 | 
			
		||||
              )
 | 
			
		||||
              .toList();
 | 
			
		||||
      logger.info('Hard dependencies found: ${hardDependencies.join(", ")}');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.warning(
 | 
			
		||||
        'Hard dependencies element is missing in ModMetaData ($aboutFile).',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    List<String> loadAfter = [];
 | 
			
		||||
    try {
 | 
			
		||||
      loadAfter =
 | 
			
		||||
          metadata
 | 
			
		||||
              .findElements('loadAfter')
 | 
			
		||||
              .first
 | 
			
		||||
              .findElements('li')
 | 
			
		||||
              .map((e) => e.innerText.toLowerCase())
 | 
			
		||||
              .toList();
 | 
			
		||||
      logger.info('Load after dependencies found: ${loadAfter.join(", ")}');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.warning(
 | 
			
		||||
        'Load after element is missing in ModMetaData ($aboutFile).',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    List<String> loadBefore = [];
 | 
			
		||||
    try {
 | 
			
		||||
      loadBefore =
 | 
			
		||||
          metadata
 | 
			
		||||
              .findElements('loadBefore')
 | 
			
		||||
              .first
 | 
			
		||||
              .findElements('li')
 | 
			
		||||
              .map((e) => e.innerText.toLowerCase())
 | 
			
		||||
              .toList();
 | 
			
		||||
      logger.info('Load before dependencies found: ${loadBefore.join(", ")}');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.warning(
 | 
			
		||||
        'Load before element is missing in ModMetaData ($aboutFile).',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    List<String> incompatabilities = [];
 | 
			
		||||
    try {
 | 
			
		||||
      incompatabilities =
 | 
			
		||||
          metadata
 | 
			
		||||
              .findElements('incompatibleWith')
 | 
			
		||||
              .first
 | 
			
		||||
              .findElements('li')
 | 
			
		||||
              .map((e) => e.innerText.toLowerCase())
 | 
			
		||||
              .toList();
 | 
			
		||||
      logger.info('Incompatibilities found: ${incompatabilities.join(", ")}');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.warning(
 | 
			
		||||
        'Incompatibilities element is missing in ModMetaData ($aboutFile).',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final metadataTime = stopwatch.elapsedMilliseconds - xmlTime;
 | 
			
		||||
 | 
			
		||||
    int size = 0;
 | 
			
		||||
    if (!skipFileCount) {
 | 
			
		||||
      size =
 | 
			
		||||
          Directory(path)
 | 
			
		||||
              .listSync(recursive: true)
 | 
			
		||||
              .where(
 | 
			
		||||
                (entity) =>
 | 
			
		||||
                    !entity.path
 | 
			
		||||
                        .split(Platform.pathSeparator)
 | 
			
		||||
                        .last
 | 
			
		||||
                        .startsWith('.'),
 | 
			
		||||
              )
 | 
			
		||||
              .length;
 | 
			
		||||
      logger.info('File count in mod directory: $size');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Check if this is RimWorld base game or expansion
 | 
			
		||||
    bool isBaseGame = id == 'ludeon.rimworld';
 | 
			
		||||
    bool isExpansion = !isBaseGame && id.startsWith('ludeon.rimworld.');
 | 
			
		||||
 | 
			
		||||
    // If this is an expansion, ensure it depends on the base game
 | 
			
		||||
    if (isExpansion && !loadAfter.contains('ludeon.rimworld')) {
 | 
			
		||||
      loadAfter.add('ludeon.rimworld');
 | 
			
		||||
      logger.info(
 | 
			
		||||
        'Added base game dependency for expansion mod: ludeon.rimworld',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final fileCountTime =
 | 
			
		||||
        stopwatch.elapsedMilliseconds - metadataTime - xmlTime;
 | 
			
		||||
    final totalTime = stopwatch.elapsedMilliseconds;
 | 
			
		||||
 | 
			
		||||
    // Log detailed timing information
 | 
			
		||||
    logger.info(
 | 
			
		||||
      'Mod $name timing: XML=${xmlTime}ms, Metadata=${metadataTime}ms, FileCount=${fileCountTime}ms, Total=${totalTime}ms',
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return Mod(
 | 
			
		||||
      name: name,
 | 
			
		||||
      id: id,
 | 
			
		||||
      path: path,
 | 
			
		||||
      versions: versions,
 | 
			
		||||
      description: description,
 | 
			
		||||
      hardDependencies: hardDependencies,
 | 
			
		||||
      loadAfter: loadAfter,
 | 
			
		||||
      loadBefore: loadBefore,
 | 
			
		||||
      incompatabilities: incompatabilities,
 | 
			
		||||
      enabled: false,
 | 
			
		||||
      size: size,
 | 
			
		||||
      isBaseGame: isBaseGame,
 | 
			
		||||
      isExpansion: isExpansion,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import 'dart:io';
 | 
			
		||||
import 'dart:async';
 | 
			
		||||
import 'package:rimworld_modman/logger.dart';
 | 
			
		||||
import 'package:rimworld_modman/mod.dart';
 | 
			
		||||
import 'package:xml/xml.dart';
 | 
			
		||||
 | 
			
		||||
const root = r'C:/Users/Administrator/Seafile/Games-Rimworld';
 | 
			
		||||
@@ -9,261 +10,6 @@ const configRoot = '$root/AppData/RimWorld by Ludeon Studios/Config';
 | 
			
		||||
const configPath = '$configRoot/ModsConfig.xml';
 | 
			
		||||
const logsPath = '$root/ModManager';
 | 
			
		||||
 | 
			
		||||
XmlElement findCaseInsensitive(XmlElement element, String name) {
 | 
			
		||||
  return element.childElements.firstWhere(
 | 
			
		||||
    (e) => e.name.local.toLowerCase() == name,
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XmlElement findCaseInsensitiveDoc(XmlDocument document, String name) {
 | 
			
		||||
  name = name.toLowerCase();
 | 
			
		||||
  return document.childElements.firstWhere(
 | 
			
		||||
    (e) => e.name.local.toLowerCase() == name,
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Mod {
 | 
			
		||||
  final String name; // ModMetaData.name
 | 
			
		||||
  final String id; // ModMetaData.packageId
 | 
			
		||||
  final String path; // figure it out
 | 
			
		||||
  final List<String> versions; // ModMetaData.supportedVersions
 | 
			
		||||
  final String description; // ModMetaData.description
 | 
			
		||||
  final List<String> hardDependencies; // ModMetaData.modDependencies
 | 
			
		||||
  final List<String> loadAfter; // ModMetaData.loadAfter
 | 
			
		||||
  final List<String> loadBefore; // ModMetaData.loadBefore
 | 
			
		||||
  final List<String> incompatabilities; // ModMetaData.incompatibleWith
 | 
			
		||||
  final bool
 | 
			
		||||
  enabled; // ConfigFile.mods.firstWhere((mod) => mod.id == id).enabled
 | 
			
		||||
  final int size; // Count of files in the mod directory
 | 
			
		||||
  final bool isBaseGame; // Is this the base RimWorld game
 | 
			
		||||
  final bool isExpansion; // Is this a RimWorld expansion
 | 
			
		||||
 | 
			
		||||
  Mod({
 | 
			
		||||
    required this.name,
 | 
			
		||||
    required this.id,
 | 
			
		||||
    required this.path,
 | 
			
		||||
    required this.versions,
 | 
			
		||||
    required this.description,
 | 
			
		||||
    required this.hardDependencies,
 | 
			
		||||
    required this.loadAfter,
 | 
			
		||||
    required this.loadBefore,
 | 
			
		||||
    required this.incompatabilities,
 | 
			
		||||
    required this.enabled,
 | 
			
		||||
    required this.size,
 | 
			
		||||
    this.isBaseGame = false,
 | 
			
		||||
    this.isExpansion = false,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  static Mod fromDirectory(String path, {bool skipFileCount = false}) {
 | 
			
		||||
    final logger = Logger.instance;
 | 
			
		||||
    final stopwatch = Stopwatch()..start();
 | 
			
		||||
 | 
			
		||||
    logger.info('Attempting to load mod from directory: $path');
 | 
			
		||||
    final aboutFile = File('$path/About/About.xml');
 | 
			
		||||
    if (!aboutFile.existsSync()) {
 | 
			
		||||
      logger.error('About.xml file does not exist in $aboutFile');
 | 
			
		||||
      throw Exception('About.xml file does not exist in $aboutFile');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    logger.info('Parsing About.xml file...');
 | 
			
		||||
    final aboutXml = XmlDocument.parse(aboutFile.readAsStringSync());
 | 
			
		||||
    final xmlTime = stopwatch.elapsedMilliseconds;
 | 
			
		||||
 | 
			
		||||
    late final XmlElement metadata;
 | 
			
		||||
    try {
 | 
			
		||||
      metadata = findCaseInsensitiveDoc(aboutXml, 'ModMetaData');
 | 
			
		||||
      logger.info('Successfully found ModMetaData in About.xml');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.error(
 | 
			
		||||
        'Error: ModMetaData element is missing in About.xml ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
      throw Exception(
 | 
			
		||||
        'Error: ModMetaData element is missing in About.xml ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    late final String name;
 | 
			
		||||
    try {
 | 
			
		||||
      name = metadata.findElements('name').first.innerText;
 | 
			
		||||
      logger.info('Mod name found: $name');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.error(
 | 
			
		||||
        'Error: name element is missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
      throw Exception(
 | 
			
		||||
        'Error: name element is missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    late final String id;
 | 
			
		||||
    try {
 | 
			
		||||
      id = metadata.findElements('packageId').first.innerText.toLowerCase();
 | 
			
		||||
      logger.info('Mod ID found: $id');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.error(
 | 
			
		||||
        'Error: packageId element is missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
      throw Exception(
 | 
			
		||||
        'Error: packageId element is missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    late final List<String> versions;
 | 
			
		||||
    try {
 | 
			
		||||
      versions =
 | 
			
		||||
          metadata
 | 
			
		||||
              .findElements('supportedVersions')
 | 
			
		||||
              .first
 | 
			
		||||
              .findElements('li')
 | 
			
		||||
              .map((e) => e.innerText)
 | 
			
		||||
              .toList();
 | 
			
		||||
      logger.info('Supported versions found: ${versions.join(", ")}');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.error(
 | 
			
		||||
        'Error: supportedVersions or li elements are missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
      throw Exception(
 | 
			
		||||
        'Error: supportedVersions or li elements are missing in ModMetaData ($aboutFile). Original error: $e',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    String description = '';
 | 
			
		||||
    try {
 | 
			
		||||
      description = metadata.findElements('description').first.innerText;
 | 
			
		||||
      logger.info('Mod description found: $description');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.warning(
 | 
			
		||||
        'Description element is missing in ModMetaData ($aboutFile).',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    List<String> hardDependencies = [];
 | 
			
		||||
    try {
 | 
			
		||||
      hardDependencies =
 | 
			
		||||
          metadata
 | 
			
		||||
              .findElements('modDependenciesByVersion')
 | 
			
		||||
              .first
 | 
			
		||||
              .children
 | 
			
		||||
              .whereType<XmlElement>()
 | 
			
		||||
              .last
 | 
			
		||||
              .findElements('li')
 | 
			
		||||
              .map(
 | 
			
		||||
                (e) =>
 | 
			
		||||
                    e.findElements("packageId").first.innerText.toLowerCase(),
 | 
			
		||||
              )
 | 
			
		||||
              .toList();
 | 
			
		||||
      logger.info('Hard dependencies found: ${hardDependencies.join(", ")}');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.warning(
 | 
			
		||||
        'Hard dependencies element is missing in ModMetaData ($aboutFile).',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    List<String> loadAfter = [];
 | 
			
		||||
    try {
 | 
			
		||||
      loadAfter =
 | 
			
		||||
          metadata
 | 
			
		||||
              .findElements('loadAfter')
 | 
			
		||||
              .first
 | 
			
		||||
              .findElements('li')
 | 
			
		||||
              .map((e) => e.innerText.toLowerCase())
 | 
			
		||||
              .toList();
 | 
			
		||||
      logger.info('Load after dependencies found: ${loadAfter.join(", ")}');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.warning(
 | 
			
		||||
        'Load after element is missing in ModMetaData ($aboutFile).',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    List<String> loadBefore = [];
 | 
			
		||||
    try {
 | 
			
		||||
      loadBefore =
 | 
			
		||||
          metadata
 | 
			
		||||
              .findElements('loadBefore')
 | 
			
		||||
              .first
 | 
			
		||||
              .findElements('li')
 | 
			
		||||
              .map((e) => e.innerText.toLowerCase())
 | 
			
		||||
              .toList();
 | 
			
		||||
      logger.info('Load before dependencies found: ${loadBefore.join(", ")}');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.warning(
 | 
			
		||||
        'Load before element is missing in ModMetaData ($aboutFile).',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    List<String> incompatabilities = [];
 | 
			
		||||
    try {
 | 
			
		||||
      incompatabilities =
 | 
			
		||||
          metadata
 | 
			
		||||
              .findElements('incompatibleWith')
 | 
			
		||||
              .first
 | 
			
		||||
              .findElements('li')
 | 
			
		||||
              .map((e) => e.innerText.toLowerCase())
 | 
			
		||||
              .toList();
 | 
			
		||||
      logger.info('Incompatibilities found: ${incompatabilities.join(", ")}');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.warning(
 | 
			
		||||
        'Incompatibilities element is missing in ModMetaData ($aboutFile).',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final metadataTime = stopwatch.elapsedMilliseconds - xmlTime;
 | 
			
		||||
 | 
			
		||||
    int size = 0;
 | 
			
		||||
    if (!skipFileCount) {
 | 
			
		||||
      size =
 | 
			
		||||
          Directory(path)
 | 
			
		||||
              .listSync(recursive: true)
 | 
			
		||||
              .where(
 | 
			
		||||
                (entity) =>
 | 
			
		||||
                    !entity.path
 | 
			
		||||
                        .split(Platform.pathSeparator)
 | 
			
		||||
                        .last
 | 
			
		||||
                        .startsWith('.'),
 | 
			
		||||
              )
 | 
			
		||||
              .length;
 | 
			
		||||
      logger.info('File count in mod directory: $size');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Check if this is RimWorld base game or expansion
 | 
			
		||||
    bool isBaseGame = id == 'ludeon.rimworld';
 | 
			
		||||
    bool isExpansion = !isBaseGame && id.startsWith('ludeon.rimworld.');
 | 
			
		||||
 | 
			
		||||
    // If this is an expansion, ensure it depends on the base game
 | 
			
		||||
    if (isExpansion && !loadAfter.contains('ludeon.rimworld')) {
 | 
			
		||||
      loadAfter.add('ludeon.rimworld');
 | 
			
		||||
      logger.info(
 | 
			
		||||
        'Added base game dependency for expansion mod: ludeon.rimworld',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final fileCountTime =
 | 
			
		||||
        stopwatch.elapsedMilliseconds - metadataTime - xmlTime;
 | 
			
		||||
    final totalTime = stopwatch.elapsedMilliseconds;
 | 
			
		||||
 | 
			
		||||
    // Log detailed timing information
 | 
			
		||||
    logger.info(
 | 
			
		||||
      'Mod $name timing: XML=${xmlTime}ms, Metadata=${metadataTime}ms, FileCount=${fileCountTime}ms, Total=${totalTime}ms',
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return Mod(
 | 
			
		||||
      name: name,
 | 
			
		||||
      id: id,
 | 
			
		||||
      path: path,
 | 
			
		||||
      versions: versions,
 | 
			
		||||
      description: description,
 | 
			
		||||
      hardDependencies: hardDependencies,
 | 
			
		||||
      loadAfter: loadAfter,
 | 
			
		||||
      loadBefore: loadBefore,
 | 
			
		||||
      incompatabilities: incompatabilities,
 | 
			
		||||
      enabled: false,
 | 
			
		||||
      size: size,
 | 
			
		||||
      isBaseGame: isBaseGame,
 | 
			
		||||
      isExpansion: isExpansion,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ModList {
 | 
			
		||||
  final String path;
 | 
			
		||||
  Map<String, Mod> mods = {};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user