Browse Source

Merge branch 'dev' of github.com:CympleTech/esse into dev

pull/18/head
Sun 4 years ago
parent
commit
d2bcf6b9d3
  1. 13
      Cargo.toml
  2. 4
      lib/global.dart
  3. 25
      lib/rpc.dart
  4. 3
      lib/security.dart
  5. 2
      macos/Flutter/GeneratedPluginRegistrant.swift
  6. 231
      pubspec.lock
  7. 4
      pubspec.yaml
  8. 70
      src/account.rs
  9. 78
      src/apps.rs
  10. 4
      src/apps/device/mod.rs
  11. 40
      src/apps/device/models.rs
  12. 10
      src/apps/device/rpc.rs
  13. 7
      src/daemon.rs
  14. 92
      src/global.rs
  15. 1630
      src/group.rs
  16. 42
      src/group/running.rs
  17. 742
      src/layer.rs
  18. 7
      src/lib.rs
  19. 2
      src/migrate.rs
  20. 2
      src/migrate/account.rs
  21. 2
      src/migrate/consensus.rs
  22. 3
      src/migrate/session.rs
  23. 785
      src/rpc.rs
  24. 265
      src/server.rs
  25. 37
      src/session.rs
  26. 106
      src/storage.rs
  27. 1
      types/cloud/Cargo.toml
  28. 5
      types/cloud/src/lib.rs
  29. 15
      types/dao/src/lib.rs
  30. 1
      types/domain/Cargo.toml
  31. 13
      types/domain/src/lib.rs
  32. 1
      types/group/Cargo.toml
  33. 5
      types/group/src/lib.rs
  34. 4
      types/primitives/src/lib.rs
  35. 9
      windows/flutter/generated_plugin_registrant.cc
  36. 1
      windows/flutter/generated_plugins.cmake

13
Cargo.toml

@ -34,9 +34,9 @@ panic = 'abort'
anyhow = "1.0" anyhow = "1.0"
log = "0.4" log = "0.4"
rand = "0.8" rand = "0.8"
once_cell = "1.8" once_cell = "1.9"
simplelog = "0.11" simplelog = "0.11"
image = "0.23" image = "0.24"
base64 = "0.13" base64 = "0.13"
hex = "0.4" hex = "0.4"
sha2 = "0.10" sha2 = "0.10"
@ -44,13 +44,14 @@ argon2 = "0.3"
blake3 = "1.3" blake3 = "1.3"
bincode = "1.3" bincode = "1.3"
aes-gcm = "0.9" aes-gcm = "0.9"
sysinfo = "0.21" sysinfo = "0.23"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
web3 = { version = "0.17", default-features = false, features = ["http-tls", "signing"] } web3 = { version = "0.18", default-features = false, features = ["http-tls", "signing"] }
tdn = { version = "0.7", default-features = false, features = ["full"] } tdn = { version = "0.7", default-features = false, features = ["std"] }
tdn_did = { version = "0.7" } tdn_did = { version = "0.7" }
tdn_storage = { git = "https://github.com/cympletech/tdn", branch="main" } tdn_storage = { git = "https://github.com/cympletech/tdn", branch="main" }
esse_primitives = { version = "0.1", path = "./types/primitives" }
chat_types = { version = "0.1", path = "./types/chat" } chat_types = { version = "0.1", path = "./types/chat" }
group_types = { version = "0.1", path = "./types/group" } group_types = { version = "0.1", path = "./types/group" }
cloud_types = { version = "0.1", path = "./types/cloud" } cloud_types = { version = "0.1", path = "./types/cloud" }
@ -66,6 +67,8 @@ jni = { version = "0.19", default-features = false }
# DEBUG patch. # DEBUG patch.
[patch.crates-io] [patch.crates-io]
chamomile = { git = "https://github.com/cympletech/chamomile" }
chamomile_types = { git = "https://github.com/cympletech/chamomile" }
tdn = { git = "https://github.com/cympletech/tdn" } tdn = { git = "https://github.com/cympletech/tdn" }
tdn_types = { git = "https://github.com/cympletech/tdn" } tdn_types = { git = "https://github.com/cympletech/tdn" }
tdn_did = { git = "https://github.com/cympletech/tdn" } tdn_did = { git = "https://github.com/cympletech/tdn" }

4
lib/global.dart

