diff --git a/assets/bin/silentbatch.exe b/assets/bin/silentbatch.exe new file mode 100644 index 0000000..93428ef Binary files /dev/null and b/assets/bin/silentbatch.exe differ diff --git a/bin/main.dart b/bin/main.dart index 97f8f35..ec7b011 100644 --- a/bin/main.dart +++ b/bin/main.dart @@ -1,4 +1,6 @@ import 'dart:io'; +import 'package:dart_framework/encrypt/encrypt.dart'; +import 'package:dart_framework/platform/process.dart'; import 'package:dart_framework/subtitle/parser_smi.dart'; import 'package:dart_framework/subtitle/parser_srt.dart'; import 'package:path/path.dart' as path; @@ -9,7 +11,19 @@ import 'package:dart_framework/charset.dart'; void main() async { Application(() async { - isolate.test(); + // isolate.test(); + // var md5 = generateMd5('test'); + // print('$md5 / ${md5.length}'); + // var encrypted = encrypt('test', 'this is test'); + // print(encrypted); + + // var raw = decrypt('test', encrypted); + // print(raw); + + var processes = await findProcess('MacOS/MetaSlap '); + for(var process in processes) { + Process.killPid(process.pid); + } }, (error, stack) { print(error); print(stack); diff --git a/lib/encrypt/encrypt.dart b/lib/encrypt/encrypt.dart new file mode 100644 index 0000000..3659fef --- /dev/null +++ b/lib/encrypt/encrypt.dart @@ -0,0 +1,33 @@ +// ignore_for_file: depend_on_referenced_packages + +import 'dart:convert'; +import 'package:encrypt/encrypt.dart'; +import 'package:convert/convert.dart'; +import 'package:crypto/crypto.dart' as crypto; + +//encrypt +String encrypt(String key, String text) { + var md5Key = md5(key); + var key32 = Key.fromUtf8(md5Key); + var iv16 = IV.fromUtf8(md5Key.substring(0, 16)); + final e = Encrypter(AES(key32, mode: AESMode.cbc)); + final encryptedData = e.encrypt(text, iv: iv16); + return encryptedData.base64; +} + +//dycrypt +String decrypt(String key, String text) { + var md5Key = md5(key); + var key32 = Key.fromUtf8(md5Key); + var iv16 = IV.fromUtf8(md5Key.substring(0, 16)); + final e = Encrypter(AES(key32, mode: AESMode.cbc)); + final decryptedData = e.decrypt(Encrypted.fromBase64(text), iv: iv16); + return decryptedData; +} + +String md5(String data) { + var content = Utf8Encoder().convert(data); + var md5 = crypto.md5; + var digest = md5.convert(content); + return hex.encode(digest.bytes); + } \ No newline at end of file diff --git a/lib/log/log_writer_io.dart b/lib/log/log_writer_io.dart index 9bd8e78..faa9ff7 100644 --- a/lib/log/log_writer_io.dart +++ b/lib/log/log_writer_io.dart @@ -35,6 +35,7 @@ class LogWriterIO extends IsolateBase implements LogWriter { void onWrite(Object? message) { // print('write in file: $message'); + if(!_file.existsSync()) _file.createSync(recursive: true); _file.writeAsStringSync(message as String, mode: FileMode.append); } diff --git a/lib/platform/process.dart b/lib/platform/process.dart index 5d7074f..74899fc 100644 --- a/lib/platform/process.dart +++ b/lib/platform/process.dart @@ -1,10 +1,12 @@ +// ignore_for_file: avoid_init_to_null + import 'dart:async'; import 'dart:io'; import 'dart:convert'; import 'dart:math'; -import 'dart:typed_data'; import 'package:dart_framework/charset/euc_kr.dart'; +import 'package:dart_framework/utils/system_util.dart'; class ProcessData { late Process process; @@ -16,6 +18,7 @@ class ProcessData { late StringBuffer stderr; bool _enableStdout; bool _enableStderr; + late Converter, String> _decoder = utf8.decoder; // ignore: no_leading_underscores_for_local_identifiers ProcessData(this._enableStdout, this._enableStderr); @@ -48,17 +51,21 @@ class ProcessData { return list; } + set decoder(Converter, String> value) { + _decoder = value; + } + set processValue(Process value) { process = value; stdout = StringBuffer(); stderr = StringBuffer(); - process.stdout.transform(utf8.decoder).listen((event) { + process.stdout.transform(_decoder).listen((event) { stdout.writeln(event); if (_enableStdout) { print(event); } }); - process.stderr.transform(utf8.decoder).listen((event) { + process.stderr.transform(_decoder).listen((event) { stderr.writeln(event); if (_enableStderr) { print('======================= $event'); @@ -96,6 +103,11 @@ class ProcessData { void dispose() async { deleteFile(); } + + Future waitForExit() async { + await process.exitCode; + return simpleFuture; + } } class ProcessExecutor { @@ -121,10 +133,16 @@ class ProcessExecutor { } static Future start(StringBuffer shell, - {String? workspace, bool? printStdout, bool? printStderr}) async { + {Converter, String>? decoder, + String? workspace, + bool? printStdout, + bool? printStderr}) async { var c = Completer(); try { var processData = ProcessData(printStdout ?? true, printStderr ?? true); + if (decoder != null) { + processData.decoder = decoder; + } if (Platform.isMacOS || Platform.isLinux) { workspace = workspace ?? Directory.systemTemp.path; var file = File('$workspace/$tempFileName'); @@ -136,7 +154,8 @@ class ProcessExecutor { file.createSync(); file.writeAsStringSync(shell.toString()); try { - processData.processValue = await Process.start('zsh', [file.path], + var shellExe = Platform.isMacOS ? 'zsh' : 'bash'; + processData.processValue = await Process.start(shellExe, [file.path], workingDirectory: workspace, runInShell: false); } on Exception catch (e) { print(e); @@ -162,6 +181,7 @@ class ProcessExecutor { print('This platform not support process executor.'); } c.complete(processData); + await processData.waitForExit(); } on Exception catch (e) { print('General Exception in ProcessExecutor.start: $e'); } @@ -171,15 +191,17 @@ class ProcessExecutor { static Future run(StringBuffer shell, {String? workspace, bool printStdout = true}) async { var c = Completer(); + workspace = workspace ?? Directory.systemTemp.path; + var file = File('$workspace/$tempFileName'); + print('---------------------------------------------------'); + print('Shell Path: ${file.path} \nExecute Shell: ${shell.toString()}'); ProcessResult? processResult; if (Platform.isMacOS || Platform.isLinux) { - workspace = workspace ?? Directory.systemTemp.path; - var file = File('$workspace/$tempFileName'); - print('Execute Shell: ${file.path} \n ${shell.toString()}'); file.createSync(); file.writeAsStringSync(shell.toString()); try { - await Process.run('zsh', [file.path], workingDirectory: workspace) + var shellExe = Platform.isMacOS ? 'zsh' : 'bash'; + await Process.run(shellExe, [file.path], workingDirectory: workspace) .then((ProcessResult result) { processResult = result; }); @@ -195,9 +217,6 @@ class ProcessExecutor { } c.complete(processResult); } else if (Platform.isWindows) { - workspace = workspace ?? Directory.systemTemp.path; - var file = File('$workspace/$tempFileName'); - print('Execute Bat: ${file.path} \n ${shell.toString()}'); file.createSync(); file.writeAsStringSync(shell.toString()); await Process.run('cmd', ['/C', file.path], workingDirectory: workspace) @@ -205,13 +224,13 @@ class ProcessExecutor { processResult = result; }); if (printStdout) { - print( - // ignore: prefer_interpolation_to_compose_strings - '[ProcessExecutor] Exit Code: ${processResult!.exitCode}\n' + - '==============================================================\n' + - 'Result: ${eucKr.decode(processResult!.stdout)}\n' + - '==============================================================\n' + - 'Error: ${eucKr.decode(processResult!.stderr)}'); + // print( + // // ignore: prefer_interpolation_to_compose_strings + // '[ProcessExecutor] Exit Code: ${processResult!.exitCode}\n' + + // '==============================================================\n' + + // 'Result: ${eucKr.decode()}\n' + + // '==============================================================\n' + + // 'Error: ${eucKr.decode(processResult!.stderr)}'); } file.deleteSync(); c.complete(processResult); @@ -294,33 +313,87 @@ Future removeTempBat() async { return c.future; } -Future> findNetStat(String searchWord) async { +Future runGetStdout(StringBuffer shell) async { + var c = Completer(); + var shellStr = shell.toString(); + var batch = + File('${Directory.systemTemp.path}/temp_${getRnadomPostfix()}.bat'); + batch.writeAsStringSync(shellStr); + var result = await ProcessExecutor.run(shell); + if (result.exitCode == 0 || result.exitCode == 1) { + c.complete(result.stdout); + return c.future; + } else { + throw Exception(result.stderr); + } +} + +Future findUsePortPid(int port, [bool runSlient = false]) async { await removeTempBat(); - var c = Completer>(); - var shell = StringBuffer('netstat -ano | findstr $searchWord'); - var stdout = await ProcessSilentExecutor.run(shell); - var netList = []; - var returnPattern = RegExp('\n|\r'); - var list = stdout.split(returnPattern); - for (var item in list) { - item = item.replaceAll(returnPattern, ''); - if (item.isNotEmpty) { - var categories = item.split(' '); - if (categories.isNotEmpty) { - netList.add(NetStatData(categories)); + var c = Completer(); + var shell = StringBuffer('netstat -aon | find "$port"'); + var stdout = ""; + try { + stdout = runSlient + ? await ProcessSilentExecutor.runSlientBat(shell) + : await runGetStdout(shell); + } on Exception catch (e) {} + if (stdout == "") { + c.complete(null); + } else { + var netList = []; + var returnPattern = RegExp('\n|\r'); + var list = stdout.split(returnPattern); + for (var item in list) { + item = item.replaceAll(returnPattern, ''); + if (item.isNotEmpty) { + var categories = item.split(' '); + if (categories.isNotEmpty) { + netList.add(NetStatData(categories)); + } } } + NetStatData? data = null; + if (netList.length > 1) { + for (var net in netList) { + if (net!.pid != -1) { + data = net; + break; + } + } + } + c.complete(data); } - c.complete(netList); return c.future; } -Future> findProcess(String searchWord) async { +Future> findProcess(String searchWord, + [bool runSlient = false]) async { await removeTempBat(); var c = Completer>(); - var shell = StringBuffer('tasklist /fo "csv" | findstr $searchWord'); - var stdout = await ProcessSilentExecutor.run(shell); - var pList = parseProcessStd(stdout); + var pList = []; + if(Platform.isWindows) { + var shell = StringBuffer('tasklist /fo "csv" | findstr $searchWord'); + var stdout = runSlient + ? await ProcessSilentExecutor.runSlientBat(shell) + : await runGetStdout(shell); + pList = parseProcessStd(stdout); + } else { + var shell = StringBuffer('ps -A | grep \'$searchWord\' | grep -v grep | awk \'{\$2=\$3=""; print \$0}\''); + var result = await ProcessExecutor.run(shell, printStdout: false); + if(result.exitCode == 0) { + var procList = result.stdout.toString().split('\n'); + for(var proc in procList) { + if(proc.isNotEmpty) { + var info = ProcessInfo(); + var index = proc.indexOf(' '); + info.pid = int.parse(proc.substring(0, index)); + info.name = proc.substring(index).trimLeft(); + pList.add(info); + } + } + } + } c.complete(pList); return c.future; } @@ -334,24 +407,27 @@ List parseProcessStd(String stdout) { if (item.isNotEmpty) { var categories = item.split(','); if (categories.length > 4) { - pList.add(ProcessInfo(categories)); + pList.add(ProcessInfo.category(categories)); } } } return pList; } -Future> findProcessByPid(int pid) async { +Future findProcessByPid(int pid, [bool runSlient = false]) async { // await removeTempBat(); - var c = Completer>(); - var batch = getTempBat(fixedName: pid.toString()); - if (!batch.existsSync()) { - batch.writeAsStringSync( - 'tasklist /fi "pid eq ${pid.toString()}" /nh /fo "csv"'); - } - String stdout = await ProcessSilentExecutor.runBat(batch.path); + var c = Completer(); + var shell = + StringBuffer('tasklist /fi "pid eq ${pid.toString()}" /nh /fo "csv"'); + var stdout = runSlient + ? await ProcessSilentExecutor.runSlientBat(shell) + : await runGetStdout(shell); var pList = parseProcessStd(stdout); - c.complete(pList); + if (pList.isNotEmpty) { + c.complete(pList.first); + } else { + c.complete(null); + } return c.future; } @@ -374,25 +450,28 @@ class ProcessSilentExecutor { } } - static Future run(StringBuffer shell) async { + static Future runSlientBat(StringBuffer shell) async { initialize(); var c = Completer(); - var batch = - File('${Directory.current.path}/silent_bat_${getRnadomPostfix()}.bat'); - batch.writeAsStringSync(shell.toString()); - var result = await runBat(batch.path); + var shellStr = shell.toString(); + print('Execute Shell: $shellStr'); + var batch = File( + '${Directory.systemTemp.path}/silent_bat_${getRnadomPostfix()}.bat'); + batch.writeAsStringSync(shellStr); + var result = await runSlient(batch.path); await batch.delete(); c.complete(result); return c.future; } - static Future runBat(String batchPath) async { + static Future runSlient(String batchPath) async { initialize(); var c = Completer(); var current = Directory.current; String result; var log = File('${current.path}/silent_log_${getRnadomPostfix()}.txt'); - await Process.run('${current.path}/silentbatch.exe', [batchPath, log.path]) + await Process.run( + '${current.path}/assets/bin/silentbatch.exe', [batchPath, log.path]) .then((resultData) { Process.killPid(resultData.pid); // print('"$batchPath" => exitCode: ${resultData.exitCode}'); @@ -415,7 +494,7 @@ String getRnadomPostfix() { File getTempBat({String? fixedName}) { fixedName ??= getRnadomPostfix(); - File batch = File('${Directory.current.path}/temp_bat_$fixedName.bat'); + File batch = File('${Directory.systemTemp.path}/temp_bat_$fixedName.bat'); return batch; } @@ -442,8 +521,8 @@ class ProcessInfoListener { _timer = Timer.periodic(Duration(seconds: _checkInterval), (time) async { var enable = false; if (_process != null) { - var list = await findProcessByPid(_process!.pid); - if (list.isNotEmpty) { + var proc = await findProcessByPid(_process!.pid); + if (proc != null) { print('process live'); enable = true; _isRunning = true; @@ -503,7 +582,8 @@ class ProcessInfo { late int session; late String memory; - ProcessInfo(List categories) { + ProcessInfo(); + ProcessInfo.category(List categories) { var count = 0; var length = categories.length; for (var i = 0; i < length; ++i) { diff --git a/lib/utils/path.dart b/lib/utils/path.dart index 565b9d2..356b87c 100644 --- a/lib/utils/path.dart +++ b/lib/utils/path.dart @@ -45,7 +45,7 @@ class Path { static Future copy(String startPath, String destPath, bool isDir, {required List? ignorePattern, required List? ignoredList, - bool isMove = false}) async { + bool isMove = false, bool isOverwrite = true}) async { var c = Completer(); var result = true; if (ignorePattern != null) { @@ -71,11 +71,11 @@ class Path { for (var file in files) { if (file is File) { await copy(file.path, destDir.path, false, - ignorePattern: ignorePattern, ignoredList: ignoredList); + ignorePattern: ignorePattern, ignoredList: ignoredList, isMove: isMove, isOverwrite: isOverwrite); } if (file is Directory) { await copy(file.path, destDir.path, true, - ignorePattern: ignorePattern, ignoredList: ignoredList); + ignorePattern: ignorePattern, ignoredList: ignoredList, isMove: isMove, isOverwrite: isOverwrite); } } } else { @@ -83,9 +83,14 @@ class Path { if (!destDir.existsSync()) destDir.createSync(recursive: true); print('File copy: $startPath --> $destChildPath'); var file = File(startPath); + var fileDest = File(destChildPath); + if(fileDest.existsSync()) + { + await fileDest.delete(); + } await file.copy(destChildPath); if (isMove) { - file.delete(recursive: true); + await file.delete(recursive: true); } } } on Exception { diff --git a/lib/utils/slack/slack_sender.dart b/lib/utils/slack/slack_sender.dart index e036bd3..28c1e46 100644 --- a/lib/utils/slack/slack_sender.dart +++ b/lib/utils/slack/slack_sender.dart @@ -13,17 +13,13 @@ enum SlackBuildType { android, ios, windows, mac, web } class SlackSender { //Bot TOKEN - String token = "xoxb-291006091297-QT2K1PCpwyX4b5wKk3AQew2G"; + String token; //API - https://api.slack.com/methods/chat.postMessage final urlMessagePost = "https://slack.com/api/chat.postMessage"; //API - https://api.slack.com/methods/files.upload final urlFileUplaod = "https://slack.com/api/files.upload"; - SlackSender(String? token) { - if(token != null) { - this.token = token; - } - } + SlackSender(this.token); String getValidatedUser(String? targetUser) { targetUser ??= "@here"; @@ -31,7 +27,13 @@ class SlackSender { return targetUser; } - Future send(DataSlack message, + Future sendData(DataSlack message, + {Function(String)? completeListener, + Function(Object)? errorListener}) async { + return await send(message.json, completeListener: completeListener, errorListener: errorListener); + } + + Future send(String jsonString, {Function(String)? completeListener, Function(Object)? errorListener}) async { String url = urlMessagePost; @@ -41,9 +43,8 @@ class SlackSender { 'Content-Type': 'application/json', 'Authorization': 'Bearer $token' }; - var body = message.json; - print(body); - var response = await http.post(Uri.parse(url), headers: header, body: message.json); + print(jsonString); + var response = await http.post(Uri.parse(url), headers: header, body: jsonString); print(response.statusCode); @@ -128,7 +129,7 @@ class SlackSender { ]; attachments?.add(attachment); - return await send(message); + return await sendData(message); } String buildTypeToString(SlackBuildType type) { diff --git a/pubspec.yaml b/pubspec.yaml index aaf28bd..f141ee0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,24 +4,25 @@ version: 1.0.0 # repository: https://github.com/my_org/my_repo environment: - sdk: '>=2.18.6 <3.0.0' + sdk: '>=3.2.3 <4.0.0' # Add regular dependencies here. dependencies: path: ^1.8.2 args: ^2.3.2 - json_annotation: ^4.8.0 + json_annotation: ^4.8.1 archive: ^3.3.5 ftpconnect: ^2.0.5 yaml: ^3.1.1 - http: ^0.13.5 + http: ^1.2.1 color: ^3.0.0 protobuf: ^3.1.0 + encrypt: ^5.0.3 # subtitle_wrapper_package: ^2.1.1 # equatable: ^2.0.5 dev_dependencies: - lints: ^2.0.0 + lints: ^3.0.0 test: ^1.21.0 - build_runner: ^2.1.4 - json_serializable: ^6.0.1 + build_runner: ^2.4.8 + json_serializable: ^6.7.1