import 'dart:io'; import 'package:naiyouwl/app/common/LogHelper.dart'; import 'package:path/path.dart' as path; import 'package:process_run/shell_run.dart'; enum OS { windows, linux, macos } enum Architecture { amd64, arm64 } class ClashName { static late final OS os; static late final Architecture architecture; static late final bool isRoot; static void init() { os = determineOS(); architecture = determineArchitecture(); isRoot = determineIsRoot(); } static String get platform { if (Platform.isWindows) return 'windows'; if (Platform.isMacOS) return 'darwin'; if (Platform.isLinux) return 'linux'; return 'unknown'; } static OS determineOS() { if(Platform.isWindows) { return OS.windows; } else if (Platform.isLinux) { return OS.linux; } else if (Platform.isMacOS){ return OS.macos; } else { LogHelper().e('Unsupported OS'); throw Exception('Unsupported OS'); } } static Architecture determineArchitecture() { if (os == OS.windows) { final arch = Platform.environment['PROCESSOR_ARCHITECTURE']; // https://learn.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details if (arch == 'AMD64') { return Architecture.amd64; } else if (arch == 'ARM64') { return Architecture.arm64; } else { LogHelper().e('Unsupported Architecture'); throw Exception('Unsupported Architecture'); } } else { final result = Process.runSync('uname', ['-m']); if (result.exitCode == 0) { final arch = result.stdout.toString().trim(); if (arch == 'x86_64') { return Architecture.amd64; } else if (arch == 'aarch64' || arch == 'arm64') { return Architecture.arm64; } else { LogHelper().e('Unsupported Architecture'); throw Exception('Unsupported Architecture'); } } else { LogHelper().e('Unsupported Architecture'); throw Exception('Unsupported Architecture'); } } } static bool determineIsRoot() { if (os == OS.windows) { final result = Process.runSync('net', ['session']); if (result.exitCode == 0) { return true; } else { return false; } } else { final result = Process.runSync('id', ['-u']); if (result.exitCode == 0) { return result.stdout.toString().trim() == '0'; } else { return false; } } } static String get arch { return architecture.name; //amd64 } static String get ext { if (Platform.isWindows) return '.exe'; return ''; } static String get name { return 'ccore-$platform-$arch$ext'; } } class Paths { static Directory get assets { File mainFile = File(Platform.resolvedExecutable); String assetsPath = '../data/flutter_assets/assets'; if (Platform.isMacOS) assetsPath = '../../Frameworks/App.framework/Resources/flutter_assets/assets'; return Directory(path.normalize(path.join(mainFile.path, assetsPath))); } static Directory get assetsBin { return Directory(path.join(assets.path, 'bin')); } static Directory get assetsDep { return Directory(path.join(assets.path, 'dep')); } static Directory get config { return Directory(path.join(userHomePath, '.config', 'ccore')); } } class Files { static File get assetsClashCore { return File(path.join(Paths.assetsBin.path, ClashName.name)); } static File get assetsClashService { if (Platform.isMacOS){ return File(path.join(Paths.assetsBin.path, 'service-${ClashName.platform}')); } return File(path.join(Paths.assetsBin.path, 'service-${ClashName.platform}-${ClashName.arch}')); } static File get assetsCCore { if (Platform.isMacOS){ return File(path.join(Paths.assetsBin.path, 'core-${ClashName.platform}')); } return File(path.join(Paths.assetsBin.path, 'core-${ClashName.platform}-${ClashName.arch}')); } static File get assetsSysProxyWin { return File(path.join(Paths.assetsBin.path, 'sysproxy64.exe')); } static File get assetsCountryMmdb { return File(path.join(Paths.assetsDep.path, 'Country.mmdb')); } static File get assetsGeosite { return File(path.join(Paths.assetsDep.path, 'geosite.dat')); } static File get assetsGeoIP { return File(path.join(Paths.assetsDep.path, 'geoip.dat')); } static File get assetsWintun { return File(path.join(Paths.assetsDep.path, 'wintun.dll')); } // static File get assetsExample { // return File(path.join(Paths.assetsDep.path, 'example.yaml')); // } static File get configConfig { return File(path.join(Paths.config.path, '.config.json')); } static File get makeProxyConfig { return File(path.join(Paths.config.path, 'proxy.yaml')); } static File get makeInitProxyConfig { return File(path.join(Paths.config.path, 'init_proxy.yaml')); } static File get versionConfig { return File(path.join(Paths.config.path, '.versions.json')); } static File get configCountryMmdb { return File(path.join(Paths.config.path, 'Country.mmdb')); } static File get configGeoIP { return File(path.join(Paths.config.path, 'geoip.dat')); } static File get configGeosite { return File(path.join(Paths.config.path, 'geosite.dat')); } static File get configWintun { return File(path.join(Paths.config.path, 'wintun.dll')); } static File get configExample { return File(path.join(Paths.config.path, 'example.yaml')); } }