@ -1,8 +1,8 @@
class Global { class Global {
static String version = 'v0.5.0'; static String version = 'v0.5.0';
static String gid = '0000000000000000000000000000000000000000000000000000000000000000'; static String gid = '0000000000000000000000000000000000000000000000000000000000000000';
static String httpRpc = '127.0.0.1:8000'; static String httpRpc = '127.0.0.1:7365';
static String wsRpc = '127.0.0.1:8080'; static String wsRpc = '127.0.0.1:7366';
//static String httpRpc = '192.168.2.148:8001'; // test code //static String httpRpc = '192.168.2.148:8001'; // test code
//static String wsRpc = '192.168.2.148:8081'; // test code //static String wsRpc = '192.168.2.148:8081'; // test code
//static String httpRpc = '192.168.50.250:8001'; // test code //static String httpRpc = '192.168.50.250:8001'; // test code

25
lib/rpc.dart

@ -10,7 +10,6 @@ import 'package:esse/global.dart';
Map jsonrpc = { Map jsonrpc = {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": 1, "id": 1,
"gid": Global.gid,
"method": "", "method": "",
"params": [], "params": [],
}; };
@ -111,7 +110,6 @@ class WebSocketsNotifications {
send(String method, List params) { send(String method, List params) {
jsonrpc["method"] = method; jsonrpc["method"] = method;
jsonrpc["params"] = params; jsonrpc["params"] = params;
jsonrpc["gid"] = Global.gid;
if (_channel != null) { if (_channel != null) {
_channel!.sink.add(json.encode(jsonrpc)); _channel!.sink.add(json.encode(jsonrpc));
@ -134,23 +132,16 @@ class WebSocketsNotifications {
Map response = json.decode(message); Map response = json.decode(message);
print(response); print(response);
if (response["result"] != null && if (response["result"] != null && response["method"] != null) {
response["method"] != null && String method = response["method"];
response["gid"] != null List params = response["result"];
) {
String method = response["method"];
List params = response["result"];
String gid = response["gid"];
if (_listeners[method] != null) { if (_listeners[method] != null) {
final callbacks = _listeners[method]!; final callbacks = _listeners[method]!;
if (gid == Global.gid || method.startsWith('account')) { try {
try { callbacks[0](params);
callbacks[0](params); } catch (e) {
} catch (e) { print('function is unvalid');
print('function is unvalid');
}
} else if (callbacks[1] != null && callbacks[1]) {
_notice!(gid);
} }
} else { } else {
print("has no this " + method); print("has no this " + method);

3
lib/security.dart

@ -175,9 +175,6 @@ class _SecurityPageState extends State<SecurityPage> {
await rpc.init(Global.wsRpc); await rpc.init(Global.wsRpc);
} }
// init system info.
rpc.send('account-system-info', []);
// check if has logined. // check if has logined.
final loginedAccounts = await getLogined(); final loginedAccounts = await getLogined();
if (loginedAccounts.length != 0) { if (loginedAccounts.length != 0) {

2
macos/Flutter/GeneratedPluginRegistrant.swift

@ -6,6 +6,7 @@ import FlutterMacOS
import Foundation import Foundation
import audio_session import audio_session
import device_info_plus_macos
import esse_core import esse_core
import file_selector_macos import file_selector_macos
import just_audio import just_audio
@ -15,6 +16,7 @@ import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
EsseCorePlugin.register(with: registry.registrar(forPlugin: "EsseCorePlugin")) EsseCorePlugin.register(with: registry.registrar(forPlugin: "EsseCorePlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))

231
pubspec.lock

@ -15,13 +15,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.0" version: "2.8.0"
ansicolor:
dependency: transitive
description:
name: ansicolor
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
archive: archive:
dependency: transitive dependency: transitive
description: description:
@ -78,6 +71,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1"
cli_dialog:
dependency: transitive
description:
name: cli_dialog
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.0"
cli_util: cli_util:
dependency: transitive dependency: transitive
description: description:
@ -141,6 +141,55 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.17.1" version: "0.17.1"
dart_console:
dependency: transitive
description:
name: dart_console
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
device_info_plus:
dependency: transitive
description:
name: device_info_plus
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.2"
device_info_plus_linux:
dependency: transitive
description:
name: device_info_plus_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
device_info_plus_macos:
dependency: transitive
description:
name: device_info_plus_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.2"
device_info_plus_platform_interface:
dependency: transitive
description:
name: device_info_plus_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0+1"
device_info_plus_web:
dependency: transitive
description:
name: device_info_plus_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
device_info_plus_windows:
dependency: transitive
description:
name: device_info_plus_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
diff_match_patch: diff_match_patch:
dependency: transitive dependency: transitive
description: description:
@ -189,20 +238,20 @@ packages:
name: file_picker name: file_picker
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.3.0" version: "4.4.0"
file_selector: file_selector:
dependency: "direct main" dependency: "direct main"
description: description:
name: file_selector name: file_selector
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.8.2+1" version: "0.8.3"
file_selector_linux: file_selector_linux:
dependency: "direct main" dependency: "direct main"
description: description:
path: "plugins/file_selector/file_selector_linux" path: "plugins/file_selector/file_selector_linux"
ref: HEAD ref: HEAD
resolved-ref: c339fe7dd2e17a80f7bb839bfad89d21a6e084ba resolved-ref: "89c350f787e1d7bff12b3517e5671146211ee70e"
url: "git://github.com/google/flutter-desktop-embedding.git" url: "git://github.com/google/flutter-desktop-embedding.git"
source: git source: git
version: "0.0.2+1" version: "0.0.2+1"
@ -211,7 +260,7 @@ packages:
description: description:
path: "plugins/file_selector/file_selector_macos" path: "plugins/file_selector/file_selector_macos"
ref: HEAD ref: HEAD
resolved-ref: c339fe7dd2e17a80f7bb839bfad89d21a6e084ba resolved-ref: "89c350f787e1d7bff12b3517e5671146211ee70e"
url: "git://github.com/google/flutter-desktop-embedding.git" url: "git://github.com/google/flutter-desktop-embedding.git"
source: git source: git
version: "0.0.4+1" version: "0.0.4+1"
@ -221,23 +270,21 @@ packages:
name: file_selector_platform_interface name: file_selector_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.3" version: "2.0.4"
file_selector_web: file_selector_web:
dependency: transitive dependency: transitive
description: description:
name: file_selector_web name: file_selector_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.8.1+2" version: "0.8.1+3"
file_selector_windows: file_selector_windows:
dependency: "direct main" dependency: transitive
description: description:
path: "plugins/file_selector/file_selector_windows" name: file_selector_windows
ref: HEAD url: "https://pub.dartlang.org"
resolved-ref: c339fe7dd2e17a80f7bb839bfad89d21a6e084ba source: hosted
url: "git://github.com/google/flutter-desktop-embedding.git" version: "0.8.2"
source: git
version: "0.0.2+1"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -268,7 +315,7 @@ packages:
name: flutter_keyboard_visibility name: flutter_keyboard_visibility
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.1.0" version: "5.2.0"
flutter_keyboard_visibility_platform_interface: flutter_keyboard_visibility_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -315,7 +362,7 @@ packages:
name: flutter_native_splash name: flutter_native_splash
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.3" version: "2.0.5"
flutter_plugin_android_lifecycle: flutter_plugin_android_lifecycle:
dependency: transitive dependency: transitive
description: description:
@ -329,7 +376,7 @@ packages:
name: flutter_quill name: flutter_quill
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.2.0" version: "4.0.5"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -352,6 +399,13 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
gallery_saver:
dependency: transitive
description:
name: gallery_saver
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.2"
gettext_parser: gettext_parser:
dependency: transitive dependency: transitive
description: description:
@ -400,28 +454,28 @@ packages:
name: image name: image
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.1.0" version: "3.1.3"
image_picker: image_picker:
dependency: "direct main" dependency: "direct main"
description: description:
name: image_picker name: image_picker
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.8.4+4" version: "0.8.4+9"
image_picker_for_web: image_picker_for_web:
dependency: transitive dependency: transitive
description: description:
name: image_picker_for_web name: image_picker_for_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.4" version: "2.1.6"
image_picker_platform_interface: image_picker_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: image_picker_platform_interface name: image_picker_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.4.2" version: "2.4.4"
image_save: image_save:
dependency: "direct main" dependency: "direct main"
description: description:
@ -429,13 +483,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.0.0" version: "5.0.0"
injector:
dependency: transitive
description:
name: injector
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
integration_test: integration_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -461,21 +508,21 @@ packages:
name: just_audio name: just_audio
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.18" version: "0.9.20"
just_audio_platform_interface: just_audio_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: just_audio_platform_interface name: just_audio_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.0.0" version: "4.1.0"
just_audio_web: just_audio_web:
dependency: transitive dependency: transitive
description: description:
name: just_audio_web name: just_audio_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.2" version: "0.4.4"
lints: lints:
dependency: transitive dependency: transitive
description: description:
@ -490,6 +537,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.11" version: "0.12.11"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
meta: meta:
dependency: transitive dependency: transitive
description: description:
@ -503,7 +557,7 @@ packages:
name: msix name: msix
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.0" version: "3.2.0"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@ -538,7 +592,7 @@ packages:
name: path_provider name: path_provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.8" version: "2.0.9"
path_provider_android: path_provider_android:
dependency: transitive dependency: transitive
description: description:
@ -559,28 +613,28 @@ packages:
name: path_provider_linux name: path_provider_linux
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.4" version: "2.1.5"
path_provider_macos: path_provider_macos:
dependency: transitive dependency: transitive
description: description:
name: path_provider_macos name: path_provider_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.4" version: "2.0.5"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: path_provider_platform_interface name: path_provider_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.2" version: "2.0.3"
path_provider_windows: path_provider_windows:
dependency: transitive dependency: transitive
description: description:
name: path_provider_windows name: path_provider_windows
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.4" version: "2.0.5"
pedantic: pedantic:
dependency: transitive dependency: transitive
description: description:
@ -594,14 +648,28 @@ packages:
name: percent_indicator name: percent_indicator
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.4.0" version: "4.0.0"
permission_handler: permission_handler:
dependency: "direct main" dependency: "direct main"
description: description:
name: permission_handler name: permission_handler
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "8.3.0" version: "9.2.0"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
url: "https://pub.dartlang.org"
source: hosted
version: "9.0.2"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
url: "https://pub.dartlang.org"
source: hosted
version: "9.0.2"
permission_handler_platform_interface: permission_handler_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -609,6 +677,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.7.0" version: "3.7.0"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0"
petitparser: petitparser:
dependency: transitive dependency: transitive
description: description:
@ -629,14 +704,14 @@ packages:
name: platform name: platform
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.2" version: "3.1.0"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: plugin_platform_interface name: plugin_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.2"
process: process:
dependency: transitive dependency: transitive
description: description:
@ -671,7 +746,7 @@ packages:
name: qr_code_scanner name: qr_code_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.1" version: "0.7.0"
qr_flutter: qr_flutter:
dependency: "direct main" dependency: "direct main"
description: description:
@ -720,35 +795,35 @@ packages:
name: shared_preferences name: shared_preferences
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.11" version: "2.0.13"
shared_preferences_android: shared_preferences_android:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_android name: shared_preferences_android
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.9" version: "2.0.11"
shared_preferences_ios: shared_preferences_ios:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_ios name: shared_preferences_ios
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.8" version: "2.1.0"
shared_preferences_linux: shared_preferences_linux:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_linux name: shared_preferences_linux
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.3" version: "2.1.0"
shared_preferences_macos: shared_preferences_macos:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_macos name: shared_preferences_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.2" version: "2.0.3"
shared_preferences_platform_interface: shared_preferences_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -762,14 +837,14 @@ packages:
name: shared_preferences_web name: shared_preferences_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.2" version: "2.0.3"
shared_preferences_windows: shared_preferences_windows:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_windows name: shared_preferences_windows
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.3" version: "2.1.0"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -837,7 +912,7 @@ packages:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.3" version: "0.4.8"
tuple: tuple:
dependency: transitive dependency: transitive
description: description:
@ -872,35 +947,35 @@ packages:
name: url_launcher name: url_launcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.0.17" version: "6.0.20"
url_launcher_android: url_launcher_android:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_android name: url_launcher_android
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.0.13" version: "6.0.15"
url_launcher_ios: url_launcher_ios:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_ios name: url_launcher_ios
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.0.13" version: "6.0.15"
url_launcher_linux: url_launcher_linux:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_linux name: url_launcher_linux
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.2" version: "3.0.0"
url_launcher_macos: url_launcher_macos:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_macos name: url_launcher_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.2" version: "3.0.0"
url_launcher_platform_interface: url_launcher_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -914,21 +989,21 @@ packages:
name: url_launcher_web name: url_launcher_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.5" version: "2.0.8"
url_launcher_windows: url_launcher_windows:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_windows name: url_launcher_windows
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.2" version: "3.0.0"
uuid: uuid:
dependency: transitive dependency: transitive
description: description:
name: uuid name: uuid
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.5" version: "3.0.6"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@ -942,28 +1017,42 @@ packages:
name: video_player name: video_player
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.10" version: "2.2.18"
video_player_android:
dependency: transitive
description:
name: video_player_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
video_player_avfoundation:
dependency: transitive
description:
name: video_player_avfoundation
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
video_player_platform_interface: video_player_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: video_player_platform_interface name: video_player_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.0.1" version: "5.1.0"
video_player_web: video_player_web:
dependency: transitive dependency: transitive
description: description:
name: video_player_web name: video_player_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.5" version: "2.0.7"
vm_service: vm_service:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "7.3.0" version: "7.5.0"
watcher: watcher:
dependency: transitive dependency: transitive
description: description:
@ -991,14 +1080,14 @@ packages:
name: win32 name: win32
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.3.3" version: "2.4.1"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
name: xdg_directories name: xdg_directories
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.0" version: "0.2.0+1"
xml: xml:
dependency: transitive dependency: transitive
description: description:
@ -1022,4 +1111,4 @@ packages:
version: "8.0.0" version: "8.0.0"
sdks: sdks:
dart: ">=2.15.1 <3.0.0" dart: ">=2.15.1 <3.0.0"
flutter: ">=2.5.3" flutter: ">=2.10.0"

4
pubspec.yaml

@ -35,10 +35,6 @@ dependencies:
git: git:
url: git://github.com/google/flutter-desktop-embedding.git url: git://github.com/google/flutter-desktop-embedding.git
path: plugins/file_selector/file_selector_macos path: plugins/file_selector/file_selector_macos
file_selector_windows:
git:
url: git://github.com/google/flutter-desktop-embedding.git
path: plugins/file_selector/file_selector_windows
open_file: any # open file in mobile. open_file: any # open file in mobile.
crop: any crop: any
unorm_dart: any unorm_dart: any

70
src/account.rs

@ -2,12 +2,14 @@ use rand::Rng;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use tdn::types::{ use tdn::types::{
group::{EventId, GroupId}, group::EventId,
primitive::{PeerId, Result}, primitives::{PeerId, PeerKey, Result},
}; };
use tdn_did::{generate_id, Keypair, Language}; use tdn_did::{generate_peer, Language};
use tdn_storage::local::{DStorage, DsValue}; use tdn_storage::local::{DStorage, DsValue};
use esse_primitives::{id_from_str, id_to_str};
use crate::utils::crypto::{ use crate::utils::crypto::{
check_pin, decrypt, decrypt_key, encrypt_key, encrypt_multiple, hash_pin, check_pin, decrypt, decrypt_key, encrypt_key, encrypt_multiple, hash_pin,
}; };
@ -45,7 +47,7 @@ pub fn lang_from_i64(u: i64) -> Language {
pub(crate) struct Account { pub(crate) struct Account {
pub id: i64, pub id: i64,
pub gid: GroupId, pub pid: PeerId,
pub index: i64, pub index: i64,
pub lang: i64, pub lang: i64,
pub mnemonic: Vec<u8>, // encrypted value. pub mnemonic: Vec<u8>, // encrypted value.
@ -56,7 +58,7 @@ pub(crate) struct Account {
pub secret: Vec<u8>, // encrypted value. pub secret: Vec<u8>, // encrypted value.
pub encrypt: Vec<u8>, // encrypted encrypt key. pub encrypt: Vec<u8>, // encrypted encrypt key.
pub wallet: String, // main wallet info. pub wallet: String, // main wallet info.
pub pub_height: i64, // public information height. pub pub_height: u64, // public information height.
pub own_height: u64, // own data consensus height. pub own_height: u64, // own data consensus height.
pub event: EventId, pub event: EventId,
pub datetime: i64, pub datetime: i64,
@ -65,7 +67,7 @@ pub(crate) struct Account {
impl Account { impl Account {
pub fn new( pub fn new(
gid: GroupId, pid: PeerId,
index: i64, index: i64,
lang: i64, lang: i64,
pass: String, pass: String,
@ -89,7 +91,7 @@ impl Account {
own_height: 0, own_height: 0,
wallet: String::new(), wallet: String::new(),
event: EventId::default(), event: EventId::default(),
gid, pid,
index, index,
lang, lang,
pass, pass,
@ -117,8 +119,8 @@ impl Account {
name: &str, name: &str,
lock: &str, lock: &str,
avatar: Vec<u8>, avatar: Vec<u8>,
) -> Result<(Account, Keypair)> { ) -> Result<(Account, PeerKey)> {
let (gid, sk) = generate_id( let sk = generate_peer(
lang_from_i64(lang), lang_from_i64(lang),
mnemonic, mnemonic,
index, index,
@ -128,15 +130,19 @@ impl Account {
let key = rand::thread_rng().gen::<[u8; 32]>(); let key = rand::thread_rng().gen::<[u8; 32]>();
let ckey = encrypt_key(salt, lock, &key)?; let ckey = encrypt_key(salt, lock, &key)?;
let mut ebytes = let mut ebytes = encrypt_multiple(
encrypt_multiple(salt, lock, &ckey, vec![&sk.to_bytes(), mnemonic.as_bytes()])?; salt,
lock,
&ckey,
vec![&sk.to_db_bytes(), mnemonic.as_bytes()],
)?;
let mnemonic = ebytes.pop().unwrap_or(vec![]); let mnemonic = ebytes.pop().unwrap_or(vec![]);
let secret = ebytes.pop().unwrap_or(vec![]); let secret = ebytes.pop().unwrap_or(vec![]);
let index = index as i64; let index = index as i64;
Ok(( Ok((
Account::new( Account::new(
gid, sk.peer_id(),
index, index,
lang, lang,
pass.to_string(), pass.to_string(),
@ -186,10 +192,10 @@ impl Account {
String::from_utf8(pbytes).or(Err(anyhow!("mnemonic unlock invalid."))) String::from_utf8(pbytes).or(Err(anyhow!("mnemonic unlock invalid.")))
} }
pub fn secret(&self, salt: &[u8], lock: &str) -> Result<Keypair> { pub fn secret(&self, salt: &[u8], lock: &str) -> Result<PeerKey> {
self.check_lock(lock)?; self.check_lock(lock)?;
let pbytes = decrypt(salt, lock, &self.encrypt, &self.secret)?; let pbytes = decrypt(salt, lock, &self.encrypt, &self.secret)?;
Keypair::from_bytes(&pbytes).or(Err(anyhow!("secret unlock invalid."))) PeerKey::from_db_bytes(&pbytes).or(Err(anyhow!("secret unlock invalid.")))
} }
/// here is zero-copy and unwrap is safe. checked. /// here is zero-copy and unwrap is safe. checked.
@ -198,7 +204,7 @@ impl Account {
datetime: v.pop().unwrap().as_i64(), datetime: v.pop().unwrap().as_i64(),
event: EventId::from_hex(v.pop().unwrap().as_str()).unwrap_or(EventId::default()), event: EventId::from_hex(v.pop().unwrap().as_str()).unwrap_or(EventId::default()),
own_height: v.pop().unwrap().as_i64() as u64, own_height: v.pop().unwrap().as_i64() as u64,
pub_height: v.pop().unwrap().as_i64(), pub_height: v.pop().unwrap().as_i64() as u64,
wallet: v.pop().unwrap().as_string(), wallet: v.pop().unwrap().as_string(),
avatar: base64::decode(v.pop().unwrap().as_str()).unwrap_or(vec![]), avatar: base64::decode(v.pop().unwrap().as_str()).unwrap_or(vec![]),
encrypt: base64::decode(v.pop().unwrap().as_str()).unwrap_or(vec![]), encrypt: base64::decode(v.pop().unwrap().as_str()).unwrap_or(vec![]),
@ -209,16 +215,16 @@ impl Account {
pass: v.pop().unwrap().as_string(), pass: v.pop().unwrap().as_string(),
lang: v.pop().unwrap().as_i64(), lang: v.pop().unwrap().as_i64(),
index: v.pop().unwrap().as_i64(), index: v.pop().unwrap().as_i64(),
gid: GroupId::from_hex(v.pop().unwrap().as_str()).unwrap_or(GroupId::default()), pid: id_from_str(v.pop().unwrap().as_str()).unwrap_or(PeerId::default()),
id: v.pop().unwrap().as_i64(), id: v.pop().unwrap().as_i64(),
plainkey: vec![], plainkey: vec![],
} }
} }
pub fn get(db: &DStorage, gid: &GroupId) -> Result<Account> { pub fn get(db: &DStorage, pid: &PeerId) -> Result<Account> {
let sql = format!( let sql = format!(
"SELECT id, gid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime FROM accounts WHERE gid = '{}'", "SELECT id, pid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime FROM accounts WHERE pid = '{}'",
gid.to_hex() id_to_str(pid)
); );
let mut matrix = db.query(&sql)?; let mut matrix = db.query(&sql)?;
if matrix.len() > 0 { if matrix.len() > 0 {
@ -231,7 +237,7 @@ impl Account {
pub fn all(db: &DStorage) -> Result<Vec<Account>> { pub fn all(db: &DStorage) -> Result<Vec<Account>> {
let matrix = db.query( let matrix = db.query(
"SELECT id, gid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime FROM accounts ORDER BY datetime DESC", "SELECT id, pid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime FROM accounts ORDER BY datetime DESC",
)?; )?;
let mut accounts = vec![]; let mut accounts = vec![];
for values in matrix { for values in matrix {
@ -242,16 +248,16 @@ impl Account {
pub fn insert(&mut self, db: &DStorage) -> Result<()> { pub fn insert(&mut self, db: &DStorage) -> Result<()> {
let mut unique_check = db.query(&format!( let mut unique_check = db.query(&format!(
"SELECT id from accounts WHERE gid = '{}'", "SELECT id from accounts WHERE pid = '{}'",
self.gid.to_hex() id_to_str(&self.pid)
))?; ))?;
if unique_check.len() > 0 { if unique_check.len() > 0 {
let id = unique_check.pop().unwrap().pop().unwrap().as_i64(); let id = unique_check.pop().unwrap().pop().unwrap().as_i64();
self.id = id; self.id = id;
self.update(db)?; self.update(db)?;
} else { } else {
let sql = format!("INSERT INTO accounts (gid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime) VALUES ('{}', {}, {}, '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', {}, {}, '{}', {})", let sql = format!("INSERT INTO accounts (pid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime) VALUES ('{}', {}, {}, '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', {}, {}, '{}', {})",
self.gid.to_hex(), id_to_str(&self.pid),
self.index, self.index,
self.lang, self.lang,
self.pass, self.pass,
@ -321,8 +327,7 @@ impl Account {
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub(crate) struct User { pub(crate) struct User {
pub id: GroupId, pub id: PeerId,
pub addr: PeerId,
pub name: String, pub name: String,
pub wallet: String, pub wallet: String,
pub height: i64, pub height: i64,
@ -330,17 +335,9 @@ pub(crate) struct User {
} }
impl User { impl User {
pub fn new( pub fn new(id: PeerId, name: String, avatar: Vec<u8>, wallet: String, height: i64) -> Self {
id: GroupId,
addr: PeerId,
name: String,
avatar: Vec<u8>,
wallet: String,
height: i64,
) -> Self {
Self { Self {
id, id,
addr,
name, name,
avatar, avatar,
wallet, wallet,
@ -350,8 +347,7 @@ impl User {
pub fn info(name: String, wallet: String, height: i64, avatar: Vec<u8>) -> Self { pub fn info(name: String, wallet: String, height: i64, avatar: Vec<u8>) -> Self {
Self { Self {
id: GroupId::default(), id: PeerId::default(),
addr: PeerId::default(),
name, name,
wallet, wallet,
height, height,

78
src/apps.rs

@ -2,56 +2,56 @@ use std::sync::Arc;
use tdn::types::{ use tdn::types::{
group::GroupId, group::GroupId,
message::RecvType, message::RecvType,
primitive::{HandleResult, Result}, primitives::{HandleResult, Result},
rpc::RpcHandler, rpc::RpcHandler,
}; };
use tokio::sync::RwLock; use tokio::sync::RwLock;
use crate::global::Global;
use crate::layer::Layer; use crate::layer::Layer;
use crate::rpc::RpcState;
pub(crate) mod chat; //pub(crate) mod chat;
pub(crate) mod cloud; //pub(crate) mod cloud;
pub(crate) mod device; pub(crate) mod device;
pub(crate) mod domain; //pub(crate) mod domain;
pub(crate) mod file; //pub(crate) mod file;
pub(crate) mod group; //pub(crate) mod group;
pub(crate) mod jarvis; //pub(crate) mod jarvis;
//pub(crate) mod dao; //pub(crate) mod dao;
pub(crate) mod wallet; //pub(crate) mod wallet;
pub(crate) fn app_rpc_inject(handler: &mut RpcHandler<RpcState>) { pub(crate) fn app_rpc_inject(handler: &mut RpcHandler<Global>) {
device::new_rpc_handler(handler); //device::new_rpc_handler(handler);
chat::new_rpc_handler(handler); //chat::new_rpc_handler(handler);
jarvis::new_rpc_handler(handler); //jarvis::new_rpc_handler(handler);
domain::new_rpc_handler(handler); //domain::new_rpc_handler(handler);
file::new_rpc_handler(handler); //file::new_rpc_handler(handler);
group::new_rpc_handler(handler); //group::new_rpc_handler(handler);
wallet::new_rpc_handler(handler); //wallet::new_rpc_handler(handler);
//dao::new_rpc_handler(handler); //dao::new_rpc_handler(handler);
cloud::new_rpc_handler(handler); //cloud::new_rpc_handler(handler);
} }
pub(crate) async fn app_layer_handle( // pub(crate) async fn app_layer_handle(
layer: &Arc<RwLock<Layer>>, // layer: &Arc<RwLock<Layer>>,
fgid: GroupId, // fgid: GroupId,
mgid: GroupId, // mgid: GroupId,
msg: RecvType, // msg: RecvType,
) -> Result<HandleResult> { // ) -> Result<HandleResult> {
match (fgid, mgid) { // match (fgid, mgid) {
(group::GROUP_ID, _) => group::handle_peer(layer, mgid, msg).await, // (group::GROUP_ID, _) => group::handle_peer(layer, mgid, msg).await,
(_, group::GROUP_ID) => group::handle_server(layer, fgid, msg).await, // (_, group::GROUP_ID) => group::handle_server(layer, fgid, msg).await,
//(dao::GROUP_ID, _) => dao::handle(layer, fgid, mgid, false, msg).await, // (dao::GROUP_ID, _) => dao::handle(layer, fgid, mgid, false, msg).await,
(domain::GROUP_ID, _) => domain::handle(layer, mgid, msg).await, // (domain::GROUP_ID, _) => domain::handle(layer, mgid, msg).await,
(cloud::GROUP_ID, _) => cloud::handle(layer, mgid, msg).await, // (cloud::GROUP_ID, _) => cloud::handle(layer, mgid, msg).await,
_ => chat::handle(layer, fgid, mgid, msg).await, // _ => chat::handle(layer, fgid, mgid, msg).await,
} // }
} // }
pub(crate) fn _app_group_handle() -> Result<HandleResult> { // pub(crate) fn _app_group_handle() -> Result<HandleResult> {
todo!() // todo!()
} // }
pub(crate) fn _app_migrate() -> Result<()> { // pub(crate) fn _app_migrate() -> Result<()> {
todo!() // todo!()
} // }

4
src/apps/device/mod.rs

@ -1,5 +1,5 @@
mod models; mod models;
pub(crate) mod rpc; //pub(crate) mod rpc;
pub(crate) use models::Device; pub(crate) use models::Device;
pub(crate) use rpc::new_rpc_handler; //pub(crate) use rpc::new_rpc_handler;

40
src/apps/device/models.rs

@ -1,6 +1,5 @@
use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use tdn::types::primitive::{Peer, PeerId, Result}; use tdn::types::primitives::{Peer, Result};
use tdn::types::rpc::{json, RpcParam}; use tdn::types::rpc::{json, RpcParam};
use tdn_storage::local::{DStorage, DsValue}; use tdn_storage::local::{DStorage, DsValue};
@ -8,13 +7,13 @@ pub(crate) struct Device {
pub id: i64, pub id: i64,
pub name: String, pub name: String,
pub info: String, pub info: String,
pub addr: PeerId, pub peer: Peer,
pub lasttime: i64, pub lasttime: i64,
pub online: bool, pub online: bool,
} }
impl Device { impl Device {
pub fn new(name: String, info: String, addr: PeerId) -> Self { pub fn new(name: String, info: String, peer: Peer) -> Self {
let start = SystemTime::now(); let start = SystemTime::now();
let lasttime = start let lasttime = start
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
@ -22,10 +21,10 @@ impl Device {
.unwrap_or(0) as i64; // safe for all life. .unwrap_or(0) as i64; // safe for all life.
Self { Self {
addr,
lasttime, lasttime,
info, info,
name, name,
peer,
id: 0, id: 0,
online: true, online: true,
} }
@ -35,7 +34,7 @@ impl Device {
fn from_values(mut v: Vec<DsValue>) -> Device { fn from_values(mut v: Vec<DsValue>) -> Device {
Device { Device {
lasttime: v.pop().unwrap().as_i64(), lasttime: v.pop().unwrap().as_i64(),
addr: PeerId::from_hex(v.pop().unwrap().as_str()).unwrap_or(PeerId::default()), peer: Peer::from_string(v.pop().unwrap().as_str()).unwrap_or(Peer::default()),
info: v.pop().unwrap().as_string(), info: v.pop().unwrap().as_string(),
name: v.pop().unwrap().as_string(), name: v.pop().unwrap().as_string(),
id: v.pop().unwrap().as_i64(), id: v.pop().unwrap().as_i64(),
@ -48,7 +47,7 @@ impl Device {
self.id, self.id,
self.name, self.name,
self.info, self.info,
self.addr.to_hex(), self.peer.to_string(),
self.lasttime, self.lasttime,
if self.online { "1" } else { "0" }, if self.online { "1" } else { "0" },
]) ])
@ -56,25 +55,22 @@ impl Device {
/// load account devices. /// load account devices.
pub fn list(db: &DStorage) -> Result<Vec<Device>> { pub fn list(db: &DStorage) -> Result<Vec<Device>> {
let matrix = db.query("SELECT id, name, info, addr, lasttime FROM devices")?; let matrix = db.query("SELECT id, name, info, peer, lasttime FROM devices")?;
let mut devices = vec![]; let mut devices = vec![];
for values in matrix { for values in matrix {
if values.len() == 5 { devices.push(Device::from_values(values));
devices.push(Device::from_values(values));
}
} }
Ok(devices) Ok(devices)
} }
pub fn distributes(db: &DStorage) -> Result<HashMap<PeerId, (Peer, i64, bool)>> { pub fn distributes(db: &DStorage) -> Result<Vec<(Peer, i64, bool)>> {
let matrix = db.query("SELECT id, addr FROM devices")?; let matrix = db.query("SELECT id, peer FROM devices")?;
let mut devices = HashMap::new(); let mut devices = vec![];
for mut values in matrix { for mut v in matrix {
if values.len() == 2 { if v.len() == 3 {
let addr = let peer = Peer::from_string(v.pop().unwrap().as_str()).unwrap_or(Peer::default());
PeerId::from_hex(values.pop().unwrap().as_str()).unwrap_or(PeerId::default()); let id = v.pop().unwrap().as_i64();
let id = values.pop().unwrap().as_i64(); devices.push((peer, id, false));
devices.insert(addr, (Peer::peer(addr), id, false));
} }
} }
Ok(devices) Ok(devices)
@ -95,10 +91,10 @@ impl Device {
pub fn insert(&mut self, db: &DStorage) -> Result<()> { pub fn insert(&mut self, db: &DStorage) -> Result<()> {
let sql = format!( let sql = format!(
"INSERT INTO devices (name, info, addr, lasttime) VALUES ('{}', '{}', '{}', {})", "INSERT INTO devices (name, info, peer, lasttime) VALUES ('{}', '{}', '{}', {})",
self.name, self.name,
self.info, self.info,
self.addr.to_hex(), self.peer.to_string(),
self.lasttime, self.lasttime,
); );
let id = db.insert(&sql)?; let id = db.insert(&sql)?;

10
src/apps/device/rpc.rs

@ -12,28 +12,28 @@ use crate::utils::device_status::device_status as local_device_status;
use super::Device; use super::Device;
#[inline] #[inline]
pub(crate) fn device_create(mgid: GroupId, device: &Device) -> RpcParam { pub(crate) fn device_create(mgid: PeerId, device: &Device) -> RpcParam {
rpc_response(0, "device-create", json!(device.to_rpc()), mgid) rpc_response(0, "device-create", json!(device.to_rpc()), mgid)
} }
#[inline] #[inline]
pub(crate) fn _device_remove(mgid: GroupId, id: i64) -> RpcParam { pub(crate) fn _device_remove(mgid: PeerId, id: i64) -> RpcParam {
rpc_response(0, "device-remove", json!([id]), mgid) rpc_response(0, "device-remove", json!([id]), mgid)
} }
#[inline] #[inline]
pub(crate) fn device_online(mgid: GroupId, id: i64) -> RpcParam { pub(crate) fn device_online(mgid: PeerId, id: i64) -> RpcParam {
rpc_response(0, "device-online", json!([id]), mgid) rpc_response(0, "device-online", json!([id]), mgid)
} }
#[inline] #[inline]
pub(crate) fn device_offline(mgid: GroupId, id: i64) -> RpcParam { pub(crate) fn device_offline(mgid: PeerId, id: i64) -> RpcParam {
rpc_response(0, "device-offline", json!([id]), mgid) rpc_response(0, "device-offline", json!([id]), mgid)
} }
#[inline] #[inline]
pub(crate) fn device_status( pub(crate) fn device_status(
mgid: GroupId, mgid: PeerId,
cpu: u32, cpu: u32,
memory: u32, memory: u32,
swap: u32, swap: u32,

7
src/daemon.rs

@ -8,15 +8,16 @@ use std::env::args;
mod account; mod account;
mod apps; mod apps;
mod consensus; //mod consensus;
mod event; //mod event;
mod group; mod group;
mod layer; mod layer;
mod migrate; mod migrate;
mod primitives; mod primitives;
mod rpc; mod rpc;
mod server; mod server;
mod session; //mod session;
mod global;
mod storage; mod storage;
mod utils; mod utils;

92
src/global.rs

@ -0,0 +1,92 @@
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
use tdn::prelude::{GroupId, PeerId, SendMessage};
use tokio::{sync::mpsc::Sender, sync::RwLock};
use crate::account::Account;
use crate::group::Group;
use crate::layer::Layer;
/// global status.
pub(crate) struct Global {
/// current running account.
pub peer_id: RwLock<PeerId>,
/// current account public height.
pub peer_pub_height: RwLock<u64>,
/// current account own height.
pub peer_own_height: RwLock<u64>,
/// current group.
pub group: RwLock<Group>,
/// current layer.
pub layer: RwLock<Layer>,
/// TDN network sender.
pub sender: RwLock<Sender<SendMessage>>,
/// message delivery tracking. uuid, me_gid, db_id.
pub _delivery: RwLock<HashMap<u64, (GroupId, i64)>>,
/// storage base path.
pub base: PathBuf,
/// random secret seed.
pub secret: [u8; 32],
}
impl Global {
pub fn init(
accounts: HashMap<PeerId, Account>,
tdn_send: Sender<SendMessage>,
base: PathBuf,
secret: [u8; 32],
) -> Self {
Global {
base,
secret,
peer_id: RwLock::new(PeerId::default()),
peer_pub_height: RwLock::new(0),
peer_own_height: RwLock::new(0),
group: RwLock::new(Group::init(accounts)),
layer: RwLock::new(Layer::init()),
sender: RwLock::new(tdn_send),
_delivery: RwLock::new(HashMap::new()),
}
}
pub async fn pid(&self) -> PeerId {
self.peer_id.read().await.clone()
}
pub async fn send(&self, msg: SendMessage) -> anyhow::Result<()> {
self.sender
.read()
.await
.send(msg)
.await
.map_err(|_e| anyhow!("network lost!"))
}
pub async fn clear(&self) {
*self.peer_id.write().await = PeerId::default();
self.layer.write().await.clear();
}
pub async fn reset(&self, pid: &PeerId, lock: &str) -> anyhow::Result<bool> {
if *self.peer_id.read().await == *pid {
return Ok(false);
}
let (pheight, oheight) =
self.group
.write()
.await
.reset(pid, lock, &self.base, &self.secret)?;
self.layer.write().await.clear();
*self.peer_id.write().await = *pid;
*self.peer_pub_height.write().await = pheight;
*self.peer_own_height.write().await = oheight;
self._delivery.write().await.clear();
// TODO change sender.
Ok(true)
}
}

1630
src/group.rs

File diff suppressed because it is too large Load Diff

42
src/group/running.rs

@ -1,11 +1,7 @@
use std::collections::HashMap; use esse_primitives::id_to_str;
use std::path::PathBuf; use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use tdn::types::{ use tdn::types::primitives::{Peer, PeerId, PeerKey, Result};
group::GroupId,
primitive::{Peer, PeerId, Result},
};
use tdn_did::Keypair;
use tdn_storage::local::DStorage; use tdn_storage::local::DStorage;
use crate::apps::device::Device; use crate::apps::device::Device;
@ -13,21 +9,21 @@ use crate::migrate::CONSENSUS_DB;
pub(crate) struct RunningAccount { pub(crate) struct RunningAccount {
/// secret keypair. /// secret keypair.
pub keypair: Keypair, pub keypair: PeerKey,
/// device's name. /// device's name.
pub device_name: String, pub device_name: String,
/// device's info. /// device's info.
pub device_info: String, pub device_info: String,
/// distribute connected devices. /// distribute connected devices.
pub distributes: HashMap<PeerId, (Peer, i64, bool)>, pub distributes: Vec<(Peer, i64, bool)>,
/// uptime /// uptime
pub uptime: u32, pub uptime: u32,
} }
impl RunningAccount { impl RunningAccount {
pub fn init(keypair: Keypair, base: &PathBuf, key: &str, gid: &GroupId) -> Result<Self> { pub fn init(keypair: PeerKey, base: &PathBuf, key: &str, pid: &PeerId) -> Result<Self> {
let mut db_path = base.clone(); let mut db_path = base.clone();
db_path.push(gid.to_hex()); db_path.push(id_to_str(&pid));
db_path.push(CONSENSUS_DB); db_path.push(CONSENSUS_DB);
let db = DStorage::open(db_path, key)?; let db = DStorage::open(db_path, key)?;
let distributes = Device::distributes(&db)?; let distributes = Device::distributes(&db)?;
@ -49,21 +45,23 @@ impl RunningAccount {
}) })
} }
pub fn add_online(&mut self, addr: &PeerId) -> Result<i64> { pub fn online(&mut self, peer: &Peer) -> Result<i64> {
if let Some(v) = self.distributes.get_mut(addr) { for i in self.distributes.iter_mut() {
v.2 = true; if &i.0 == peer {
Ok(v.1) i.2 = true;
} else { return Ok(i.1);
Err(anyhow!("device missing")) }
} }
Err(anyhow!("missing distribute device"))
} }
pub fn offline(&mut self, addr: &PeerId) -> Result<i64> { pub fn offline(&mut self, peer: &Peer) -> Result<i64> {
if let Some(v) = self.distributes.get_mut(addr) { for i in self.distributes.iter_mut() {
v.2 = false; if &i.0 == peer {
Ok(v.1) i.2 = false;
} else { return Ok(i.1);
Err(anyhow!("device missing")) }
} }
Err(anyhow!("missing distribute device"))
} }
} }

742
src/layer.rs

@ -5,15 +5,15 @@ use std::sync::Arc;
use tdn::types::{ use tdn::types::{
group::GroupId, group::GroupId,
message::SendType, message::SendType,
primitive::{HandleResult, Peer, PeerId, Result}, primitives::{HandleResult, Peer, PeerId, Result},
}; };
use tokio::sync::RwLock; use tokio::sync::RwLock;
use crate::account::User; use crate::account::User;
use crate::apps::chat::{chat_conn, LayerEvent as ChatLayerEvent}; //use crate::apps::chat::{chat_conn, LayerEvent as ChatLayerEvent};
use crate::apps::group::{group_conn, GROUP_ID}; //use crate::apps::group::{group_conn, GROUP_ID};
use crate::group::Group; use crate::group::Group;
use crate::session::{Session, SessionType}; //use crate::session::{Session, SessionType};
/// ESSE app's `BaseLayerEvent`. /// ESSE app's `BaseLayerEvent`.
/// EVERY LAYER APP MUST EQUAL THE FIRST THREE FIELDS. /// EVERY LAYER APP MUST EQUAL THE FIRST THREE FIELDS.
@ -29,157 +29,126 @@ pub(crate) enum LayerEvent {
/// ESSE layers. /// ESSE layers.
pub(crate) struct Layer { pub(crate) struct Layer {
/// layer_gid (include account id, group chat id) => running_layer. /// running layers: (Layer_gid, layer sessions)
pub runnings: HashMap<GroupId, RunningLayer>, pub sessions: HashMap<GroupId, HashMap<PeerId, LayerSession>>,
/// message delivery tracking. uuid, me_gid, db_id.
pub delivery: HashMap<u64, (GroupId, i64)>,
/// storage base path.
pub base: PathBuf,
/// self peer addr.
pub addr: PeerId,
/// group info.
pub group: Arc<RwLock<Group>>,
} }
impl Layer { impl Layer {
pub async fn init(base: PathBuf, addr: PeerId, group: Arc<RwLock<Group>>) -> Result<Layer> { pub fn init() -> Layer {
Ok(Layer { // add all inner-service layers
base, // add all third-service layers
group, let mut sessions = HashMap::new();
addr,
runnings: HashMap::new(), // runnings.insert(CHAT_GROUP_ID, RunningLayer::init());
delivery: HashMap::new(),
}) Layer { sessions }
} }
pub fn base(&self) -> &PathBuf { pub fn clear(&mut self) {
&self.base let _ = self.sessions.iter_mut().map(|(_, s)| s.clear());
} }
pub fn running(&self, gid: &GroupId) -> Result<&RunningLayer> { // pub fn remove_running(&mut self, gid: &GroupId) -> HashMap<PeerId, GroupId> {
self.runnings.get(gid).ok_or(anyhow!("not online")) // // check close the stable connection.
} // let mut addrs: HashMap<PeerId, GroupId> = HashMap::new();
// if let Some(running) = self.runnings.remove(gid) {
pub fn running_mut(&mut self, gid: &GroupId) -> Result<&mut RunningLayer> { // for (addr, fgid) in running.remove_onlines() {
self.runnings.get_mut(gid).ok_or(anyhow!("not online")) // addrs.insert(addr, fgid);
} // }
// }
pub fn add_running(
&mut self, // let mut need_keep = vec![];
gid: &GroupId, // for (_, running) in &self.runnings {
owner: GroupId, // for addr in addrs.keys() {
id: i64, // if running.check_addr_online(addr) {
consensus: i64, // need_keep.push(*addr);
) -> Result<()> { // }
if !self.runnings.contains_key(gid) { // }
self.runnings // }
.insert(*gid, RunningLayer::init(owner, id, consensus)); // for i in need_keep {
} // addrs.remove(&i);
// }
Ok(())
} // addrs
// }
pub fn remove_running(&mut self, gid: &GroupId) -> HashMap<PeerId, GroupId> {
// check close the stable connection. // pub fn remove_all_running(&mut self) -> HashMap<PeerId, GroupId> {
let mut addrs: HashMap<PeerId, GroupId> = HashMap::new(); // let mut addrs: HashMap<PeerId, GroupId> = HashMap::new();
if let Some(running) = self.runnings.remove(gid) { // for (_, running) in self.runnings.drain() {
for (addr, fgid) in running.remove_onlines() { // for (addr, fgid) in running.remove_onlines() {
addrs.insert(addr, fgid); // addrs.insert(addr, fgid);
} // }
} // }
// addrs
let mut need_keep = vec![]; // }
for (_, running) in &self.runnings {
for addr in addrs.keys() { // pub fn get_running_remote_id(&self, mgid: &GroupId, fgid: &GroupId) -> Result<(i64, i64)> {
if running.check_addr_online(addr) { // debug!("onlines: {:?}, find: {:?}", self.runnings.keys(), mgid);
need_keep.push(*addr); // self.running(mgid)?.get_online_id(fgid)
} // }
}
} // pub fn remove_online(&mut self, gid: &GroupId, fgid: &GroupId) -> Option<PeerId> {
for i in need_keep { // self.running_mut(gid).ok()?.remove_online(fgid)
addrs.remove(&i); // }
}
// pub async fn all_layer_conns(&self) -> Result<HashMap<GroupId, Vec<(GroupId, SendType)>>> {
addrs // let mut conns = HashMap::new();
} // let group_lock = self.group.read().await;
// for mgid in self.runnings.keys() {
pub fn remove_all_running(&mut self) -> HashMap<PeerId, GroupId> { // let mut vecs = vec![];
let mut addrs: HashMap<PeerId, GroupId> = HashMap::new();
for (_, running) in self.runnings.drain() { // let db = group_lock.session_db(&mgid)?;
for (addr, fgid) in running.remove_onlines() { // let sessions = Session::list(&db)?;
addrs.insert(addr, fgid); // drop(db);
}
} // for s in sessions {
addrs // match s.s_type {
} // SessionType::Chat => {
// let proof = group_lock.prove_addr(mgid, &s.addr)?;
pub fn get_running_remote_id(&self, mgid: &GroupId, fgid: &GroupId) -> Result<(i64, i64)> { // vecs.push((s.gid, chat_conn(proof, Peer::peer(s.addr))));
debug!("onlines: {:?}, find: {:?}", self.runnings.keys(), mgid); // }
self.running(mgid)?.get_online_id(fgid) // SessionType::Group => {
} // let proof = group_lock.prove_addr(mgid, &s.addr)?;
// vecs.push((GROUP_ID, group_conn(proof, Peer::peer(s.addr), s.gid)));
pub fn remove_online(&mut self, gid: &GroupId, fgid: &GroupId) -> Option<PeerId> { // }
self.running_mut(gid).ok()?.remove_online(fgid) // _ => {}
} // }
// }
pub async fn all_layer_conns(&self) -> Result<HashMap<GroupId, Vec<(GroupId, SendType)>>> {
let mut conns = HashMap::new(); // conns.insert(*mgid, vecs);
let group_lock = self.group.read().await; // }
for mgid in self.runnings.keys() {
let mut vecs = vec![]; // Ok(conns)
// }
let db = group_lock.session_db(&mgid)?;
let sessions = Session::list(&db)?; // pub fn is_addr_online(&self, faddr: &PeerId) -> bool {
drop(db); // for (_, running) in &self.runnings {
// if running.check_addr_online(faddr) {
for s in sessions { // return true;
match s.s_type { // }
SessionType::Chat => { // }
let proof = group_lock.prove_addr(mgid, &s.addr)?; // return false;
vecs.push((s.gid, chat_conn(proof, Peer::peer(s.addr)))); // }
}
SessionType::Group => { // pub fn is_online(&self, gid: &GroupId, fgid: &GroupId) -> bool {
let proof = group_lock.prove_addr(mgid, &s.addr)?; // if let Some(running) = self.runnings.get(gid) {
vecs.push((GROUP_ID, group_conn(proof, Peer::peer(s.addr), s.gid))); // running.is_online(fgid)
} // } else {
_ => {} // false
} // }
} // }
conns.insert(*mgid, vecs); // pub fn broadcast(&self, user: User, results: &mut HandleResult) {
} // let gid = user.id;
// let info = ChatLayerEvent::InfoRes(user);
Ok(conns) // let data = bincode::serialize(&info).unwrap_or(vec![]);
} // if let Some(running) = self.runnings.get(&gid) {
// for (fgid, online) in &running.sessions {
pub fn is_addr_online(&self, faddr: &PeerId) -> bool { // let msg = SendType::Event(0, *online.online.addr(), data.clone());
for (_, running) in &self.runnings { // results.layers.push((gid, *fgid, msg));
if running.check_addr_online(faddr) { // }
return true; // }
} // }
}
return false;
}
pub fn is_online(&self, gid: &GroupId, fgid: &GroupId) -> bool {
if let Some(running) = self.runnings.get(gid) {
running.is_online(fgid)
} else {
false
}
}
pub fn broadcast(&self, user: User, results: &mut HandleResult) {
let gid = user.id;
let info = ChatLayerEvent::InfoRes(user);
let data = bincode::serialize(&info).unwrap_or(vec![]);
if let Some(running) = self.runnings.get(&gid) {
for (fgid, online) in &running.sessions {
let msg = SendType::Event(0, *online.online.addr(), data.clone());
results.layers.push((gid, *fgid, msg));
}
}
}
} }
/// online info. /// online info.
@ -188,13 +157,13 @@ pub(crate) enum Online {
/// connected to this device. /// connected to this device.
Direct(PeerId), Direct(PeerId),
/// connected to other device. /// connected to other device.
_Relay(PeerId), Relay(PeerId),
} }
impl Online { impl Online {
fn addr(&self) -> &PeerId { fn addr(&self) -> &PeerId {
match self { match self {
Online::Direct(ref addr) | Online::_Relay(ref addr) => addr, Online::Direct(ref addr) | Online::Relay(ref addr) => addr,
} }
} }
} }
@ -210,241 +179,236 @@ pub(crate) struct OnlineSession {
pub remain: u16, // keep-alive remain minutes pub remain: u16, // keep-alive remain minutes
} }
impl OnlineSession { // impl OnlineSession {
fn new(online: Online, db_id: i64, db_fid: i64) -> Self { // fn new(online: Online, db_id: i64, db_fid: i64) -> Self {
Self { // Self {
online, // online,
db_id, // db_id,
db_fid, // db_fid,
suspend_me: false, // suspend_me: false,
suspend_remote: false, // suspend_remote: false,
remain: 0, // remain: 0,
} // }
} // }
fn close_suspend(&mut self) -> bool { // fn close_suspend(&mut self) -> bool {
if self.suspend_me && self.suspend_remote { // if self.suspend_me && self.suspend_remote {
if self.remain == 0 { // if self.remain == 0 {
true // true
} else { // } else {
self.remain -= 1; // self.remain -= 1;
false // false
} // }
} else { // } else {
false // false
} // }
} // }
} // }
pub(crate) struct RunningLayer { /// online connected layer session.
owner: GroupId, // if is service it has owner account. pub(crate) struct LayerSession {
/// layer current database id. /// session online type.
id: i64, pub online: Online,
/// layer current consensus height. /// current layer consensus(height).
consensus: i64, pub consensus: i64,
/// online group (friends/services) => (group's address, group's db id) /// session database id.
sessions: HashMap<GroupId, OnlineSession>, pub s_id: i64,
/// layer database id.
pub db_id: i64,
/// if session is suspend by me.
pub suspend_me: bool,
/// if session is suspend by remote.
pub suspend_remote: bool,
/// keep alive remain minutes.
pub remain: u16,
} }
impl RunningLayer { impl LayerSession {
pub fn init(owner: GroupId, id: i64, consensus: i64) -> Self { // pub fn increased(&mut self) -> i64 {
RunningLayer { // self.consensus += 1;
owner, // self.consensus
id, // }
consensus,
sessions: HashMap::new(), // pub fn active(&mut self, gid: &GroupId, is_me: bool) -> Option<PeerId> {
} // if let Some(online) = self.sessions.get_mut(gid) {
} // if is_me {
// online.suspend_me = false;
pub fn owner_height_id(&self) -> (GroupId, i64, i64) { // } else {
(self.owner, self.consensus, self.id) // online.suspend_remote = false;
} // }
pub fn increased(&mut self) -> i64 { // online.remain = 0;
self.consensus += 1; // Some(*online.online.addr())
self.consensus // } else {
} // None
// }
pub fn active(&mut self, gid: &GroupId, is_me: bool) -> Option<PeerId> { // }
if let Some(online) = self.sessions.get_mut(gid) {
if is_me { // pub fn suspend(&mut self, gid: &GroupId, is_me: bool, must: bool) -> Result<bool> {
online.suspend_me = false; // if let Some(online) = self.sessions.get_mut(gid) {
} else { // if must {
online.suspend_remote = false; // online.suspend_me = true;
} // online.suspend_remote = true;
// }
online.remain = 0;
Some(*online.online.addr()) // if is_me {
} else { // online.suspend_me = true;
None // } else {
} // online.suspend_remote = true;
} // }
pub fn suspend(&mut self, gid: &GroupId, is_me: bool, must: bool) -> Result<bool> { // if online.suspend_remote && online.suspend_me {
if let Some(online) = self.sessions.get_mut(gid) { // online.remain = 6; // keep-alive 10~11 minutes 120s/time
if must { // Ok(true)
online.suspend_me = true; // } else {
online.suspend_remote = true; // Ok(false)
} // }
// } else {
if is_me { // Err(anyhow!("remote not online"))
online.suspend_me = true; // }
} else { // }
online.suspend_remote = true;
} // pub fn get_online_id(&self, gid: &GroupId) -> Result<(i64, i64)> {
// debug!("onlines: {:?}, find: {:?}", self.sessions.keys(), gid);
if online.suspend_remote && online.suspend_me { // self.sessions
online.remain = 6; // keep-alive 10~11 minutes 120s/time // .get(gid)
Ok(true) // .map(|online| (online.db_id, online.db_fid))
} else { // .ok_or(anyhow!("remote not online"))
Ok(false) // }
}
} else { // /// get online peer's addr.
Err(anyhow!("remote not online")) // pub fn online(&self, gid: &GroupId) -> Result<PeerId> {
} // self.sessions
} // .get(gid)
// .map(|online| *online.online.addr())
pub fn get_online_id(&self, gid: &GroupId) -> Result<(i64, i64)> { // .ok_or(anyhow!("remote not online"))
debug!("onlines: {:?}, find: {:?}", self.sessions.keys(), gid); // }
self.sessions
.get(gid) // pub fn online_direct(&self, gid: &GroupId) -> Result<PeerId> {
.map(|online| (online.db_id, online.db_fid)) // if let Some(online) = self.sessions.get(gid) {
.ok_or(anyhow!("remote not online")) // match online.online {
} // Online::Direct(addr) => return Ok(addr),
// _ => {}
/// get online peer's addr. // }
pub fn online(&self, gid: &GroupId) -> Result<PeerId> { // }
self.sessions // Err(anyhow!("no direct online"))
.get(gid) // }
.map(|online| *online.online.addr())
.ok_or(anyhow!("remote not online")) // /// get all online peer.
} // pub fn onlines(&self) -> Vec<(&GroupId, &PeerId)> {
// self.sessions
pub fn online_direct(&self, gid: &GroupId) -> Result<PeerId> { // .iter()
if let Some(online) = self.sessions.get(gid) { // .map(|(fgid, online)| (fgid, online.online.addr()))
match online.online { // .collect()
Online::Direct(addr) => return Ok(addr), // }
_ => {}
} // pub fn is_online(&self, gid: &GroupId) -> bool {
} // self.sessions.contains_key(gid)
Err(anyhow!("no direct online")) // }
}
// /// check add online.
/// get all online peer. // pub fn check_add_online(
pub fn onlines(&self) -> Vec<(&GroupId, &PeerId)> { // &mut self,
self.sessions // gid: GroupId,
.iter() // online: Online,
.map(|(fgid, online)| (fgid, online.online.addr())) // id: i64,
.collect() // fid: i64,
} // ) -> Result<()> {
// if let Some(o) = self.sessions.get(&gid) {
pub fn is_online(&self, gid: &GroupId) -> bool { // match (&o.online, &online) {
self.sessions.contains_key(gid) // (Online::_Relay(..), Online::Direct(..)) => {
} // self.sessions
// .insert(gid, OnlineSession::new(online, id, fid));
/// check add online. // Ok(())
pub fn check_add_online( // }
&mut self, // _ => Err(anyhow!("remote had online")),
gid: GroupId, // }
online: Online, // } else {
id: i64, // self.sessions
fid: i64, // .insert(gid, OnlineSession::new(online, id, fid));
) -> Result<()> { // Ok(())
if let Some(o) = self.sessions.get(&gid) { // }
match (&o.online, &online) { // }
(Online::_Relay(..), Online::Direct(..)) => {
self.sessions // /// check offline, and return is direct.
.insert(gid, OnlineSession::new(online, id, fid)); // pub fn check_offline(&mut self, gid: &GroupId, addr: &PeerId) -> bool {
Ok(()) // if let Some(online) = self.sessions.remove(gid) {
} // if online.online.addr() != addr {
_ => Err(anyhow!("remote had online")), // return false;
} // }
} else {
self.sessions // match online.online {
.insert(gid, OnlineSession::new(online, id, fid)); // Online::Direct(..) => {
Ok(()) // return true;
} // }
} // _ => {}
// }
/// check offline, and return is direct. // }
pub fn check_offline(&mut self, gid: &GroupId, addr: &PeerId) -> bool { // false
if let Some(online) = self.sessions.remove(gid) { // }
if online.online.addr() != addr {
return false; // pub fn remove_online(&mut self, gid: &GroupId) -> Option<PeerId> {
} // self.sessions
// .remove(gid)
match online.online { // .map(|online| *online.online.addr())
Online::Direct(..) => { // }
return true;
} // /// remove all onlines peer.
_ => {} // pub fn remove_onlines(self) -> Vec<(PeerId, GroupId)> {
} // let mut peers = vec![];
} // for (fgid, online) in self.sessions {
false // match online.online {
} // Online::Direct(addr) => peers.push((addr, fgid)),
// _ => {}
pub fn remove_online(&mut self, gid: &GroupId) -> Option<PeerId> { // }
self.sessions // }
.remove(gid) // peers
.map(|online| *online.online.addr()) // }
}
// /// check if addr is online.
/// remove all onlines peer. // pub fn check_addr_online(&self, addr: &PeerId) -> bool {
pub fn remove_onlines(self) -> Vec<(PeerId, GroupId)> { // for (_, online) in &self.sessions {
let mut peers = vec![]; // if online.online.addr() == addr {
for (fgid, online) in self.sessions { // return true;
match online.online { // }
Online::Direct(addr) => peers.push((addr, fgid)), // }
_ => {} // false
} // }
}
peers // /// peer leave, remove online peer.
} // pub fn peer_leave(&mut self, addr: &PeerId) -> Vec<i64> {
// let mut peers = vec![];
/// check if addr is online. // let mut deletes = vec![];
pub fn check_addr_online(&self, addr: &PeerId) -> bool { // for (fgid, online) in &self.sessions {
for (_, online) in &self.sessions { // if online.online.addr() == addr {
if online.online.addr() == addr { // peers.push(online.db_id);
return true; // deletes.push(*fgid);
} // }
} // }
false // for i in &deletes {
} // self.sessions.remove(&i);
// }
/// peer leave, remove online peer.
pub fn peer_leave(&mut self, addr: &PeerId) -> Vec<i64> { // peers
let mut peers = vec![]; // }
let mut deletes = vec![];
for (fgid, online) in &self.sessions { // /// list all onlines groups.
if online.online.addr() == addr { // pub fn close_suspend(&mut self, self_addr: &PeerId) -> Vec<(GroupId, PeerId, i64)> {
peers.push(online.db_id); // let mut needed = vec![];
deletes.push(*fgid); // for (fgid, online) in &mut self.sessions {
} // // when online is self. skip.
} // if online.online == Online::Direct(*self_addr) {
for i in &deletes { // continue;
self.sessions.remove(&i); // }
}
// if online.close_suspend() {
peers // needed.push((*fgid, *online.online.addr(), online.db_id));
} // }
// }
/// list all onlines groups.
pub fn close_suspend(&mut self, self_addr: &PeerId) -> Vec<(GroupId, PeerId, i64)> { // for (gid, _, _) in needed.iter() {
let mut needed = vec![]; // self.sessions.remove(gid);
for (fgid, online) in &mut self.sessions { // }
// when online is self. skip. // needed
if online.online == Online::Direct(*self_addr) { // }
continue;
}
if online.close_suspend() {
needed.push((*fgid, *online.online.addr(), online.db_id));
}
}
for (gid, _, _) in needed.iter() {
self.sessions.remove(gid);
}
needed
}
} }

7
src/lib.rs

@ -9,15 +9,16 @@ use std::os::raw::c_char;
mod account; mod account;
mod apps; mod apps;
mod consensus; //mod consensus;
mod event; //mod event;
mod group; mod group;
mod layer; mod layer;
mod migrate; mod migrate;
mod primitives; mod primitives;
mod rpc; mod rpc;
mod server; mod server;
mod session; //mod session;
mod global;
mod storage; mod storage;
mod utils; mod utils;

2
src/migrate.rs

@ -1,5 +1,5 @@
use std::path::PathBuf; use std::path::PathBuf;
use tdn::types::primitive::Result; use tdn::types::primitives::Result;
use tdn_storage::local::DStorage; use tdn_storage::local::DStorage;
pub mod consensus; pub mod consensus;

2
src/migrate/account.rs

@ -2,7 +2,7 @@
pub(super) const ACCOUNT_VERSIONS: [&str; 13] = [ pub(super) const ACCOUNT_VERSIONS: [&str; 13] = [
"CREATE TABLE IF NOT EXISTS accounts( "CREATE TABLE IF NOT EXISTS accounts(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
gid TEXT NOT NULL, pid TEXT NOT NULL,
indx INTEGER NOT NULL, indx INTEGER NOT NULL,
lang INTEGER NOT NULL, lang INTEGER NOT NULL,
pass TEXT NOT NULL, pass TEXT NOT NULL,

2
src/migrate/consensus.rs

@ -10,7 +10,7 @@ pub(super) const CONSENSUS_VERSIONS: [&str; 9] = [
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
info TEXT NOT NULL, info TEXT NOT NULL,
addr TEXT NOT NULL, peer TEXT NOT NULL,
lasttime INTEGER NOT NULL);", lasttime INTEGER NOT NULL);",
"CREATE TABLE IF NOT EXISTS db_tables( "CREATE TABLE IF NOT EXISTS db_tables(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,

3
src/migrate/session.rs

@ -3,7 +3,6 @@ pub(super) const SESSION_VERSIONS: [&str; 2] = [
"CREATE TABLE IF NOT EXISTS sessions( "CREATE TABLE IF NOT EXISTS sessions(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
fid INTEGER NOT NULL, fid INTEGER NOT NULL,
gid TEXT NOT NULL,
addr TEXT NOT NULL, addr TEXT NOT NULL,
s_type INTEGER NOT NULL, s_type INTEGER NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
@ -12,5 +11,5 @@ pub(super) const SESSION_VERSIONS: [&str; 2] = [
last_datetime INTEGER, last_datetime INTEGER,
last_content TEXT, last_content TEXT,
last_readed INTEGER);", last_readed INTEGER);",
"INSERT INTO sessions (fid, gid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES (0, '', '', 3, '', 0, 0, 0, '', 1);", // Jarvis. "INSERT INTO sessions (fid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES (0, '', 3, '', 0, 0, 0, '', 1);", // Jarvis.
]; ];

785
src/rpc.rs

@ -1,10 +1,11 @@
use esse_primitives::{id_from_str, id_to_str};
use std::collections::HashMap; use std::collections::HashMap;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::Arc; use std::sync::Arc;
use tdn::types::{ use tdn::types::{
group::GroupId, group::GroupId,
message::{NetworkType, SendMessage, SendType, StateRequest, StateResponse}, message::{NetworkType, SendMessage, SendType, StateRequest, StateResponse},
primitive::{HandleResult, Peer, PeerId, Result}, primitives::{HandleResult, Peer, PeerId, Result},
rpc::{json, rpc_response, RpcError, RpcHandler, RpcParam}, rpc::{json, rpc_response, RpcError, RpcHandler, RpcParam},
}; };
use tdn_did::{generate_mnemonic, Count}; use tdn_did::{generate_mnemonic, Count};
@ -15,28 +16,20 @@ use tokio::sync::{
use crate::account::lang_from_i64; use crate::account::lang_from_i64;
use crate::apps::app_rpc_inject; use crate::apps::app_rpc_inject;
use crate::apps::chat::chat_conn; use crate::global::Global;
use crate::apps::group::{add_layer, group_conn, GroupChat}; //use crate::apps::chat::chat_conn;
use crate::event::InnerEvent; //use crate::apps::group::{add_layer, group_conn, GroupChat};
//use crate::event::InnerEvent;
use crate::group::Group; use crate::group::Group;
use crate::layer::{Layer, LayerEvent, Online}; use crate::layer::{Layer, LayerEvent, Online};
use crate::session::{connect_session, Session, SessionType}; //use crate::session::{connect_session, Session, SessionType};
pub(crate) fn init_rpc( pub(crate) fn init_rpc(global: Arc<Global>) -> RpcHandler<Global> {
addr: PeerId, let mut handler = new_rpc_handler(global);
group: Arc<RwLock<Group>>,
layer: Arc<RwLock<Layer>>,
) -> RpcHandler<RpcState> {
let mut handler = new_rpc_handler(addr, group, layer);
app_rpc_inject(&mut handler); app_rpc_inject(&mut handler);
handler handler
} }
pub(crate) struct RpcState {
pub group: Arc<RwLock<Group>>,
pub layer: Arc<RwLock<Layer>>,
}
#[inline] #[inline]
pub(crate) fn network_stable(peers: Vec<(PeerId, bool)>) -> RpcParam { pub(crate) fn network_stable(peers: Vec<(PeerId, bool)>) -> RpcParam {
let s_peers: Vec<Vec<String>> = peers let s_peers: Vec<Vec<String>> = peers
@ -50,100 +43,95 @@ pub(crate) fn network_stable(peers: Vec<(PeerId, bool)>) -> RpcParam {
vec![p.to_hex(), d] vec![p.to_hex(), d]
}) })
.collect(); .collect();
rpc_response(0, "network-stable", json!(s_peers), GroupId::default()) rpc_response(0, "network-stable", json!(s_peers))
} }
#[inline] #[inline]
pub(crate) fn network_dht(peers: Vec<PeerId>) -> RpcParam { pub(crate) fn network_dht(peers: Vec<PeerId>) -> RpcParam {
let s_peers: Vec<String> = peers.iter().map(|p| p.to_hex()).collect(); let s_peers: Vec<String> = peers.iter().map(|p| p.to_hex()).collect();
rpc_response(0, "network-dht", json!(s_peers), GroupId::default()) rpc_response(0, "network-dht", json!(s_peers))
}
#[inline]
pub(crate) fn account_update(mgid: GroupId, name: &str, avatar: String) -> RpcParam {
rpc_response(
0,
"account-update",
json!([mgid.to_hex(), name, avatar]),
mgid,
)
}
#[inline]
pub(crate) fn session_create(mgid: GroupId, session: &Session) -> RpcParam {
rpc_response(0, "session-create", session.to_rpc(), mgid)
}
#[inline]
pub(crate) fn session_last(
mgid: GroupId,
id: &i64,
time: &i64,
content: &str,
readed: bool,
) -> RpcParam {
rpc_response(0, "session-last", json!([id, time, content, readed]), mgid)
}
#[inline]
pub(crate) fn notice_menu(mgid: GroupId, t: &SessionType) -> RpcParam {
rpc_response(0, "notice-menu", json!([t.to_int()]), mgid)
}
#[inline]
pub(crate) fn session_update_name(mgid: GroupId, id: &i64, name: &str) -> RpcParam {
rpc_response(0, "session-update", json!([id, "", name, false]), mgid)
}
#[inline]
pub(crate) fn session_update(
mgid: GroupId,
id: &i64,
addr: &PeerId,
name: &str,
is_top: bool,
) -> RpcParam {
rpc_response(
0,
"session-update",
json!([id, addr.to_hex(), name, is_top]),
mgid,
)
}
#[inline]
pub(crate) fn session_connect(mgid: GroupId, id: &i64, addr: &PeerId) -> RpcParam {
rpc_response(0, "session-connect", json!([id, addr.to_hex()]), mgid)
}
#[inline]
pub(crate) fn session_suspend(mgid: GroupId, id: &i64) -> RpcParam {
rpc_response(0, "session-suspend", json!([id]), mgid)
}
#[inline]
pub(crate) fn session_lost(mgid: GroupId, id: &i64) -> RpcParam {
rpc_response(0, "session-lost", json!([id]), mgid)
} }
#[inline] #[inline]
pub(crate) fn session_delete(mgid: GroupId, id: &i64) -> RpcParam { pub(crate) fn account_update(pid: &PeerId, name: &str, avatar: String) -> RpcParam {
rpc_response(0, "session-delete", json!([id]), mgid) rpc_response(0, "account-update", json!([id_to_str(pid), name, avatar]))
} }
#[inline] // #[inline]
pub(crate) fn session_close(mgid: GroupId, id: &i64) -> RpcParam { // pub(crate) fn session_create(mgid: GroupId, session: &Session) -> RpcParam {
rpc_response(0, "session-close", json!([id]), mgid) // rpc_response(0, "session-create", session.to_rpc(), mgid)
} // }
#[inline] // #[inline]
fn session_list(sessions: Vec<Session>) -> RpcParam { // pub(crate) fn session_last(
let mut results = vec![]; // mgid: GroupId,
for session in sessions { // id: &i64,
results.push(session.to_rpc()); // time: &i64,
} // content: &str,
json!(results) // readed: bool,
} // ) -> RpcParam {
// rpc_response(0, "session-last", json!([id, time, content, readed]), mgid)
// }
// #[inline]
// pub(crate) fn notice_menu(mgid: GroupId, t: &SessionType) -> RpcParam {
// rpc_response(0, "notice-menu", json!([t.to_int()]), mgid)
// }
// #[inline]
// pub(crate) fn session_update_name(mgid: GroupId, id: &i64, name: &str) -> RpcParam {
// rpc_response(0, "session-update", json!([id, "", name, false]), mgid)
// }
// #[inline]
// pub(crate) fn session_update(
// mgid: GroupId,
// id: &i64,
// addr: &PeerId,
// name: &str,
// is_top: bool,
// ) -> RpcParam {
// rpc_response(
// 0,
// "session-update",
// json!([id, addr.to_hex(), name, is_top]),
// mgid,
// )
// }
// #[inline]
// pub(crate) fn session_connect(mgid: GroupId, id: &i64, addr: &PeerId) -> RpcParam {
// rpc_response(0, "session-connect", json!([id, addr.to_hex()]), mgid)
// }
// #[inline]
// pub(crate) fn session_suspend(mgid: GroupId, id: &i64) -> RpcParam {
// rpc_response(0, "session-suspend", json!([id]), mgid)
// }
// #[inline]
// pub(crate) fn session_lost(mgid: GroupId, id: &i64) -> RpcParam {
// rpc_response(0, "session-lost", json!([id]), mgid)
// }
// #[inline]
// pub(crate) fn session_delete(mgid: GroupId, id: &i64) -> RpcParam {
// rpc_response(0, "session-delete", json!([id]), mgid)
// }
// #[inline]
// pub(crate) fn session_close(mgid: GroupId, id: &i64) -> RpcParam {
// rpc_response(0, "session-close", json!([id]), mgid)
// }
// #[inline]
// fn session_list(sessions: Vec<Session>) -> RpcParam {
// let mut results = vec![];
// for session in sessions {
// results.push(session.to_rpc());
// }
// json!(results)
// }
#[inline] #[inline]
pub(crate) async fn sleep_waiting_close_stable( pub(crate) async fn sleep_waiting_close_stable(
@ -154,20 +142,13 @@ pub(crate) async fn sleep_waiting_close_stable(
tokio::time::sleep(std::time::Duration::from_secs(10)).await; tokio::time::sleep(std::time::Duration::from_secs(10)).await;
for (addr, _) in groups { for (addr, _) in groups {
sender sender
.send(SendMessage::Group( .send(SendMessage::Group(SendType::Disconnect(addr)))
Default::default(),
SendType::Disconnect(addr),
))
.await?; .await?;
} }
for (faddr, fgid) in layers { for (faddr, fgid) in layers {
sender sender
.send(SendMessage::Layer( .send(SendMessage::Layer(fgid, SendType::Disconnect(faddr)))
Default::default(),
fgid,
SendType::Disconnect(faddr),
))
.await?; .await?;
} }
@ -175,7 +156,7 @@ pub(crate) async fn sleep_waiting_close_stable(
} }
#[inline] #[inline]
pub(crate) async fn inner_rpc(uid: u64, method: &str, sender: &Sender<SendMessage>) -> Result<()> { pub(crate) async fn inner_rpc(uid: u64, method: &str, global: &Arc<Global>) -> Result<()> {
// Inner network default rpc method. only use in http-rpc. // Inner network default rpc method. only use in http-rpc.
if method == "network-stable" || method == "network-dht" { if method == "network-stable" || method == "network-dht" {
let req = match method { let req = match method {
@ -185,7 +166,10 @@ pub(crate) async fn inner_rpc(uid: u64, method: &str, sender: &Sender<SendMessag
}; };
let (s, mut r) = mpsc::channel::<StateResponse>(128); let (s, mut r) = mpsc::channel::<StateResponse>(128);
let _ = sender let _ = global
.sender
.read()
.await
.send(SendMessage::Network(NetworkType::NetworkState(req, s))) .send(SendMessage::Network(NetworkType::NetworkState(req, s)))
.await .await
.expect("TDN channel closed"); .expect("TDN channel closed");
@ -198,7 +182,10 @@ pub(crate) async fn inner_rpc(uid: u64, method: &str, sender: &Sender<SendMessag
} }
}; };
sender global
.sender
.read()
.await
.send(SendMessage::Rpc(uid, param, false)) .send(SendMessage::Rpc(uid, param, false))
.await .await
.expect("TDN channel closed"); .expect("TDN channel closed");
@ -209,58 +196,44 @@ pub(crate) async fn inner_rpc(uid: u64, method: &str, sender: &Sender<SendMessag
Err(anyhow!("not found")) Err(anyhow!("not found"))
} }
fn new_rpc_handler( fn new_rpc_handler(global: Arc<Global>) -> RpcHandler<Global> {
addr: PeerId, let mut handler = RpcHandler::new_with_state(global);
group: Arc<RwLock<Group>>,
layer: Arc<RwLock<Layer>>,
) -> RpcHandler<RpcState> {
let mut handler = RpcHandler::new(RpcState { group, layer });
handler.add_method("echo", |_, params, _| async move { handler.add_method("echo", |params, _| async move {
Ok(HandleResult::rpc(json!(params))) Ok(HandleResult::rpc(json!(params)))
}); });
handler.add_method("account-system-info", move |_, _, _| async move { handler.add_method("add-bootstrap", |params: Vec<RpcParam>, _| async move {
Ok(HandleResult::rpc(json!(vec![addr.to_hex()]))) let socket = params[0].as_str().ok_or(RpcError::ParseError)?;
let transport = params[1].as_str().ok_or(RpcError::ParseError)?;
if let Ok(addr) = socket.parse::<SocketAddr>() {
Ok(HandleResult::network(NetworkType::Connect(
Peer::socket_transport(addr, transport),
)))
} else {
Err(RpcError::InvalidRequest)
}
}); });
handler.add_method( handler.add_method("account-list", |_, state: Arc<Global>| async move {
"add-bootstrap", let mut accounts: Vec<Vec<String>> = vec![];
|_gid, params: Vec<RpcParam>, _| async move { let group_lock = state.group.read().await;
let socket = params[0].as_str().ok_or(RpcError::ParseError)?; for (pid, account) in group_lock.list_accounts().iter() {
let transport = params[1].as_str().ok_or(RpcError::ParseError)?; accounts.push(vec![
id_to_str(pid),
if let Ok(addr) = socket.parse::<SocketAddr>() { account.name.clone(),
Ok(HandleResult::network(NetworkType::Connect( base64::encode(&account.avatar),
Peer::socket_transport(addr, transport), ]);
))) }
} else { drop(group_lock);
Err(RpcError::InvalidRequest)
} Ok(HandleResult::rpc(json!(accounts)))
}, });
);
handler.add_method(
"account-list",
|_gid, _params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let mut users: Vec<Vec<String>> = vec![];
let group_lock = state.group.read().await;
for (gid, user) in group_lock.list_users().iter() {
users.push(vec![
gid.to_hex(),
user.name.clone(),
base64::encode(&user.avatar),
]);
}
drop(group_lock);
Ok(HandleResult::rpc(json!(users)))
},
);
handler.add_method( handler.add_method(
"account-generate", "account-generate",
|_gid, params: Vec<RpcParam>, _state: Arc<RpcState>| async move { |params: Vec<RpcParam>, _state: Arc<Global>| async move {
let lang = params[0].as_i64().ok_or(RpcError::ParseError)?; let lang = params[0].as_i64().ok_or(RpcError::ParseError)?;
let language = lang_from_i64(lang); let language = lang_from_i64(lang);
let words = generate_mnemonic(language, Count::Words12); let words = generate_mnemonic(language, Count::Words12);
@ -270,7 +243,7 @@ fn new_rpc_handler(
handler.add_method( handler.add_method(
"account-create", "account-create",
|_gid, params: Vec<RpcParam>, state: Arc<RpcState>| async move { |params: Vec<RpcParam>, state: Arc<Global>| async move {
let lang = params[0].as_i64().ok_or(RpcError::ParseError)?; let lang = params[0].as_i64().ok_or(RpcError::ParseError)?;
let seed = params[1].as_str().ok_or(RpcError::ParseError)?; let seed = params[1].as_str().ok_or(RpcError::ParseError)?;
let pass = params[2].as_str().ok_or(RpcError::ParseError)?; let pass = params[2].as_str().ok_or(RpcError::ParseError)?;
@ -280,26 +253,29 @@ fn new_rpc_handler(
let avatar = params[5].as_str().ok_or(RpcError::ParseError)?; let avatar = params[5].as_str().ok_or(RpcError::ParseError)?;
let avatar_bytes = base64::decode(avatar).unwrap_or(vec![]); let avatar_bytes = base64::decode(avatar).unwrap_or(vec![]);
let (id, gid) = state let (_id, pid) = state
.group .group
.write() .write()
.await .await
.add_account(lang, seed, pass, name, lock, avatar_bytes) .add_account(
lang,
seed,
pass,
name,
lock,
avatar_bytes,
&state.base,
&state.secret,
)
.await?; .await?;
state.layer.write().await.add_running(&gid, gid, id, 0)?;
let mut results = HandleResult::rpc(json!(vec![gid.to_hex()]));
results.networks.push(NetworkType::AddGroup(gid)); // add AddGroup to TDN.
debug!("Account Logined: {}.", gid.to_hex()); Ok(HandleResult::rpc(json!(vec![id_to_str(&pid)])))
Ok(results)
}, },
); );
handler.add_method( handler.add_method(
"account-restore", "account-restore",
|_gid, params: Vec<RpcParam>, state: Arc<RpcState>| async move { |params: Vec<RpcParam>, state: Arc<Global>| async move {
let lang = params[0].as_i64().ok_or(RpcError::ParseError)?; let lang = params[0].as_i64().ok_or(RpcError::ParseError)?;
let seed = params[1].as_str().ok_or(RpcError::ParseError)?; let seed = params[1].as_str().ok_or(RpcError::ParseError)?;
let pass = params[2].as_str().ok_or(RpcError::ParseError)?; let pass = params[2].as_str().ok_or(RpcError::ParseError)?;
@ -307,60 +283,55 @@ fn new_rpc_handler(
let name = params[3].as_str().ok_or(RpcError::ParseError)?; let name = params[3].as_str().ok_or(RpcError::ParseError)?;
let lock = params[4].as_str().ok_or(RpcError::ParseError)?; let lock = params[4].as_str().ok_or(RpcError::ParseError)?;
let some_addr = PeerId::from_hex(params[5].as_str().ok_or(RpcError::ParseError)?).ok(); let (_id, pid) = state
let (id, gid) = state
.group .group
.write() .write()
.await .await
.add_account(lang, seed, pass, name, lock, vec![]) .add_account(
lang,
seed,
pass,
name,
lock,
vec![],
&state.base,
&state.secret,
)
.await?; .await?;
state.layer.write().await.add_running(&gid, gid, id, 0)?;
let mut results = HandleResult::rpc(json!(vec![gid.to_hex()]));
results.networks.push(NetworkType::AddGroup(gid)); // add AddGroup to TDN.
debug!("Account Logined: {}.", gid.to_hex());
if let Some(addr) = some_addr {
let group_lock = state.group.read().await;
let sender = group_lock.sender();
let msg = group_lock.create_message(&gid, Peer::peer(addr))?;
drop(group_lock);
tokio::spawn(async move {
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
let _ = sender.send(SendMessage::Group(gid, msg)).await;
});
}
Ok(results) // TODO auto search online account info.
Ok(HandleResult::rpc(json!(vec![id_to_str(&pid)])))
}, },
); );
handler.add_method( handler.add_method(
"account-update", "account-update",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move { |params: Vec<RpcParam>, state: Arc<Global>| async move {
let name = params[0].as_str().ok_or(RpcError::ParseError)?; let name = params[0].as_str().ok_or(RpcError::ParseError)?;
let avatar = params[1].as_str().ok_or(RpcError::ParseError)?; let avatar = params[1].as_str().ok_or(RpcError::ParseError)?;
let avatar_bytes = base64::decode(avatar).unwrap_or(vec![]); let avatar_bytes = base64::decode(avatar).unwrap_or(vec![]);
let pid = state.pid().await;
let mut group_lock = state.group.write().await; let mut group_lock = state.group.write().await;
group_lock.update_account(gid, name, avatar_bytes.clone())?; group_lock.update_account(
let user = group_lock.clone_user(&gid)?; pid,
name,
let mut results = HandleResult::new(); avatar_bytes.clone(),
group_lock.broadcast( &state.base,
&gid, &state.secret,
InnerEvent::UserInfo(name.to_owned(), avatar_bytes.clone()),
0,
0,
&mut results,
)?; )?;
drop(group_lock); drop(group_lock);
// broadcast all friends. let results = HandleResult::new();
state.layer.read().await.broadcast(user, &mut results);
// TODO broadcast to all devices.
//let user = group_lock.clone_user(&pid)?;
//group_lock.broadcast(&pid, &mut results)?;
// TODO broadcast to all layers.
//state.layer.read().await.broadcast(user, &mut results);
Ok(results) Ok(results)
}, },
@ -368,81 +339,84 @@ fn new_rpc_handler(
handler.add_method( handler.add_method(
"account-pin-check", "account-pin-check",
|_gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move { |params: Vec<RpcParam>, state: Arc<Global>| async move {
let gid = GroupId::from_hex(params[0].as_str().ok_or(RpcError::ParseError)?)?; let pid = id_from_str(params[0].as_str().ok_or(RpcError::ParseError)?)?;
let lock = params[1].as_str().ok_or(RpcError::ParseError)?; let lock = params[1].as_str().ok_or(RpcError::ParseError)?;
let res = state.group.read().await.check_lock(&gid, lock); let res = state.group.read().await.check_lock(&pid, lock);
Ok(HandleResult::rpc(json!([res]))) Ok(HandleResult::rpc(json!([res])))
}, },
); );
handler.add_method( handler.add_method(
"account-pin", "account-pin-change",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move { |params: Vec<RpcParam>, state: Arc<Global>| async move {
let old = params[0].as_str().ok_or(RpcError::ParseError)?; let old = params[0].as_str().ok_or(RpcError::ParseError)?;
let new = params[1].as_str().ok_or(RpcError::ParseError)?; let new = params[1].as_str().ok_or(RpcError::ParseError)?;
let pid = state.pid().await;
let result = HandleResult::rpc(json!([new])); let result = HandleResult::rpc(json!([new]));
state.group.write().await.pin(&gid, old, new)?; state
.group
.write()
.await
.pin(&pid, old, new, &state.base, &state.secret)?;
Ok(result) Ok(result)
}, },
); );
handler.add_method( handler.add_method(
"account-mnemonic", "account-mnemonic",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move { |params: Vec<RpcParam>, state: Arc<Global>| async move {
let lock = params[0].as_str().ok_or(RpcError::ParseError)?; let lock = params[0].as_str().ok_or(RpcError::ParseError)?;
let pid = state.pid().await;
let mnemonic = state.group.read().await.mnemonic(&gid, lock)?; let mnemonic = state
.group
.read()
.await
.mnemonic(&pid, lock, &state.secret)?;
Ok(HandleResult::rpc(json!([mnemonic]))) Ok(HandleResult::rpc(json!([mnemonic])))
}, },
); );
handler.add_method( handler.add_method(
"account-login", "account-login",
|_gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move { |params: Vec<RpcParam>, state: Arc<Global>| async move {
let ogid = GroupId::from_hex(params[0].as_str().ok_or(RpcError::ParseError)?)?; let pid = id_from_str(params[0].as_str().ok_or(RpcError::ParseError)?)?;
let me_lock = params[1].as_str().ok_or(RpcError::ParseError)?; let me_lock = params[1].as_str().ok_or(RpcError::ParseError)?;
let mut results = HandleResult::rpc(json!([ogid.to_hex()])); let mut results = HandleResult::rpc(json!([id_to_str(&pid)]));
let (id, running) = state.group.write().await.add_running(&ogid, me_lock)?; let running = state.reset(&pid, me_lock).await?;
if running { if running {
return Ok(results); return Ok(results);
} }
// add AddGroup to TDN. // TODO load all local services created by this account.
results.networks.push(NetworkType::AddGroup(ogid));
let mut layer_lock = state.layer.write().await;
layer_lock.add_running(&ogid, ogid, id, 0)?; // TODO account current state height.
// load all services layer created by this account.
// 1. group chat. // 1. group chat.
let self_addr = layer_lock.addr.clone(); // let self_addr = layer_lock.addr.clone();
let group_lock = state.group.read().await; // let group_lock = state.group.read().await;
let group_db = group_lock.group_db(&ogid)?; // let group_db = group_lock.group_db(&ogid)?;
let s_db = group_lock.session_db(&ogid)?; // let s_db = group_lock.session_db(&ogid)?;
drop(group_lock); // drop(group_lock);
let group_chats = GroupChat::local(&group_db)?; // let group_chats = GroupChat::local(&group_db)?;
for g in group_chats { // for g in group_chats {
layer_lock.add_running(&g.g_id, ogid, g.id, g.height)?; // layer_lock.add_running(&g.g_id, ogid, g.id, g.height)?;
results.networks.push(NetworkType::AddGroup(g.g_id)); // results.networks.push(NetworkType::AddGroup(g.g_id));
// 2. online group to self group onlines. // // 2. online group to self group onlines.
if let Some(session) = // if let Some(session) =
connect_session(&s_db, &SessionType::Group, &g.id, &self_addr)? // connect_session(&s_db, &SessionType::Group, &g.id, &self_addr)?
{ // {
layer_lock.running_mut(&ogid)?.check_add_online( // layer_lock.running_mut(&ogid)?.check_add_online(
g.g_id, // g.g_id,
Online::Direct(self_addr), // Online::Direct(self_addr),
session.id, // session.id,
g.id, // g.id,
)?; // )?;
} // }
} // }
drop(layer_lock); // drop(layer_lock);
debug!("Account Logined: {}.", ogid.to_hex()); debug!("Account Logined: {}.", id_to_str(&pid));
Ok(results) Ok(results)
}, },
@ -450,209 +424,152 @@ fn new_rpc_handler(
handler.add_method( handler.add_method(
"account-logout", "account-logout",
|_gid: GroupId, _params: Vec<RpcParam>, state: Arc<RpcState>| async move { |_params: Vec<RpcParam>, state: Arc<Global>| async move {
let mut results = HandleResult::new(); let mut results = HandleResult::new();
// TODO broadcast to inner-group.
let group_lock = state.group.read().await; let group_lock = state.group.read().await;
let layer_lock = state.layer.read().await;
let keys = group_lock.list_running_user();
for gid in keys {
for (fgid, addr) in layer_lock.running(&gid)?.onlines() {
// send a event that is offline.
let data = bincode::serialize(&LayerEvent::Offline(*fgid))?;
let msg = SendType::Event(0, *addr, data);
results.layers.push((gid, *fgid, msg));
}
debug!("Account Offline: {}.", gid.to_hex());
// add Remove Group to TDN.
results.networks.push(NetworkType::DelGroup(gid));
}
drop(group_lock);
drop(layer_lock);
let mut layer_lock = state.layer.write().await;
let layers = layer_lock.remove_all_running();
drop(layer_lock);
let mut group_lock = state.group.write().await;
let groups = group_lock.remove_all_running();
let sender = group_lock.sender();
drop(group_lock);
tokio::spawn(sleep_waiting_close_stable(sender, groups, layers));
Ok(results)
},
);
handler.add_method(
"account-online",
|_gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let gid = GroupId::from_hex(params[0].as_str().ok_or(RpcError::ParseError)?)?;
let mut results = HandleResult::new();
let group_lock = state.group.read().await;
let devices = group_lock.distribute_conns(&gid);
for device in devices {
results.groups.push((gid, device));
}
drop(group_lock); drop(group_lock);
debug!("Account Online: {}.", gid.to_hex());
Ok(results)
},
);
handler.add_method(
"account-offline",
|_gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let gid = GroupId::from_hex(params[0].as_str().ok_or(RpcError::ParseError)?)?;
let mut results = HandleResult::new(); // TODO broadcast to layers.
let layer_lock = state.layer.read().await; let layer_lock = state.layer.read().await;
for (fgid, addr) in layer_lock.running(&gid)?.onlines() { for (gid, sessions) in layer_lock.sessions.iter() {
// send a event that is offline. for (pid, _) in sessions {
let data = bincode::serialize(&LayerEvent::Offline(*fgid))?; // send a event that is offline.
let msg = SendType::Event(0, *addr, data); let data = bincode::serialize(&LayerEvent::Offline(*gid))?;
results.layers.push((gid, *fgid, msg)); let msg = SendType::Event(0, *pid, data);
} results.layers.push((*gid, msg));
drop(layer_lock);
let layers = state.layer.write().await.remove_running(&gid);
let mut group_lock = state.group.write().await;
let groups = group_lock.remove_running(&gid);
let sender = group_lock.sender();
drop(group_lock);
tokio::spawn(sleep_waiting_close_stable(sender, groups, layers));
debug!("Account Offline: {}.", gid.to_hex());
// add Remove Group to TDN.
results.networks.push(NetworkType::DelGroup(gid));
Ok(results)
},
);
handler.add_method(
"session-list",
|gid: GroupId, _params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let db = state.group.read().await.session_db(&gid)?;
Ok(HandleResult::rpc(session_list(Session::list(&db)?)))
},
);
handler.add_method(
"session-connect",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
let remote = GroupId::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?;
let group_lock = state.group.read().await;
let db = group_lock.session_db(&gid)?;
Session::readed(&db, &id)?;
let mut layer_lock = state.layer.write().await;
let online = layer_lock.running_mut(&gid)?.active(&remote, true);
drop(layer_lock);
if let Some(addr) = online {
return Ok(HandleResult::rpc(json!([id, addr.to_hex()])));
}
let s = Session::get(&db, &id)?;
drop(db);
let mut results = HandleResult::new();
match s.s_type {
SessionType::Chat => {
let proof = group_lock.prove_addr(&gid, &s.addr)?;
results
.layers
.push((gid, s.gid, chat_conn(proof, Peer::peer(s.addr))));
}
SessionType::Group => {
let proof = group_lock.prove_addr(&gid, &s.addr)?;
add_layer(
&mut results,
gid,
group_conn(proof, Peer::peer(s.addr), s.gid),
);
} }
_ => {}
} }
Ok(results)
},
);
handler.add_method(
"session-suspend",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
let remote = GroupId::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?;
let must = params[2].as_bool().ok_or(RpcError::ParseError)?; // if need must suspend.
let db = state.group.read().await.session_db(&gid)?;
let s = Session::get(&db, &id)?;
drop(db);
let msg = match s.s_type {
SessionType::Chat | SessionType::Group => {
let event = LayerEvent::Suspend(s.gid);
let data = bincode::serialize(&event)?;
SendType::Event(0, s.addr, data)
}
_ => {
return Ok(HandleResult::new()); // others has no online.
}
};
let mut layer_lock = state.layer.write().await;
let suspend = layer_lock.running_mut(&gid)?.suspend(&remote, true, must)?;
drop(layer_lock); drop(layer_lock);
let mut results = HandleResult::new(); debug!("Account Offline: {}.", id_to_str(&state.pid().await));
if suspend {
results.rpcs.push(json!([id]))
}
match s.s_type { //let sender = state.sender.read().await.clone();
SessionType::Chat => { state.clear().await;
results.layers.push((gid, s.gid, msg)); //tokio::spawn(sleep_waiting_close_stable(sender, groups, layers));
}
SessionType::Group => {
add_layer(&mut results, gid, msg);
}
_ => {}
}
Ok(results) Ok(results)
}, },
); );
handler.add_method( // handler.add_method(
"session-readed", // "session-list",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move { // |gid: GroupId, _params: Vec<RpcParam>, state: Arc<Global>| async move {
let id = params[0].as_i64().ok_or(RpcError::ParseError)?; // let db = state.group.read().await.session_db(&gid)?;
let db = state.group.read().await.session_db(&gid)?; // Ok(HandleResult::rpc(session_list(Session::list(&db)?)))
Session::readed(&db, &id)?; // },
Ok(HandleResult::new()) // );
},
); // handler.add_method(
// "session-connect",
handler.add_method( // |gid: GroupId, params: Vec<RpcParam>, state: Arc<Global>| async move {
"session-update", // let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move { // let remote = GroupId::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?;
let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
let is_top = params[1].as_bool().ok_or(RpcError::ParseError)?; // let group_lock = state.group.read().await;
let is_close = params[2].as_bool().ok_or(RpcError::ParseError)?; // let db = group_lock.session_db(&gid)?;
// Session::readed(&db, &id)?;
let db = state.group.read().await.session_db(&gid)?;
Session::update(&db, &id, is_top, is_close)?; // let mut layer_lock = state.layer.write().await;
Ok(HandleResult::new()) // let online = layer_lock.running_mut(&gid)?.active(&remote, true);
}, // drop(layer_lock);
); // if let Some(addr) = online {
// return Ok(HandleResult::rpc(json!([id, addr.to_hex()])));
// }
// let s = Session::get(&db, &id)?;
// drop(db);
// let mut results = HandleResult::new();
// match s.s_type {
// SessionType::Chat => {
// let proof = group_lock.prove_addr(&gid, &s.addr)?;
// results
// .layers
// .push((gid, s.gid, chat_conn(proof, Peer::peer(s.addr))));
// }
// SessionType::Group => {
// let proof = group_lock.prove_addr(&gid, &s.addr)?;
// add_layer(
// &mut results,
// gid,
// group_conn(proof, Peer::peer(s.addr), s.gid),
// );
// }
// _ => {}
// }
// Ok(results)
// },
// );
// handler.add_method(
// "session-suspend",
// |gid: GroupId, params: Vec<RpcParam>, state: Arc<Global>| async move {
// let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
// let remote = GroupId::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?;
// let must = params[2].as_bool().ok_or(RpcError::ParseError)?; // if need must suspend.
// let db = state.group.read().await.session_db(&gid)?;
// let s = Session::get(&db, &id)?;
// drop(db);
// let msg = match s.s_type {
// SessionType::Chat | SessionType::Group => {
// let event = LayerEvent::Suspend(s.gid);
// let data = bincode::serialize(&event)?;
// SendType::Event(0, s.addr, data)
// }
// _ => {
// return Ok(HandleResult::new()); // others has no online.
// }
// };
// let mut layer_lock = state.layer.write().await;
// let suspend = layer_lock.running_mut(&gid)?.suspend(&remote, true, must)?;
// drop(layer_lock);
// let mut results = HandleResult::new();
// if suspend {
// results.rpcs.push(json!([id]))
// }
// match s.s_type {
// SessionType::Chat => {
// results.layers.push((gid, s.gid, msg));
// }
// SessionType::Group => {
// add_layer(&mut results, gid, msg);
// }
// _ => {}
// }
// Ok(results)
// },
// );
// handler.add_method(
// "session-readed",
// |gid: GroupId, params: Vec<RpcParam>, state: Arc<Global>| async move {
// let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
// let db = state.group.read().await.session_db(&gid)?;
// Session::readed(&db, &id)?;
// Ok(HandleResult::new())
// },
// );
// handler.add_method(
// "session-update",
// |gid: GroupId, params: Vec<RpcParam>, state: Arc<Global>| async move {
// let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
// let is_top = params[1].as_bool().ok_or(RpcError::ParseError)?;
// let is_close = params[2].as_bool().ok_or(RpcError::ParseError)?;
// let db = state.group.read().await.session_db(&gid)?;
// Session::update(&db, &id, is_top, is_close)?;
// Ok(HandleResult::new())
// },
// );
handler handler
} }

265
src/server.rs

@ -5,7 +5,10 @@ use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use tdn::{ use tdn::{
prelude::*, prelude::*,
types::primitive::{HandleResult, Result}, types::{
message::RpcSendMessage,
primitives::{HandleResult, Result},
},
}; };
use tokio::{ use tokio::{
sync::mpsc::{error::SendError, Sender}, sync::mpsc::{error::SendError, Sender},
@ -15,14 +18,15 @@ use tokio::{
use tdn_storage::local::DStorage; use tdn_storage::local::DStorage;
use crate::account::Account; use crate::account::Account;
use crate::apps::app_layer_handle; //use crate::apps::app_layer_handle;
use crate::global::Global;
use crate::group::Group; use crate::group::Group;
use crate::layer::Layer; use crate::layer::Layer;
use crate::migrate::{main_migrate, ACCOUNT_DB}; use crate::migrate::{main_migrate, ACCOUNT_DB};
use crate::primitives::network_seeds; use crate::primitives::network_seeds;
use crate::rpc::{init_rpc, inner_rpc}; use crate::rpc::{init_rpc, inner_rpc};
pub const DEFAULT_WS_ADDR: &'static str = "127.0.0.1:8080"; pub const DEFAULT_WS_ADDR: &'static str = "127.0.0.1:7366";
pub const DEFAULT_LOG_FILE: &'static str = "esse.log.txt"; pub const DEFAULT_LOG_FILE: &'static str = "esse.log.txt";
pub static RPC_WS_UID: OnceCell<u64> = OnceCell::new(); pub static RPC_WS_UID: OnceCell<u64> = OnceCell::new();
@ -61,49 +65,54 @@ pub async fn start(db_path: String) -> Result<()> {
let account_db = DStorage::open(account_db_path, &hex::encode(&rand_secret))?; let account_db = DStorage::open(account_db_path, &hex::encode(&rand_secret))?;
let accounts = Account::all(&account_db)?; let accounts = Account::all(&account_db)?;
account_db.close()?; account_db.close()?;
let mut me: HashMap<GroupId, Account> = HashMap::new(); let mut me: HashMap<PeerId, Account> = HashMap::new();
for account in accounts { for account in accounts {
me.insert(account.gid, account); me.insert(account.pid, account);
} }
config.group_ids = me.keys().cloned().collect(); let gids: Vec<GroupId> = vec![]; // TODO add apps inject GROUP_ID
let peer_id = PeerId::default();
let (peer_id, sender, mut recver) = start_with_config(config).await?; let (_, _, p2p_config, rpc_config) = config.split();
info!("Network Peer id : {}", peer_id.to_hex()); let (tdn_send, tdn_recv) = new_send_channel();
let (self_send, mut self_recv) = new_receive_channel();
let rpc_send = start_rpc(rpc_config, self_send).await?;
let group = Arc::new(RwLock::new( let global = Arc::new(Global::init(me, tdn_send, db_path, rand_secret));
Group::init(rand_secret, sender.clone(), peer_id, me, db_path.clone()).await?,
));
let layer = Arc::new(RwLock::new(
Layer::init(db_path, peer_id, group.clone()).await?,
));
let rpc = init_rpc(peer_id, group.clone(), layer.clone()); //let peer_id = start_main(gids, p2p_config, self_send, tdn_recv, rpc_send, Some(key)).await;
//let mut group_rpcs: HashMap<u64, GroupId> = HashMap::new(); // TODO CHECK peer_id is equal.
// info!("Network Peer id : {}", peer_id.to_hex());
// let group = Arc::new(RwLock::new(
// Group::init(rand_secret, sender.clone(), peer_id, me, db_path.clone()).await?,
// ));
// let layer = Arc::new(RwLock::new(
// Layer::init(db_path, peer_id, group.clone()).await?,
// ));
let rpc = init_rpc(global.clone());
// //let mut group_rpcs: HashMap<u64, GroupId> = HashMap::new();
let mut now_rpc_uid = 0; let mut now_rpc_uid = 0;
// running session remain task. // // running session remain task.
tokio::spawn(session_remain(peer_id, layer.clone(), sender.clone())); // tokio::spawn(session_remain(peer_id, layer.clone(), sender.clone()));
while let Some(message) = recver.recv().await { while let Some(message) = self_recv.recv().await {
match message { match message {
ReceiveMessage::Group(fgid, g_msg) => { ReceiveMessage::Group(g_msg) => {
if let Ok(handle_result) = group //if let Ok(handle_result) = group.write().await.handle(g_msg, now_rpc_uid).await {
.write() //handle(handle_result, now_rpc_uid, true, &sender).await;
.await //}
.handle(fgid, g_msg, &layer, now_rpc_uid)
.await
{
handle(handle_result, now_rpc_uid, true, &sender).await;
}
} }
ReceiveMessage::Layer(fgid, tgid, l_msg) => { ReceiveMessage::Layer(fgid, l_msg) => {
if let Ok(handle_result) = app_layer_handle(&layer, fgid, tgid, l_msg).await { // if let Ok(handle_result) = app_layer_handle(&layer, fgid, tgid, l_msg).await {
handle(handle_result, now_rpc_uid, true, &sender).await; // handle(handle_result, now_rpc_uid, true, &sender).await;
} // }
} }
ReceiveMessage::Rpc(uid, params, is_ws) => { ReceiveMessage::Rpc(uid, params, is_ws) => {
if !is_ws { if !is_ws {
if inner_rpc(uid, params["method"].as_str().unwrap(), &sender) if inner_rpc(uid, params["method"].as_str().unwrap(), &global)
.await .await
.is_ok() .is_ok()
{ {
@ -117,23 +126,22 @@ pub async fn start(db_path: String) -> Result<()> {
} }
if let Ok(handle_result) = rpc.handle(params).await { if let Ok(handle_result) = rpc.handle(params).await {
handle(handle_result, uid, is_ws, &sender).await; handle(handle_result, uid, is_ws, &global, &rpc_send).await;
} }
} }
ReceiveMessage::NetworkLost => { ReceiveMessage::NetworkLost => {
sender global
.send(SendMessage::Network(NetworkType::NetworkReboot)) .send(SendMessage::Network(NetworkType::NetworkReboot))
.await .await?;
.expect("TDN channel closed"); // let t_sender = tdn_send.clone();
let t_sender = sender.clone(); // let g_conns = group.read().await.all_distribute_conns();
let g_conns = group.read().await.all_distribute_conns(); // let l_conns = layer
let l_conns = layer // .read()
.read() // .await
.await // .all_layer_conns()
.all_layer_conns() // .await
.await // .unwrap_or(HashMap::new());
.unwrap_or(HashMap::new()); // tokio::spawn(sleep_waiting_reboot(t_sender, g_conns, l_conns));
tokio::spawn(sleep_waiting_reboot(t_sender, g_conns, l_conns));
} }
} }
} }
@ -141,81 +149,87 @@ pub async fn start(db_path: String) -> Result<()> {
Ok(()) Ok(())
} }
#[inline] // #[inline]
async fn sleep_waiting_reboot( // async fn sleep_waiting_reboot(
sender: Sender<SendMessage>, // sender: Sender<SendMessage>,
groups: HashMap<GroupId, Vec<SendType>>, // groups: HashMap<GroupId, Vec<SendType>>,
layers: HashMap<GroupId, Vec<(GroupId, SendType)>>, // layers: HashMap<GroupId, Vec<(GroupId, SendType)>>,
) -> std::result::Result<(), SendError<SendMessage>> { // ) -> std::result::Result<(), SendError<SendMessage>> {
tokio::time::sleep(std::time::Duration::from_secs(10)).await; // tokio::time::sleep(std::time::Duration::from_secs(10)).await;
for (gid, conns) in groups { // for (gid, conns) in groups {
for conn in conns { // for conn in conns {
sender.send(SendMessage::Group(gid, conn)).await?; // sender.send(SendMessage::Group(gid, conn)).await?;
} // }
} // }
for (fgid, conns) in layers { // for (fgid, conns) in layers {
for (tgid, conn) in conns { // for (tgid, conn) in conns {
sender.send(SendMessage::Layer(fgid, tgid, conn)).await?; // sender.send(SendMessage::Layer(fgid, tgid, conn)).await?;
} // }
} // }
Ok(()) // Ok(())
} // }
async fn session_remain( // async fn session_remain(
self_addr: PeerId, // self_addr: PeerId,
layer: Arc<RwLock<Layer>>, // layer: Arc<RwLock<Layer>>,
sender: Sender<SendMessage>, // sender: Sender<SendMessage>,
) -> Result<()> { // ) -> Result<()> {
loop { // loop {
tokio::time::sleep(std::time::Duration::from_secs(120)).await; // tokio::time::sleep(std::time::Duration::from_secs(120)).await;
if let Some(uid) = RPC_WS_UID.get() { // if let Some(uid) = RPC_WS_UID.get() {
let mut layer_lock = layer.write().await; // let mut layer_lock = layer.write().await;
let mut rpcs = vec![]; // let mut rpcs = vec![];
let mut addrs = HashMap::new(); // let mut addrs = HashMap::new();
for (_, running) in layer_lock.runnings.iter_mut() { // for (_, running) in layer_lock.runnings.iter_mut() {
let closed = running.close_suspend(&self_addr); // let closed = running.close_suspend(&self_addr);
for (gid, addr, sid) in closed { // for (gid, addr, sid) in closed {
addrs.insert(addr, false); // addrs.insert(addr, false);
rpcs.push(crate::rpc::session_lost(gid, &sid)); // rpcs.push(crate::rpc::session_lost(gid, &sid));
} // }
} // }
drop(layer_lock); // drop(layer_lock);
let layer_lock = layer.read().await; // let layer_lock = layer.read().await;
for (_, running) in layer_lock.runnings.iter() { // for (_, running) in layer_lock.runnings.iter() {
for (addr, keep) in addrs.iter_mut() { // for (addr, keep) in addrs.iter_mut() {
if running.check_addr_online(addr) { // if running.check_addr_online(addr) {
*keep = true; // *keep = true;
} // }
} // }
} // }
drop(layer_lock); // drop(layer_lock);
for rpc in rpcs { // for rpc in rpcs {
let _ = sender.send(SendMessage::Rpc(*uid, rpc, true)).await; // let _ = sender.send(SendMessage::Rpc(*uid, rpc, true)).await;
} // }
for (addr, keep) in addrs { // for (addr, keep) in addrs {
if !keep { // if !keep {
let _ = sender // let _ = sender
.send(SendMessage::Layer( // .send(SendMessage::Layer(
GroupId::default(), // GroupId::default(),
GroupId::default(), // GroupId::default(),
SendType::Disconnect(addr), // SendType::Disconnect(addr),
)) // ))
.await; // .await;
} // }
} // }
} // }
} // }
} // }
#[inline] #[inline]
async fn handle(handle_result: HandleResult, uid: u64, is_ws: bool, sender: &Sender<SendMessage>) { async fn handle(
handle_result: HandleResult,
uid: u64,
is_ws: bool,
global: &Arc<Global>,
rpc_sender: &Sender<RpcSendMessage>,
) {
let HandleResult { let HandleResult {
mut rpcs, mut rpcs,
mut groups, mut groups,
@ -226,8 +240,8 @@ async fn handle(handle_result: HandleResult, uid: u64, is_ws: bool, sender: &Sen
loop { loop {
if rpcs.len() != 0 { if rpcs.len() != 0 {
let msg = rpcs.remove(0); let msg = rpcs.remove(0);
sender rpc_sender
.send(SendMessage::Rpc(uid, msg, is_ws)) .send(RpcSendMessage(uid, msg, is_ws))
.await .await
.expect("TDN channel closed"); .expect("TDN channel closed");
} else { } else {
@ -235,6 +249,7 @@ async fn handle(handle_result: HandleResult, uid: u64, is_ws: bool, sender: &Sen
} }
} }
let sender = global.sender.read().await;
loop { loop {
if networks.len() != 0 { if networks.len() != 0 {
let msg = networks.remove(0); let msg = networks.remove(0);
@ -249,9 +264,9 @@ async fn handle(handle_result: HandleResult, uid: u64, is_ws: bool, sender: &Sen
loop { loop {
if groups.len() != 0 { if groups.len() != 0 {
let (gid, msg) = groups.remove(0); let msg = groups.remove(0);
sender sender
.send(SendMessage::Group(gid, msg)) .send(SendMessage::Group(msg))
.await .await
.expect("TDN channel closed"); .expect("TDN channel closed");
} else { } else {
@ -261,9 +276,9 @@ async fn handle(handle_result: HandleResult, uid: u64, is_ws: bool, sender: &Sen
loop { loop {
if layers.len() != 0 { if layers.len() != 0 {
let (fgid, tgid, msg) = layers.remove(0); let (tgid, msg) = layers.remove(0);
sender sender
.send(SendMessage::Layer(fgid, tgid, msg)) .send(SendMessage::Layer(tgid, msg))
.await .await
.expect("TDN channel closed"); .expect("TDN channel closed");
} else { } else {

37
src/session.rs

@ -1,6 +1,6 @@
use esse_primitives::{id_from_str, id_to_string};
use tdn::types::{ use tdn::types::{
group::GroupId, primitives::{PeerId, Result},
primitive::{PeerId, Result},
rpc::{json, RpcParam}, rpc::{json, RpcParam},
}; };
use tdn_storage::local::{DStorage, DsValue}; use tdn_storage::local::{DStorage, DsValue};
@ -36,7 +36,6 @@ impl SessionType {
pub(crate) struct Session { pub(crate) struct Session {
pub id: i64, pub id: i64,
fid: i64, fid: i64,
pub gid: GroupId,
pub addr: PeerId, pub addr: PeerId,
pub s_type: SessionType, pub s_type: SessionType,
name: String, name: String,
@ -48,17 +47,9 @@ pub(crate) struct Session {
} }
impl Session { impl Session {
pub fn new( pub fn new(fid: i64, addr: PeerId, s_type: SessionType, name: String, datetime: i64) -> Self {
fid: i64,
gid: GroupId,
addr: PeerId,
s_type: SessionType,
name: String,
datetime: i64,
) -> Self {
Self { Self {
fid, fid,
gid,
addr, addr,
s_type, s_type,
name, name,
@ -75,8 +66,7 @@ impl Session {
json!([ json!([
self.id, self.id,
self.fid, self.fid,
self.gid.to_hex(), id_to_string(&self.addr),
self.addr.to_hex(),
self.s_type.to_int(), self.s_type.to_int(),
self.name, self.name,
self.is_top, self.is_top,
@ -96,8 +86,7 @@ impl Session {
is_top: v.pop().unwrap().as_bool(), is_top: v.pop().unwrap().as_bool(),
name: v.pop().unwrap().as_string(), name: v.pop().unwrap().as_string(),
s_type: SessionType::from_int(v.pop().unwrap().as_i64()), s_type: SessionType::from_int(v.pop().unwrap().as_i64()),
addr: PeerId::from_hex(v.pop().unwrap().as_str()).unwrap_or(PeerId::default()), addr: id_from_str(v.pop().unwrap().as_str()).unwrap_or(PeerId::default()),
gid: GroupId::from_hex(v.pop().unwrap().as_str()).unwrap_or(GroupId::default()),
fid: v.pop().unwrap().as_i64(), fid: v.pop().unwrap().as_i64(),
id: v.pop().unwrap().as_i64(), id: v.pop().unwrap().as_i64(),
} }
@ -113,19 +102,17 @@ impl Session {
let id = unique_check.pop().unwrap().pop().unwrap().as_i64(); let id = unique_check.pop().unwrap().pop().unwrap().as_i64();
self.id = id; self.id = id;
let sql = format!("UPDATE sessions SET gid = '{}', addr='{}', name = '{}', is_top = '{}', is_close = false WHERE id = {}", let sql = format!("UPDATE sessions SET addr='{}', name = '{}', is_top = '{}', is_close = false WHERE id = {}",
self.gid.to_hex(), id_to_string(&self.addr),
self.addr.to_hex(),
self.name, self.name,
self.is_top, self.is_top,
self.id, self.id,
); );
db.update(&sql)?; db.update(&sql)?;
} else { } else {
let sql = format!("INSERT INTO sessions (fid, gid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES ({}, '{}', '{}', {}, '{}', {}, {}, {}, '{}', {})", let sql = format!("INSERT INTO sessions (fid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES ({}, '{}', {}, '{}', {}, {}, {}, '{}', {})",
self.fid, self.fid,
self.gid.to_hex(), id_to_string(&self.addr),
self.addr.to_hex(),
self.s_type.to_int(), self.s_type.to_int(),
self.name, self.name,
self.is_top, self.is_top,
@ -142,7 +129,7 @@ impl Session {
} }
pub fn get(db: &DStorage, id: &i64) -> Result<Session> { pub fn get(db: &DStorage, id: &i64) -> Result<Session> {
let sql = format!("SELECT id, fid, gid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE id = {}", id); let sql = format!("SELECT id, fid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE id = {}", id);
let mut matrix = db.query(&sql)?; let mut matrix = db.query(&sql)?;
if matrix.len() > 0 { if matrix.len() > 0 {
Ok(Session::from_values(matrix.pop().unwrap())) // safe unwrap() Ok(Session::from_values(matrix.pop().unwrap())) // safe unwrap()
@ -152,7 +139,7 @@ impl Session {
} }
pub fn list(db: &DStorage) -> Result<Vec<Session>> { pub fn list(db: &DStorage) -> Result<Vec<Session>> {
let matrix = db.query("SELECT id, fid, gid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions ORDER BY last_datetime DESC")?; let matrix = db.query("SELECT id, fid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions ORDER BY last_datetime DESC")?;
let mut sessions = vec![]; let mut sessions = vec![];
for values in matrix { for values in matrix {
sessions.push(Session::from_values(values)); sessions.push(Session::from_values(values));
@ -268,7 +255,7 @@ pub(crate) fn connect_session(
fid: &i64, fid: &i64,
addr: &PeerId, addr: &PeerId,
) -> Result<Option<Session>> { ) -> Result<Option<Session>> {
let sql = format!("SELECT id, fid, gid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE s_type = {} AND fid = {}", s_type.to_int(), fid); let sql = format!("SELECT id, fid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE s_type = {} AND fid = {}", s_type.to_int(), fid);
let mut matrix = db.query(&sql)?; let mut matrix = db.query(&sql)?;
if matrix.len() > 0 { if matrix.len() > 0 {

106
src/storage.rs

@ -1,12 +1,17 @@
use esse_primitives::id_to_str;
use image::{load_from_memory, DynamicImage, GenericImageView}; use image::{load_from_memory, DynamicImage, GenericImageView};
use rand::{distributions::Alphanumeric, thread_rng, Rng}; use rand::{distributions::Alphanumeric, thread_rng, Rng};
use std::path::PathBuf; use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use tdn::types::primitives::{PeerId, Result};
use tdn_storage::local::DStorage;
use tokio::fs; use tokio::fs;
use tdn::types::{group::GroupId, primitive::Result};
use crate::migrate::account_init_migrate; use crate::migrate::account_init_migrate;
use crate::migrate::{
ACCOUNT_DB, CHAT_DB, CLOUD_DB, CONSENSUS_DB, DAO_DB, DOMAIN_DB, FILE_DB, GROUP_DB, JARVIS_DB,
SERVICE_DB, SESSION_DB, WALLET_DB,
};
const FILES_DIR: &'static str = "files"; const FILES_DIR: &'static str = "files";
const IMAGE_DIR: &'static str = "images"; const IMAGE_DIR: &'static str = "images";
@ -56,11 +61,11 @@ pub(crate) async fn read_file(base: &PathBuf) -> Result<Vec<u8>> {
pub(crate) async fn copy_file( pub(crate) async fn copy_file(
target: &PathBuf, target: &PathBuf,
base: &PathBuf, base: &PathBuf,
gid: &GroupId, pid: &PeerId,
name: &str, name: &str,
) -> Result<()> { ) -> Result<()> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(FILES_DIR); path.push(FILES_DIR);
path.push(name); path.push(name);
fs::copy(target, path).await?; fs::copy(target, path).await?;
@ -69,12 +74,12 @@ pub(crate) async fn copy_file(
pub(crate) async fn write_file( pub(crate) async fn write_file(
base: &PathBuf, base: &PathBuf,
gid: &GroupId, pid: &PeerId,
name: &str, name: &str,
bytes: &[u8], bytes: &[u8],
) -> Result<String> { ) -> Result<String> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(FILES_DIR); path.push(FILES_DIR);
path.push(name); path.push(name);
fs::write(path, bytes).await?; fs::write(path, bytes).await?;
@ -83,12 +88,12 @@ pub(crate) async fn write_file(
pub(crate) fn write_file_sync( pub(crate) fn write_file_sync(
base: &PathBuf, base: &PathBuf,
gid: &GroupId, pid: &PeerId,
name: &str, name: &str,
bytes: Vec<u8>, bytes: Vec<u8>,
) -> Result<String> { ) -> Result<String> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(FILES_DIR); path.push(FILES_DIR);
path.push(name); path.push(name);
tokio::spawn(async move { fs::write(path, bytes).await }); tokio::spawn(async move { fs::write(path, bytes).await });
@ -96,9 +101,9 @@ pub(crate) fn write_file_sync(
Ok(name.to_owned()) Ok(name.to_owned())
} }
pub(crate) async fn read_db_file(base: &PathBuf, gid: &GroupId, name: &str) -> Result<Vec<u8>> { pub(crate) async fn read_db_file(base: &PathBuf, pid: &PeerId, name: &str) -> Result<Vec<u8>> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(FILES_DIR); path.push(FILES_DIR);
path.push(name); path.push(name);
if path.exists() { if path.exists() {
@ -108,9 +113,9 @@ pub(crate) async fn read_db_file(base: &PathBuf, gid: &GroupId, name: &str) -> R
} }
} }
pub(crate) async fn read_image(base: &PathBuf, gid: &GroupId, name: &str) -> Result<Vec<u8>> { pub(crate) async fn read_image(base: &PathBuf, pid: &PeerId, name: &str) -> Result<Vec<u8>> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(IMAGE_DIR); path.push(IMAGE_DIR);
path.push(name); path.push(name);
if path.exists() { if path.exists() {
@ -143,9 +148,9 @@ fn image_thumb(bytes: &[u8]) -> Result<DynamicImage> {
} }
} }
pub(crate) fn write_image_sync(base: &PathBuf, gid: &GroupId, bytes: Vec<u8>) -> Result<String> { pub(crate) fn write_image_sync(base: &PathBuf, pid: &PeerId, bytes: Vec<u8>) -> Result<String> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
let thumb = image_thumb(&bytes)?; let thumb = image_thumb(&bytes)?;
let name = image_name(); let name = image_name();
@ -164,9 +169,9 @@ pub(crate) fn write_image_sync(base: &PathBuf, gid: &GroupId, bytes: Vec<u8>) ->
Ok(name) Ok(name)
} }
pub(crate) async fn write_image(base: &PathBuf, gid: &GroupId, bytes: &[u8]) -> Result<String> { pub(crate) async fn write_image(base: &PathBuf, pid: &PeerId, bytes: &[u8]) -> Result<String> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
let thumb = image_thumb(bytes)?; let thumb = image_thumb(bytes)?;
let name = image_name(); let name = image_name();
@ -186,19 +191,15 @@ pub(crate) async fn write_image(base: &PathBuf, gid: &GroupId, bytes: &[u8]) ->
} }
#[inline] #[inline]
fn avatar_png(gid: &GroupId) -> String { fn avatar_png(pid: &PeerId) -> String {
let mut gs = gid.to_hex(); let mut gs = id_to_str(pid);
gs.push_str(".png"); gs.push_str(".png");
gs gs
} }
pub(crate) async fn read_avatar( pub(crate) async fn read_avatar(base: &PathBuf, pid: &PeerId, remote: &PeerId) -> Result<Vec<u8>> {
base: &PathBuf,
gid: &GroupId,
remote: &GroupId,
) -> Result<Vec<u8>> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(AVATAR_DIR); path.push(AVATAR_DIR);
path.push(avatar_png(remote)); path.push(avatar_png(remote));
if path.exists() { if path.exists() {
@ -208,9 +209,9 @@ pub(crate) async fn read_avatar(
} }
} }
pub(crate) fn read_avatar_sync(base: &PathBuf, gid: &GroupId, remote: &GroupId) -> Result<Vec<u8>> { pub(crate) fn read_avatar_sync(base: &PathBuf, pid: &PeerId, remote: &PeerId) -> Result<Vec<u8>> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(AVATAR_DIR); path.push(AVATAR_DIR);
path.push(avatar_png(remote)); path.push(avatar_png(remote));
if path.exists() { if path.exists() {
@ -222,15 +223,15 @@ pub(crate) fn read_avatar_sync(base: &PathBuf, gid: &GroupId, remote: &GroupId)
pub(crate) async fn write_avatar( pub(crate) async fn write_avatar(
base: &PathBuf, base: &PathBuf,
gid: &GroupId, pid: &PeerId,
remote: &GroupId, remote: &PeerId,
bytes: &[u8], bytes: &[u8],
) -> Result<()> { ) -> Result<()> {
if bytes.len() < 1 { if bytes.len() < 1 {
return Ok(()); return Ok(());
} }
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(AVATAR_DIR); path.push(AVATAR_DIR);
path.push(avatar_png(remote)); path.push(avatar_png(remote));
Ok(fs::write(path, bytes).await?) Ok(fs::write(path, bytes).await?)
@ -238,24 +239,24 @@ pub(crate) async fn write_avatar(
pub(crate) fn write_avatar_sync( pub(crate) fn write_avatar_sync(
base: &PathBuf, base: &PathBuf,
gid: &GroupId, pid: &PeerId,
remote: &GroupId, remote: &PeerId,
bytes: Vec<u8>, bytes: Vec<u8>,
) -> Result<()> { ) -> Result<()> {
if bytes.len() < 1 { if bytes.len() < 1 {
return Ok(()); return Ok(());
} }
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(AVATAR_DIR); path.push(AVATAR_DIR);
path.push(avatar_png(remote)); path.push(avatar_png(remote));
tokio::spawn(async move { fs::write(path, bytes).await }); tokio::spawn(async move { fs::write(path, bytes).await });
Ok(()) Ok(())
} }
pub(crate) async fn delete_avatar(base: &PathBuf, gid: &GroupId, remote: &GroupId) -> Result<()> { pub(crate) async fn delete_avatar(base: &PathBuf, pid: &PeerId, remote: &PeerId) -> Result<()> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(AVATAR_DIR); path.push(AVATAR_DIR);
path.push(avatar_png(remote)); path.push(avatar_png(remote));
if path.exists() { if path.exists() {
@ -265,9 +266,9 @@ pub(crate) async fn delete_avatar(base: &PathBuf, gid: &GroupId, remote: &GroupI
} }
} }
pub(crate) fn delete_avatar_sync(base: &PathBuf, gid: &GroupId, remote: &GroupId) -> Result<()> { pub(crate) fn delete_avatar_sync(base: &PathBuf, pid: &PeerId, remote: &PeerId) -> Result<()> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(AVATAR_DIR); path.push(AVATAR_DIR);
path.push(avatar_png(remote)); path.push(avatar_png(remote));
if path.exists() { if path.exists() {
@ -276,9 +277,9 @@ pub(crate) fn delete_avatar_sync(base: &PathBuf, gid: &GroupId, remote: &GroupId
Ok(()) Ok(())
} }
pub(crate) async fn read_record(base: &PathBuf, gid: &GroupId, name: &str) -> Result<Vec<u8>> { pub(crate) async fn read_record(base: &PathBuf, pid: &PeerId, name: &str) -> Result<Vec<u8>> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(RECORD_DIR); path.push(RECORD_DIR);
path.push(name); path.push(name);
if path.exists() { if path.exists() {
@ -290,7 +291,7 @@ pub(crate) async fn read_record(base: &PathBuf, gid: &GroupId, name: &str) -> Re
pub(crate) fn write_record_sync( pub(crate) fn write_record_sync(
base: &PathBuf, base: &PathBuf,
gid: &GroupId, pid: &PeerId,
t: u32, t: u32,
bytes: Vec<u8>, bytes: Vec<u8>,
) -> Result<String> { ) -> Result<String> {
@ -301,7 +302,7 @@ pub(crate) fn write_record_sync(
.unwrap_or(0u128); .unwrap_or(0u128);
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(RECORD_DIR); path.push(RECORD_DIR);
path.push(format!("{}.m4a", datetime)); path.push(format!("{}.m4a", datetime));
tokio::spawn(async move { fs::write(path, bytes).await }); tokio::spawn(async move { fs::write(path, bytes).await });
@ -309,27 +310,40 @@ pub(crate) fn write_record_sync(
Ok(format!("{}_{}.m4a", t, datetime)) Ok(format!("{}_{}.m4a", t, datetime))
} }
pub(crate) async fn _delete_record(base: &PathBuf, gid: &GroupId, name: &str) -> Result<()> { pub(crate) async fn _delete_record(base: &PathBuf, pid: &PeerId, name: &str) -> Result<()> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(RECORD_DIR); path.push(RECORD_DIR);
path.push(name); path.push(name);
Ok(fs::remove_file(path).await?) Ok(fs::remove_file(path).await?)
} }
pub(crate) fn _write_emoji(base: &PathBuf, gid: &GroupId) -> Result<()> { pub(crate) fn _write_emoji(base: &PathBuf, pid: &PeerId) -> Result<()> {
let mut path = base.clone(); let mut path = base.clone();
path.push(gid.to_hex()); path.push(id_to_str(pid));
path.push(EMOJI_DIR); path.push(EMOJI_DIR);
Ok(()) Ok(())
} }
/// account independent db and storage directory. /// account independent db and storage directory.
pub(crate) async fn account_init(base: &PathBuf, key: &str, gid: &GroupId) -> Result<()> { pub(crate) async fn account_init(base: &PathBuf, key: &str, pid: &PeerId) -> Result<()> {
let mut db_path = base.clone(); let mut db_path = base.clone();
db_path.push(gid.to_hex()); db_path.push(id_to_str(pid));
init_local_files(&db_path).await?; init_local_files(&db_path).await?;
// Inner Database. // Inner Database.
account_init_migrate(&db_path, key) account_init_migrate(&db_path, key)
} }
pub(crate) fn account_db(base: &PathBuf, secret: &[u8]) -> Result<DStorage> {
let mut db_path = base.clone();
db_path.push(ACCOUNT_DB);
DStorage::open(db_path, &hex::encode(secret))
}
pub(crate) fn consensus_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result<DStorage> {
let mut db_path = base.clone();
db_path.push(id_to_str(pid));
db_path.push(CONSENSUS_DB);
DStorage::open(db_path, db_key)
}

1
types/cloud/Cargo.toml

@ -12,4 +12,3 @@ license = "MIT/Apache-2.0"
[dependencies] [dependencies]
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
tdn_types = { version = "0.7", default-features = false } tdn_types = { version = "0.7", default-features = false }
tdn_did = { version = "0.7", default-features = false }

5
types/cloud/src/lib.rs

@ -1,5 +1,4 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tdn_did::Proof;
use tdn_types::group::GroupId; use tdn_types::group::GroupId;
/// Personal data cloud service default TDN GROUP ID. /// Personal data cloud service default TDN GROUP ID.
@ -7,11 +6,11 @@ pub const CLOUD_ID: GroupId = 5;
/// ESSE service to peer layer Event. /// ESSE service to peer layer Event.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct LayerServerEvent(pub ServerEvent, pub Proof); pub struct LayerServerEvent(pub ServerEvent);
/// ESSE peer to layer Event. /// ESSE peer to layer Event.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct LayerPeerEvent(pub PeerEvent, pub Proof); pub struct LayerPeerEvent(pub PeerEvent);
/// ESSE service to peer Event. /// ESSE service to peer Event.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]

15
types/dao/src/lib.rs

@ -1,5 +1,4 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tdn_did::Proof;
use tdn_types::{group::GroupId, primitives::PeerId}; use tdn_types::{group::GroupId, primitives::PeerId};
use chat_types::NetworkMessage; use chat_types::NetworkMessage;
@ -91,10 +90,10 @@ pub struct LayerResult(pub DaoId, pub i64);
pub enum ConnectProof { pub enum ConnectProof {
/// when is joined in group chat, can only use had to join (connect). /// when is joined in group chat, can only use had to join (connect).
/// params: proof. /// params: proof.
Common(Proof), Common,
/// zero-knowledge-proof. not has account id. /// zero-knowledge-proof. not has account id.
/// verify(proof, key_hash, current_peer_addr). /// verify(proof, key_hash, current_peer_addr).
Zkp(Proof), // TODO MOCK-PROOF Zkp, // TODO MOCK-PROOF
} }
/// Dao chat join proof. /// Dao chat join proof.
@ -104,11 +103,11 @@ pub enum JoinProof {
/// params: member name, member avatar. /// params: member name, member avatar.
Open(String, Vec<u8>), Open(String, Vec<u8>),
/// when is invate, it will take group_manager's proof for invate. /// when is invate, it will take group_manager's proof for invate.
/// params: invite_by_account, invite_proof, member name, member avatar. /// params: invite_by_account, member name, member avatar.
Invite(PeerId, Proof, String, Vec<u8>), Invite(PeerId, String, Vec<u8>),
/// zero-knowledge-proof. not has account id. /// zero-knowledge-proof. not has account id.
/// verify(proof, key_hash, current_peer_addr). /// verify(proof, key_hash, current_peer_addr).
Zkp(Proof), // TODO MOCK-PROOF Zkp, // TODO MOCK-PROOF
} }
/// check result type. /// check result type.
@ -150,8 +149,8 @@ pub enum LayerEvent {
/// params: check type, provider name, remain, supported_group_types. /// params: check type, provider name, remain, supported_group_types.
CheckResult(CheckType, String, i64, Vec<GroupType>), CheckResult(CheckType, String, i64, Vec<GroupType>),
/// create a Group Chat. /// create a Group Chat.
/// params: group_info, proof. /// params: group_info.
Create(DaoInfo, Proof), Create(DaoInfo),
/// result create group success. /// result create group success.
/// params: Group ID, is_ok. /// params: Group ID, is_ok.
CreateResult(DaoId, bool), CreateResult(DaoId, bool),

1
types/domain/Cargo.toml

@ -12,4 +12,3 @@ license = "MIT/Apache-2.0"
[dependencies] [dependencies]
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
tdn_types = { version = "0.7", default-features = false } tdn_types = { version = "0.7", default-features = false }
tdn_did = { version = "0.7", default-features = false }

13
types/domain/src/lib.rs

@ -1,5 +1,4 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tdn_did::Proof;
use tdn_types::{group::GroupId, primitives::PeerId}; use tdn_types::{group::GroupId, primitives::PeerId};
// Same ID can has many name !. // Same ID can has many name !.
@ -7,17 +6,9 @@ use tdn_types::{group::GroupId, primitives::PeerId};
/// Group chat app(service) default TDN GROUP ID. /// Group chat app(service) default TDN GROUP ID.
pub const DOMAIN_ID: GroupId = 4; pub const DOMAIN_ID: GroupId = 4;
/// ESSE domain service layer Event.
#[derive(Serialize, Deserialize)]
pub struct LayerServerEvent(pub ServerEvent, pub Proof);
/// ESSE domain service layer Event.
#[derive(Serialize, Deserialize)]
pub struct LayerPeerEvent(pub PeerEvent, pub Proof);
/// ESSE domain service to peer layer Event. /// ESSE domain service to peer layer Event.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub enum ServerEvent { pub enum LayerServerEvent {
/// check result status. /// check result status.
/// params: provider name, is support request proxy. /// params: provider name, is support request proxy.
Status(String, bool), Status(String, bool),
@ -42,7 +33,7 @@ pub enum ServerEvent {
/// ESSE domain peer to service layer Event. /// ESSE domain peer to service layer Event.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub enum PeerEvent { pub enum LayerPeerEvent {
/// check service status is ok. /// check service status is ok.
Check, Check,
/// register new unique identity to service. /// register new unique identity to service.

1
types/group/Cargo.toml

@ -13,4 +13,3 @@ license = "MIT/Apache-2.0"
chat_types = { path = "../chat", version = "0.1" } chat_types = { path = "../chat", version = "0.1" }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
tdn_types = { version = "0.7", default-features = false } tdn_types = { version = "0.7", default-features = false }
tdn_did = { version = "0.7", default-features = false }

5
types/group/src/lib.rs

@ -1,5 +1,4 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tdn_did::Proof;
use tdn_types::{group::GroupId, primitives::PeerId}; use tdn_types::{group::GroupId, primitives::PeerId};
use chat_types::NetworkMessage; use chat_types::NetworkMessage;
@ -11,9 +10,9 @@ pub const GROUP_CHAT_ID: GroupId = 2;
pub type GroupChatId = u64; pub type GroupChatId = u64;
/// Group chat connect data structure. /// Group chat connect data structure.
/// params: Group Chat ID, join_proof. /// params: Group Chat ID.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct LayerConnect(pub GroupChatId, pub Proof); pub struct LayerConnect(pub GroupChatId);
/// Group chat connect success result data structure. /// Group chat connect success result data structure.
/// params: Group ID, group name, group current height. /// params: Group ID, group name, group current height.

4
types/primitives/src/lib.rs

@ -77,11 +77,11 @@ pub mod bs32 {
use tdn_types::primitives::{new_io_error, PeerId, PEER_ID_LENGTH}; use tdn_types::primitives::{new_io_error, PeerId, PEER_ID_LENGTH};
pub fn id_to_string(peer: &PeerId) -> String { pub fn id_to_str(peer: &PeerId) -> String {
bs32::encode(&peer.0) bs32::encode(&peer.0)
} }
pub fn id_from_string(s: &str) -> std::io::Result<PeerId> { pub fn id_from_str(s: &str) -> std::io::Result<PeerId> {
let data = bs32::decode(s).ok_or(new_io_error("id from string is failure."))?; let data = bs32::decode(s).ok_or(new_io_error("id from string is failure."))?;
if data.len() != PEER_ID_LENGTH { if data.len() != PEER_ID_LENGTH {
return Err(new_io_error("id from string is failure.")); return Err(new_io_error("id from string is failure."));

9
windows/flutter/generated_plugin_registrant.cc

@ -7,14 +7,17 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <esse_core/esse_core_plugin.h> #include <esse_core/esse_core_plugin.h>
#include <file_selector_windows/file_selector_plugin.h> #include <file_selector_windows/file_selector_windows.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
EsseCorePluginRegisterWithRegistrar( EsseCorePluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("EsseCorePlugin")); registry->GetRegistrarForPlugin("EsseCorePlugin"));
FileSelectorPluginRegisterWithRegistrar( FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorPlugin")); registry->GetRegistrarForPlugin("FileSelectorWindows"));
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows")); registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

1
windows/flutter/generated_plugins.cmake

@ -5,6 +5,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
esse_core esse_core
file_selector_windows file_selector_windows
permission_handler_windows
url_launcher_windows url_launcher_windows
) )

Loading…
Cancel
Save