update
This commit is contained in:
parent
2af436382e
commit
65e218ccea
8 changed files with 215 additions and 80 deletions
BIN
assets/bin/silentbatch.exe
Normal file
BIN
assets/bin/silentbatch.exe
Normal file
Binary file not shown.
|
|
@ -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);
|
||||
|
|
|
|||
33
lib/encrypt/encrypt.dart
Normal file
33
lib/encrypt/encrypt.dart
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<List<int>, 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<List<int>, 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<ProcessData> start(StringBuffer shell,
|
||||
{String? workspace, bool? printStdout, bool? printStderr}) async {
|
||||
{Converter<List<int>, String>? decoder,
|
||||
String? workspace,
|
||||
bool? printStdout,
|
||||
bool? printStderr}) async {
|
||||
var c = Completer<ProcessData>();
|
||||
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<ProcessResult> run(StringBuffer shell,
|
||||
{String? workspace, bool printStdout = true}) async {
|
||||
var c = Completer<ProcessResult>();
|
||||
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<List<NetStatData>> findNetStat(String searchWord) async {
|
||||
Future<String> runGetStdout(StringBuffer shell) async {
|
||||
var c = Completer<String>();
|
||||
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<NetStatData?> findUsePortPid(int port, [bool runSlient = false]) async {
|
||||
await removeTempBat();
|
||||
var c = Completer<List<NetStatData>>();
|
||||
var shell = StringBuffer('netstat -ano | findstr $searchWord');
|
||||
var stdout = await ProcessSilentExecutor.run(shell);
|
||||
var netList = <NetStatData>[];
|
||||
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<NetStatData?>();
|
||||
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 = <NetStatData?>[];
|
||||
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<List<ProcessInfo>> findProcess(String searchWord) async {
|
||||
Future<List<ProcessInfo>> findProcess(String searchWord,
|
||||
[bool runSlient = false]) async {
|
||||
await removeTempBat();
|
||||
var c = Completer<List<ProcessInfo>>();
|
||||
var shell = StringBuffer('tasklist /fo "csv" | findstr $searchWord');
|
||||
var stdout = await ProcessSilentExecutor.run(shell);
|
||||
var pList = parseProcessStd(stdout);
|
||||
var pList = <ProcessInfo>[];
|
||||
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<ProcessInfo> 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<List<ProcessInfo>> findProcessByPid(int pid) async {
|
||||
Future<ProcessInfo?> findProcessByPid(int pid, [bool runSlient = false]) async {
|
||||
// await removeTempBat();
|
||||
var c = Completer<List<ProcessInfo>>();
|
||||
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<ProcessInfo?>();
|
||||
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<String> run(StringBuffer shell) async {
|
||||
static Future<String> runSlientBat(StringBuffer shell) async {
|
||||
initialize();
|
||||
var c = Completer<String>();
|
||||
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<String> runBat(String batchPath) async {
|
||||
static Future<String> runSlient(String batchPath) async {
|
||||
initialize();
|
||||
var c = Completer<String>();
|
||||
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<String> categories) {
|
||||
ProcessInfo();
|
||||
ProcessInfo.category(List<String> categories) {
|
||||
var count = 0;
|
||||
var length = categories.length;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class Path {
|
|||
static Future<bool> copy(String startPath, String destPath, bool isDir,
|
||||
{required List<String>? ignorePattern,
|
||||
required List<String>? ignoredList,
|
||||
bool isMove = false}) async {
|
||||
bool isMove = false, bool isOverwrite = true}) async {
|
||||
var c = Completer<bool>();
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
13
pubspec.yaml
13
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue