Less warnings & Speeeeed!!

This commit is contained in:
Alex Emmet 2025-11-05 09:09:06 +01:00
commit 42cfada4a7
22 changed files with 312 additions and 403 deletions

View file

@ -51,7 +51,7 @@ pub async fn get_uuid(username: &str) -> Option<Uuid> {
let client = client(); let client = client();
let res = client.get(&url).send().await.ok()?; let res = client.get(&url).send().await.ok()?;
let json = res.text().await.ok()?; let json = res.text().await.ok()?;
let mut cv = CommunicationValue::from_json(&json); let cv = CommunicationValue::from_json(&json);
if !cv.is_type(CommunicationType::success) { if !cv.is_type(CommunicationType::success) {
return None; return None;
} }
@ -64,7 +64,7 @@ pub async fn get_user(user_id: Uuid) -> Option<AuthUser> {
let res = client.get(&url).send().await.ok()?; let res = client.get(&url).send().await.ok()?;
let json = res.text().await.ok()?; let json = res.text().await.ok()?;
let mut cv = CommunicationValue::from_json(&json); let cv = CommunicationValue::from_json(&json);
if cv.comm_type != CommunicationType::success { if cv.comm_type != CommunicationType::success {
return None; return None;
} }
@ -103,7 +103,7 @@ pub async fn get_register() -> Option<Uuid> {
let res = client.get(&url).send().await.ok()?; let res = client.get(&url).send().await.ok()?;
let json = res.text().await.ok()?; let json = res.text().await.ok()?;
let mut cv = CommunicationValue::from_json(&json); let cv = CommunicationValue::from_json(&json);
Uuid::parse_str(&*cv.get_data(DataTypes::user_id).unwrap().to_string()).ok() Uuid::parse_str(&*cv.get_data(DataTypes::user_id).unwrap().to_string()).ok()
} }

View file

@ -4,16 +4,8 @@ use aes_gcm::{
aead::{Aead, KeyInit, OsRng}, aead::{Aead, KeyInit, OsRng},
}; };
use base64::{Engine as _, engine::general_purpose::STANDARD}; use base64::{Engine as _, engine::general_purpose::STANDARD};
use base64::{decode as b64_decode, encode as b64_encode};
use hex;
use json::JsonValue;
use once_cell::sync::Lazy;
use rand::Rng;
use rand_core::RngCore; use rand_core::RngCore;
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use std::io;
use std::sync::Mutex;
use uuid::Uuid;
use x448::{PublicKey, Secret, SharedSecret}; // from the `x448` crate use x448::{PublicKey, Secret, SharedSecret}; // from the `x448` crate
/// Errors for crypto operations /// Errors for crypto operations
@ -47,20 +39,20 @@ pub fn generate_keypair() -> KeyPair {
} }
pub fn public_key_to_base64(pubkey: &PublicKey) -> String { pub fn public_key_to_base64(pubkey: &PublicKey) -> String {
b64_encode(pubkey.as_bytes().as_ref()) STANDARD.encode(pubkey.as_bytes().as_ref())
} }
pub fn secret_key_to_base64(secret: &Secret) -> String { pub fn secret_key_to_base64(secret: &Secret) -> String {
b64_encode(secret.as_bytes().as_ref()) STANDARD.encode(secret.as_bytes().as_ref())
} }
pub fn load_public_key(base64_pub: &str) -> Option<PublicKey> { pub fn load_public_key(base64_pub: &str) -> Option<PublicKey> {
let bytes = b64_decode(base64_pub).unwrap(); let bytes = STANDARD.decode(base64_pub).unwrap();
PublicKey::from_bytes(&bytes) PublicKey::from_bytes(&bytes)
} }
pub fn load_secret_key(base64_secret: &str) -> Option<Secret> { pub fn load_secret_key(base64_secret: &str) -> Option<Secret> {
let bytes = b64_decode(base64_secret).unwrap(); let bytes = STANDARD.decode(base64_secret).unwrap();
Secret::from_bytes(&bytes) Secret::from_bytes(&bytes)
} }
@ -95,7 +87,7 @@ pub fn encrypt(
let mut out = Vec::with_capacity(nonce_bytes.len() + ciphertext.len()); let mut out = Vec::with_capacity(nonce_bytes.len() + ciphertext.len());
out.extend_from_slice(&nonce_bytes); out.extend_from_slice(&nonce_bytes);
out.extend_from_slice(&ciphertext); out.extend_from_slice(&ciphertext);
Ok(b64_encode(&out)) Ok(STANDARD.encode(&out))
} }
pub fn decrypt( pub fn decrypt(
@ -111,7 +103,7 @@ pub fn decrypt(
let key_bytes = derive_aes_key(&shared); let key_bytes = derive_aes_key(&shared);
let cipher = Aes256Gcm::new_from_slice(&key_bytes).expect("Key length should be correct"); let cipher = Aes256Gcm::new_from_slice(&key_bytes).expect("Key length should be correct");
let encrypted = b64_decode(encrypted_base64)?; let encrypted = STANDARD.decode(encrypted_base64)?;
if encrypted.len() < 12 { if encrypted.len() < 12 {
return Err(CryptoError::DecryptionError(aes_gcm::Error)); return Err(CryptoError::DecryptionError(aes_gcm::Error));
} }

View file

@ -1,7 +1,5 @@
use crate::communities::interactables::category::Category; use crate::communities::interactables::category::Category;
use crate::communities::interactables::registry; use crate::communities::interactables::registry;
use crate::communities::interactables::text_chat::TextChat;
use crate::communities::interactables::voice_chat::VoiceChat;
use crate::communities::{ use crate::communities::{
community_connection::CommunityConnection, interactables::interactable::Interactable, community_connection::CommunityConnection, interactables::interactable::Interactable,
}; };
@ -12,8 +10,6 @@ use json::JsonValue;
use json::object::Object; use json::object::Object;
use rand::RngCore; use rand::RngCore;
use rand_core::OsRng; use rand_core::OsRng;
use ratatui::text;
use serde::de::value::StringDeserializer;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::RwLock; use tokio::sync::RwLock;
@ -127,7 +123,7 @@ impl Community {
cv: &CommunicationValue, cv: &CommunicationValue,
) -> CommunicationValue { ) -> CommunicationValue {
if path.is_empty() { if path.is_empty() {
let mut target_interactables = &self.interactables.read().await.clone(); let target_interactables = &self.interactables.read().await.clone();
for interactable in target_interactables.iter() { for interactable in target_interactables.iter() {
if interactable.get_name() == name { if interactable.get_name() == name {
if interactable.get_codec() == "category" { if interactable.get_codec() == "category" {
@ -183,10 +179,10 @@ impl Community {
let mut permissions = JsonValue::new_array(); let mut permissions = JsonValue::new_array();
for perm in self.permissions.get(user).unwrap() { for perm in self.permissions.get(user).unwrap() {
permissions.push(perm.to_string()); if let Ok(_) = permissions.push(perm.to_string()) {}
} }
data.insert("permissions", permissions); if let Ok(_) = data.insert("permissions", permissions) {}
user_data.insert(&user.to_string(), data); user_data.insert(&user.to_string(), data);
} }
file_util::save_file( file_util::save_file(
@ -213,7 +209,7 @@ pub async fn load(name: &String) -> Option<Arc<Community>> {
let (str, json): (&str, &JsonValue) = user; let (str, json): (&str, &JsonValue) = user;
let perms_j = &json["permissions"]; let perms_j = &json["permissions"];
let perms = Vec::new(); let perms = Vec::new();
for i in perms_j.entries() { for _ in perms_j.entries() {
// let perm_j = i.as_str().unwrap(); // let perm_j = i.as_str().unwrap();
// perms.push(perm_j.to_string()); // perms.push(perm_j.to_string());
} }
@ -225,11 +221,12 @@ pub async fn load(name: &String) -> Option<Arc<Community>> {
} }
let role_data = file_util::load_file(&format!("communities/{}/", name), "roles.json"); let role_data = file_util::load_file(&format!("communities/{}/", name), "roles.json");
if let Ok(user_json) = json::parse(&role_data) { let roles: HashMap<String, Vec<String>> = HashMap::new();
if let Ok(_) = json::parse(&role_data) {
// Fill roles
} else { } else {
return None; return None;
}; };
let mut roles: HashMap<String, Vec<String>> = HashMap::new();
let community = Community { let community = Community {
name: json_content["name"].as_str().unwrap().to_string(), name: json_content["name"].as_str().unwrap().to_string(),
@ -266,15 +263,5 @@ pub async fn load(name: &String) -> Option<Arc<Community>> {
comarc.add_interactable(Arc::new(interactable)).await; comarc.add_interactable(Arc::new(interactable)).await;
} }
} }
let mut text_chat: TextChat = TextChat::new();
text_chat.load(
comarc.clone(),
String::new(),
String::from("a"),
&JsonValue::Null,
);
comarc.add_interactable(Arc::new(Box::new(text_chat))).await;
Some(comarc) Some(comarc)
} }

View file

@ -8,7 +8,6 @@ use base64::{Engine as _, engine::general_purpose::STANDARD};
use futures::SinkExt; use futures::SinkExt;
use hkdf::Hkdf; use hkdf::Hkdf;
use json::JsonValue; use json::JsonValue;
use json::object::Object;
use rand::{Rng, distributions::Alphanumeric}; use rand::{Rng, distributions::Alphanumeric};
use sha2::Sha256; use sha2::Sha256;
use std::sync::Arc; use std::sync::Arc;
@ -61,7 +60,8 @@ impl CommunityConnection {
} }
pub async fn handle_message(self: Arc<Self>, message: String) { pub async fn handle_message(self: Arc<Self>, message: String) {
let cv = CommunicationValue::from_json(&message); let cv =
CommunicationValue::from_json(&message).with_sender(self.get_user_id().await.unwrap());
if cv.is_type(CommunicationType::identification) && !self.is_identified().await { if cv.is_type(CommunicationType::identification) && !self.is_identified().await {
self.handle_identification(cv).await; self.handle_identification(cv).await;
@ -394,7 +394,7 @@ impl CommunityConnection {
} }
pub async fn handle_close(&self) { pub async fn handle_close(&self) {
if self.is_identified().await { if self.is_identified().await {
if let Some(user_id) = self.get_user_id().await { if let Some(_) = self.get_user_id().await {
todo!(); todo!();
} }
} }

View file

@ -5,7 +5,6 @@ use once_cell::sync::Lazy;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use uuid::Uuid;
pub static COMMUNITY_REGISTRY: Lazy<Arc<Mutex<HashMap<String, Arc<Community>>>>> = pub static COMMUNITY_REGISTRY: Lazy<Arc<Mutex<HashMap<String, Arc<Community>>>>> =
Lazy::new(|| Arc::new(Mutex::new(HashMap::new()))); Lazy::new(|| Arc::new(Mutex::new(HashMap::new())));

View file

@ -1,6 +1,4 @@
use crate::communities::{ use crate::communities::{community_connection::CommunityConnection, community_manager};
community::Community, community_connection::CommunityConnection, community_manager,
};
use futures::StreamExt; use futures::StreamExt;
use std::sync::Arc; use std::sync::Arc;
use tokio::net::TcpListener; use tokio::net::TcpListener;
@ -23,7 +21,7 @@ pub async fn start(port: u16) -> bool {
}; };
let ws_stream = match accept_hdr_async(stream, callback).await { let ws_stream = match accept_hdr_async(stream, callback).await {
Ok(ws) => ws, Ok(ws) => ws,
Err(e) => { Err(_) => {
return; return;
} }
}; };
@ -48,7 +46,7 @@ pub async fn start(port: u16) -> bool {
return; return;
} }
} }
Some(Err(e)) => { Some(Err(_)) => {
community_conn.handle_close().await; community_conn.handle_close().await;
return; return;
} }

View file

@ -2,7 +2,6 @@ use crate::{
communities::{community::Community, interactables::interactable::Interactable}, communities::{community::Community, interactables::interactable::Interactable},
data::communication::{CommunicationType, CommunicationValue}, data::communication::{CommunicationType, CommunicationValue},
}; };
use axum::Json;
use json::JsonValue; use json::JsonValue;
use std::any::Any; use std::any::Any;
use std::sync::Arc; use std::sync::Arc;
@ -96,11 +95,11 @@ impl Interactable for Category {
let mut v = JsonValue::new_object(); let mut v = JsonValue::new_object();
v["children"] = JsonValue::new_array(); v["children"] = JsonValue::new_array();
for child in &self.children { for child in &self.children {
v["children"].push(child.to_json()); let _ = v["children"].push(child.to_json());
} }
v v
} }
fn load(&mut self, community: Arc<Community>, path: String, name: String, json: &JsonValue) { fn load(&mut self, community: Arc<Community>, path: String, name: String, _json: &JsonValue) {
self.community = community; self.community = community;
self.name = name; self.name = name;
self.path = path; self.path = path;

View file

@ -1,11 +1,7 @@
use crate::{ use crate::{communities::community::Community, data::communication::CommunicationValue};
communities::community::Community,
data::communication::{CommunicationType, CommunicationValue},
};
use axum::Json;
use json::JsonValue; use json::JsonValue;
use std::any::Any;
use std::sync::Arc; use std::sync::Arc;
use std::{any::Any, pin::Pin};
pub type InteractableFactory = fn() -> Box<dyn Interactable>; pub type InteractableFactory = fn() -> Box<dyn Interactable>;

View file

@ -3,7 +3,6 @@ use crate::communities::interactables::category::Category;
use crate::communities::interactables::interactable::{Interactable, InteractableFactory}; use crate::communities::interactables::interactable::{Interactable, InteractableFactory};
use crate::communities::interactables::text_chat::TextChat; use crate::communities::interactables::text_chat::TextChat;
use crate::communities::interactables::voice_chat::VoiceChat; use crate::communities::interactables::voice_chat::VoiceChat;
use crate::gui::log_panel;
use crate::util::file_util; use crate::util::file_util;
use json::JsonValue; use json::JsonValue;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;

View file

@ -7,16 +7,10 @@ use crate::{
gui::log_panel::log_message, gui::log_panel::log_message,
util::file_util::{get_children, load_file, save_file}, util::file_util::{get_children, load_file, save_file},
}; };
use aes_gcm::aead::Payload;
use axum::Json;
use json::{JsonValue, array, object}; use json::{JsonValue, array, object};
use rustls::ClientConnection;
use std::sync::Arc; use std::sync::Arc;
use std::{any::Any, collections::HashMap}; use std::{any::Any, collections::HashMap};
use std::{ use std::{fs, pin::Pin};
fs::{self, File},
pin::Pin,
};
use uuid::Uuid; use uuid::Uuid;
pub struct TextChat { pub struct TextChat {
name: String, name: String,
@ -190,7 +184,7 @@ impl Interactable for TextChat {
JsonValue::new_object() JsonValue::new_object()
} }
fn run_function(&self, cv: CommunicationValue) -> CommunicationValue { fn run_function(&self, cv: CommunicationValue) -> CommunicationValue {
let ret: Pin<Box<dyn Future<Output = CommunicationValue> + Send>> = Box::pin(async move { let _: Pin<Box<dyn Future<Output = CommunicationValue> + Send>> = Box::pin(async move {
let payload = cv.get_data(DataTypes::payload).unwrap(); let payload = cv.get_data(DataTypes::payload).unwrap();
if cv.get_data(DataTypes::function).unwrap().as_str().unwrap() == "get_messages" { if cv.get_data(DataTypes::function).unwrap().as_str().unwrap() == "get_messages" {
let amount = payload["amount"].as_i64().unwrap(); let amount = payload["amount"].as_i64().unwrap();
@ -247,10 +241,9 @@ impl Interactable for TextChat {
CommunicationValue::new(CommunicationType::error) CommunicationValue::new(CommunicationType::error)
} }
fn to_json(&self) -> JsonValue { fn to_json(&self) -> JsonValue {
let mut v = JsonValue::new_object(); JsonValue::new_object()
v
} }
fn load(&mut self, community: Arc<Community>, path: String, name: String, json: &JsonValue) { fn load(&mut self, community: Arc<Community>, path: String, name: String, _: &JsonValue) {
self.community = community; self.community = community;
self.name = name; self.name = name;
self.path = path; self.path = path;

View file

@ -72,10 +72,10 @@ impl Interactable for VoiceChat {
CommunicationValue::new(CommunicationType::error) CommunicationValue::new(CommunicationType::error)
} }
fn to_json(&self) -> JsonValue { fn to_json(&self) -> JsonValue {
let mut v = JsonValue::new_object(); let v = JsonValue::new_object();
v v
} }
fn load(&mut self, community: Arc<Community>, path: String, name: String, json: &JsonValue) { fn load(&mut self, community: Arc<Community>, path: String, name: String, _json: &JsonValue) {
self.community = community; self.community = community;
self.name = name; self.name = name;
self.path = path; self.path = path;

View file

@ -393,14 +393,6 @@ impl CommunicationValue {
data, data,
} }
} }
pub fn ack_message(message_id: Uuid, sender: Uuid) -> CommunicationValue {
let mut cv = CommunicationValue::new(CommunicationType::message).with_id(message_id);
if let s = sender {
cv = cv.add_data(DataTypes::send_time, JsonValue::String(s.to_string()));
}
cv
}
pub fn forward_to_other_iota(original: &mut CommunicationValue) -> CommunicationValue { pub fn forward_to_other_iota(original: &mut CommunicationValue) -> CommunicationValue {
let receiver = Uuid::from_str( let receiver = Uuid::from_str(
&*original &*original
@ -420,7 +412,8 @@ impl CommunicationValue {
CommunicationValue::new(CommunicationType::message_other_iota) CommunicationValue::new(CommunicationType::message_other_iota)
.with_id(original.get_id()) .with_id(original.get_id())
.with_receiver(receiver.unwrap()) .with_receiver(receiver.unwrap())
.add_data( DataTypes::receiver_id, .add_data(
DataTypes::receiver_id,
JsonValue::String(receiver.unwrap().to_string()), JsonValue::String(receiver.unwrap().to_string()),
) )
.with_sender(sender.unwrap()) .with_sender(sender.unwrap())

View file

@ -1,12 +1,11 @@
use crate::util::file_util::{load_file, save_file}; use crate::util::file_util::{load_file, save_file};
pub fn check_eula() -> bool { pub fn check_eula() -> bool {
let eula = "By changing the value to \"true\" you agree to our end user license agreement and our terms of service!\ let eula = "By changing the value to \"true\" you agree to our end user license agreement and our terms of service!\
\nYou can find our Terms of service on https://docs.tensamin.methanium.net/legal/terms-of-service/.\ \nYou can find our Terms of service on https://docs.tensamin.net/legal/terms-of-service/.\
\neula=false"; \neula=false";
let file = load_file("", "eula.txt"); let file = load_file("", "eula.txt");
if(file.is_empty()){ if file.is_empty() {
save_file("", "eula.txt", eula); save_file("", "eula.txt", eula);
return false; return false;
} }
@ -20,8 +19,8 @@ pub fn check_eula() -> bool{
} }
} }
pub fn accept_eula() { pub fn accept_eula() {
let eula = "By changing the value to \"true\" you agree to some shit we say on our website IDK this shouldn't be public yet!\ let eula = "By changing the value to \"true\" you agree to our end user license agreement and our terms of service!\
\nYou also give us all rights to your soul, and we own your dog now.\ \nYou can find our Terms of service on https://docs.tensamin.net/legal/terms-of-service/.\
\neula=true"; \neula=true";
save_file("", "eula.txt", eula); save_file("", "eula.txt", eula);
} }

View file

@ -5,7 +5,6 @@ use crate::langu::language_manager::format;
use crate::langu::language_manager::from_key; use crate::langu::language_manager::from_key;
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes}; use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
use json::Array;
use ratatui::widgets::canvas::{Canvas, Line}; use ratatui::widgets::canvas::{Canvas, Line};
use ratatui::{ use ratatui::{
layout::{Constraint, Direction, Layout}, layout::{Constraint, Direction, Layout},
@ -96,8 +95,8 @@ pub fn setup() {
} }
let ram = (sys.used_memory() as f64 / sys.total_memory() as f64) * 100.0; let ram = (sys.used_memory() as f64 / sys.total_memory() as f64) * 100.0;
let mut total_received = 0u64; let total_received = 0u64;
let mut total_transmitted = 0u64; let total_transmitted = 0u64;
let delta_received = if last_total_received == 0 { let delta_received = if last_total_received == 0 {
0 0

View file

@ -1,7 +1,7 @@
use crate::util::file_util::{self, save_file}; use crate::util::file_util::save_file;
use json::{self, JsonValue}; use json::{self, JsonError, JsonValue};
pub fn create_languages() { pub fn create_languages() -> Result<(), JsonError> {
let mut frontend_messages = JsonValue::new_object(); let mut frontend_messages = JsonValue::new_object();
let mut omikron_messages = JsonValue::new_object(); let mut omikron_messages = JsonValue::new_object();
let mut button_texts = JsonValue::new_object(); let mut button_texts = JsonValue::new_object();
@ -9,40 +9,43 @@ pub fn create_languages() {
let mut debug_messages = JsonValue::new_object(); let mut debug_messages = JsonValue::new_object();
// FRONTEND // FRONTEND
frontend_messages.insert("get_chats", "User {} is loading conversations"); frontend_messages.insert("get_chats", "User {} is loading conversations")?;
frontend_messages.insert("message_get", "User {} is loading messages"); frontend_messages.insert("message_get", "User {} is loading messages")?;
frontend_messages.insert("get_communities", "User {} is loading communities"); frontend_messages.insert("get_communities", "User {} is loading communities")?;
frontend_messages.insert("client_connected", "Client {} connected"); frontend_messages.insert("client_connected", "Client {} connected")?;
frontend_messages.insert("add_conversation", "User {} added {}"); frontend_messages.insert("add_conversation", "User {} added {}")?;
frontend_messages.insert("message_send", "User {} sent a message")?;
// OMIKRON // OMIKRON
omikron_messages.insert( omikron_messages.insert(
"identification_response", "identification_response",
"IOTA identified on Omikron, {} users!", "IOTA identified on Omikron, {} users!",
); )?;
omikron_messages.insert("send_message_failed", "Failed to send message to Omikron")?;
// BUTTONS // BUTTONS
button_texts.insert("exit", "Exit"); button_texts.insert("exit", "Exit")?;
// GENERAL // GENERAL
general_texts.insert("iota_id", "IOTA ID: {}-####-####-####-############"); general_texts.insert("iota_id", "IOTA ID: {}-####-####-####-############")?;
general_texts.insert("user_id", "USER ID: {}"); general_texts.insert("user_id", "USER ID: {}")?;
general_texts.insert("user_ids", "USER IDS: {}"); general_texts.insert("user_ids", "USER IDS: {}")?;
general_texts.insert("setup_completed", "Launched"); general_texts.insert("user_load_failed", "Failed to load user data")?;
general_texts.insert("setup_completed", "Launched")?;
general_texts.insert( general_texts.insert(
"community_active", "community_active",
"Communities active on ws://0.0.0.0:{}/community/...", "Communities active on ws://0.0.0.0:{}/community/...",
); )?;
general_texts.insert( general_texts.insert(
"community_start_error", "community_start_error",
"Failed to start community socket on port {}!", "Failed to start community socket on port {}!",
); )?;
general_texts.insert( general_texts.insert(
"community_start_error_admin", "community_start_error_admin",
"Failed to start community socket on port {}! Run with admin privileges", "Failed to start community socket on port {}! Run with admin privileges",
); )?;
// DEBUG // DEBUG
debug_messages.insert("", ""); debug_messages.insert("", "")?;
save_file( save_file(
"languages/en_INT", "languages/en_INT",
"frontend.json", "frontend.json",
@ -68,4 +71,5 @@ pub fn create_languages() {
"general.json", "general.json",
&general_texts.to_string(), &general_texts.to_string(),
); );
Ok(())
} }

View file

@ -39,7 +39,7 @@ pub fn from_key(key: &str) -> String {
pub fn format(key: &str, args: &[&str]) -> String { pub fn format(key: &str, args: &[&str]) -> String {
let message = from_key(key); let message = from_key(key);
let mut formatted = String::new(); let mut formatted = String::new();
let mut parts = message.split("{}"); let parts = message.split("{}");
for (i, part) in parts.enumerate() { for (i, part) in parts.enumerate() {
formatted.push_str(part); formatted.push_str(part);
if i < args.len() { if i < args.len() {

View file

@ -29,8 +29,8 @@ use crate::util::config_util::CONFIG;
pub static APP_STATE: LazyLock<Arc<Mutex<AppState>>> = pub static APP_STATE: LazyLock<Arc<Mutex<AppState>>> =
LazyLock::new(|| Arc::new(Mutex::new(AppState::new()))); LazyLock::new(|| Arc::new(Mutex::new(AppState::new())));
#[tokio::main(flavor = "multi_thread", worker_threads = 8)]
#[tokio::main] #[allow(unused_must_use, dead_code)]
async fn main() { async fn main() {
// EULA // EULA
//if !eula_checker::check_eula() { //if !eula_checker::check_eula() {
@ -38,21 +38,31 @@ async fn main() {
// return; // return;
//} //}
// LANGUAGE PACK
if let Err(e) = language_creator::create_languages() {
println!("Language pack creation failed: {}", e);
return;
}
// UI // UI
log_panel::setup(); log_panel::setup();
ratatui_interface::launch(); if let Err(e) = ratatui_interface::launch() {
// LANGUAGE PACK println!("Ui launch failed: {}", &e.to_string());
language_creator::create_languages(); return;
}
// BASIC CONFIGURATION // BASIC CONFIGURATION
CONFIG.lock().unwrap().load(); CONFIG.lock().unwrap().load();
if !CONFIG.lock().unwrap().config.has_key("iota_id") { if !CONFIG.lock().unwrap().config.has_key("iota_id") {
CONFIG.lock().unwrap().change("iota_id", Uuid::new_v4()); CONFIG.lock().unwrap().change("iota_id", Uuid::new_v4());
CONFIG.lock().unwrap().save(); CONFIG.lock().unwrap().update();
} }
// USER MANAGEMENT // USER MANAGEMENT
user_manager::load_users().await;
if let Err(_) = user_manager::load_users().await {
log_message_trans("user_load_failed");
}
let mut sb = "".to_string(); let mut sb = "".to_string();
for up in user_manager::get_users() { for up in user_manager::get_users() {
sb = sb + "," + &up.user_id.to_string().as_str(); sb = sb + "," + &up.user_id.to_string().as_str();

View file

@ -1,5 +1,5 @@
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes}; use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
use crate::gui::log_panel::{log_cv, log_message}; use crate::gui::log_panel::{log_cv, log_message, log_message_trans};
use crate::users::contact::Contact; use crate::users::contact::Contact;
use crate::users::user_community_util::UserCommunityUtil; use crate::users::user_community_util::UserCommunityUtil;
use crate::util::chat_files; use crate::util::chat_files;
@ -80,7 +80,7 @@ impl OmikronConnection {
} }
} }
pub async fn send_message(&self, msg: String) { pub async fn send_message(&self, msg: String) {
Self::send_message_static(&self.writer, msg).await; Self::send_message_static(&self.writer, msg).await
} }
/// Listener for all incoming messages /// Listener for all incoming messages
@ -90,28 +90,37 @@ impl OmikronConnection {
WebSocketStream<MaybeTlsStream<TcpStream>>, WebSocketStream<MaybeTlsStream<TcpStream>>,
>, >,
) { ) {
let waiting = self.waiting.clone(); let waiting_out = self.waiting.clone();
let writer = self.writer.clone(); let writer_out = self.writer.clone();
let is_connected = self.is_connected.clone(); let is_connected_out = self.is_connected.clone();
let sel = self.clone(); let sel_out = self.clone();
tokio::spawn(async move { tokio::spawn(async move {
while let Some(msg) = read_half.next().await { while let Some(msg) = read_half.next().await {
let waiting = waiting_out.clone();
let writer = writer_out.clone();
let is_connected = is_connected_out.clone();
let sel = sel_out.clone();
tokio::spawn(async move {
match msg { match msg {
Ok(Message::Close(Some(frame))) => { Ok(Message::Close(Some(frame))) => {
log_message(format!("[Omikron] Closed: {:?}", frame)); log_message(format!("[Omikron] Closed: {:?}", frame));
*is_connected.lock().await = false; *is_connected.lock().await = false;
break; return;
} }
Ok(Message::Text(text)) => { Ok(Message::Text(text)) => {
let mut cv = CommunicationValue::from_json(&text); let mut cv = CommunicationValue::from_json(&text);
if cv.is_type(CommunicationType::pong) { if cv.is_type(CommunicationType::pong) {
sel.handle_pong(&cv, true).await; sel.handle_pong(&cv, true).await;
continue; return;
} }
// ************************************************ // // ************************************************ //
// Direct messages // // Direct messages //
// ************************************************ // // ************************************************ //
log_cv(&cv); log_cv(&cv);
if let Some(x) = waiting.lock().await.remove(&cv.get_id()) {
x(cv);
return;
}
if cv.is_type(CommunicationType::message_other_iota) { if cv.is_type(CommunicationType::message_other_iota) {
let sender_id = &cv.get_sender().unwrap(); let sender_id = &cv.get_sender().unwrap();
let receiver_id = &cv.get_receiver().unwrap(); let receiver_id = &cv.get_receiver().unwrap();
@ -126,7 +135,8 @@ impl OmikronConnection {
*sender_id, *sender_id,
cv.get_data(DataTypes::content).unwrap().as_str().unwrap(), cv.get_data(DataTypes::content).unwrap().as_str().unwrap(),
); );
let response = CommunicationValue::new(CommunicationType::message_live) let response =
CommunicationValue::new(CommunicationType::message_live)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(cv.get_receiver().unwrap()) .with_receiver(cv.get_receiver().unwrap())
.add_data( .add_data(
@ -146,22 +156,10 @@ impl OmikronConnection {
response.to_json().to_string(), response.to_json().to_string(),
) )
.await; .await;
continue; return;
} }
if cv.is_type(CommunicationType::message_send) { if cv.is_type(CommunicationType::message_send) {
/* DATA CONTAINER:
"sent_by_self": true,
"timestamp": unixTimestamp,
"files": [ // wenn keine files dann weglassen
{
"name": "<name>",
"id": "<uuid>",
"type": "[ image | image_top_right | file ]"
}
],
"content": "<enc markdown>"
*/
let my_id = cv.get_sender().unwrap(); let my_id = cv.get_sender().unwrap();
let other_id = Uuid::from_str( let other_id = Uuid::from_str(
&*cv.get_data(DataTypes::receiver_id).unwrap().to_string(), &*cv.get_data(DataTypes::receiver_id).unwrap().to_string(),
@ -177,8 +175,13 @@ impl OmikronConnection {
other_id, other_id,
&*cv.get_data(DataTypes::content).unwrap().to_string(), &*cv.get_data(DataTypes::content).unwrap().to_string(),
); );
let ack = CommunicationValue::ack_message(cv.get_id(), my_id); let ack = CommunicationValue::new(CommunicationType::message)
Self::send_message_static(&writer.clone(), ack.to_json().to_string()) .with_id(cv.get_id())
.with_receiver(my_id);
Self::send_message_static(
&writer.clone(),
ack.to_json().to_string(),
)
.await; .await;
let forward = CommunicationValue::forward_to_other_iota(&mut cv); let forward = CommunicationValue::forward_to_other_iota(&mut cv);
Self::send_message_static( Self::send_message_static(
@ -186,7 +189,7 @@ impl OmikronConnection {
forward.to_json().to_string(), forward.to_json().to_string(),
) )
.await; .await;
continue; return;
} }
if cv.is_type(CommunicationType::messages_get) { if cv.is_type(CommunicationType::messages_get) {
@ -214,9 +217,12 @@ impl OmikronConnection {
.with_receiver(my_id) .with_receiver(my_id)
.add_data(DataTypes::messages, messages); .add_data(DataTypes::messages, messages);
Self::send_message_static(&writer.clone(), resp.to_json().to_string()) Self::send_message_static(
&writer.clone(),
resp.to_json().to_string(),
)
.await; .await;
continue; return;
} }
if cv.is_type(CommunicationType::get_chats) { if cv.is_type(CommunicationType::get_chats) {
@ -226,9 +232,12 @@ impl OmikronConnection {
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(user_id) .with_receiver(user_id)
.add_data(DataTypes::user_ids, users); .add_data(DataTypes::user_ids, users);
Self::send_message_static(&writer.clone(), resp.to_json().to_string()) Self::send_message_static(
&writer.clone(),
resp.to_json().to_string(),
)
.await; .await;
continue; return;
} }
if cv.is_type(CommunicationType::add_chat) { if cv.is_type(CommunicationType::add_chat) {
@ -249,9 +258,12 @@ impl OmikronConnection {
let resp = CommunicationValue::new(CommunicationType::add_chat) let resp = CommunicationValue::new(CommunicationType::add_chat)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(user_id); .with_receiver(user_id);
Self::send_message_static(&writer.clone(), resp.to_json().to_string()) Self::send_message_static(
&writer.clone(),
resp.to_json().to_string(),
)
.await; .await;
continue; return;
} }
if cv.is_type(CommunicationType::add_community) { if cv.is_type(CommunicationType::add_community) {
@ -263,25 +275,35 @@ impl OmikronConnection {
cv.get_data(DataTypes::community_title).unwrap().to_string(), cv.get_data(DataTypes::community_title).unwrap().to_string(),
cv.get_data(DataTypes::position).unwrap().to_string(), cv.get_data(DataTypes::position).unwrap().to_string(),
); );
let resp = CommunicationValue::new(CommunicationType::add_community) let resp =
CommunicationValue::new(CommunicationType::add_community)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(cv.get_sender().unwrap()); .with_receiver(cv.get_sender().unwrap());
Self::send_message_static(&writer.clone(), resp.to_json().to_string()) Self::send_message_static(
&writer.clone(),
resp.to_json().to_string(),
)
.await; .await;
continue; return;
} }
if cv.is_type(CommunicationType::get_communities) { if cv.is_type(CommunicationType::get_communities) {
let resp = CommunicationValue::new(CommunicationType::get_communities) let resp =
CommunicationValue::new(CommunicationType::get_communities)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(cv.get_sender().unwrap()) .with_receiver(cv.get_sender().unwrap())
.add_array( .add_array(
DataTypes::communities, DataTypes::communities,
UserCommunityUtil::get_communities(cv.get_sender().unwrap()), UserCommunityUtil::get_communities(
cv.get_sender().unwrap(),
),
); );
Self::send_message_static(&writer.clone(), resp.to_json().to_string()) Self::send_message_static(
&writer.clone(),
resp.to_json().to_string(),
)
.await; .await;
continue; return;
} }
if cv.is_type(CommunicationType::remove_community) { if cv.is_type(CommunicationType::remove_community) {
@ -291,21 +313,26 @@ impl OmikronConnection {
.unwrap() .unwrap()
.to_string(), .to_string(),
); // needs UserCommunityUtil ); // needs UserCommunityUtil
let resp = CommunicationValue::new(CommunicationType::remove_community) let resp =
CommunicationValue::new(CommunicationType::remove_community)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(cv.get_sender().unwrap()); .with_receiver(cv.get_sender().unwrap());
Self::send_message_static(&writer.clone(), resp.to_json().to_string()) Self::send_message_static(
&writer.clone(),
resp.to_json().to_string(),
)
.await; .await;
continue; return;
} }
} }
Err(e) => { Err(e) => {
log_message(format!("[Omikron] Error: {}", e)); log_message(format!("[Omikron] Error: {}", e));
*is_connected.lock().await = false; *is_connected.lock().await = false;
break; return;
} }
_ => {} _ => {}
} }
});
} }
}); });
} }
@ -324,8 +351,12 @@ impl OmikronConnection {
) { ) {
let mut guard = writer.lock().await; let mut guard = writer.lock().await;
if let Some(writer) = guard.as_mut() { if let Some(writer) = guard.as_mut() {
writer.send(Message::Text(msg)).await; if let Ok(_) = writer.send(Message::Text(msg)).await {
writer.flush().await; if let Ok(_) = writer.flush().await {
return;
} }
} }
} }
log_message_trans("send_message_failed");
}
}

View file

@ -1,9 +1,7 @@
use crate::APP_STATE; use crate::APP_STATE;
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes}; use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
use crate::omikron::omikron_connection::OmikronConnection; use crate::omikron::omikron_connection::OmikronConnection;
use json::JsonValue;
use json::number::Number; use json::number::Number;
use std::sync::Arc;
use tokio::time::Instant; use tokio::time::Instant;
use uuid::Uuid; use uuid::Uuid;

View file

@ -7,18 +7,6 @@ pub struct Contact {
pub user_id: Option<Uuid>, pub user_id: Option<Uuid>,
pub user_name: Option<String>, pub user_name: Option<String>,
pub last_message_at: Option<i64>, pub last_message_at: Option<i64>,
pub user_status: UserStatus,
pub about: Option<String>,
}
#[derive(Debug, Clone)]
pub enum UserStatus {
Online,
Do_Not_Disturb,
WC,
Away,
User_Offline,
Iota_Offline,
} }
impl Default for Contact { impl Default for Contact {
@ -31,30 +19,16 @@ impl Default for Contact {
user_id: None, user_id: None,
user_name: None, user_name: None,
last_message_at: Some(now), last_message_at: Some(now),
user_status: UserStatus::User_Offline,
about: None,
} }
} }
} }
impl Contact { impl Contact {
pub fn new_with_time(last_message_at: i64, user_id: Uuid) -> Self {
Contact {
user_id: Some(user_id),
user_name: None,
last_message_at: Some(last_message_at),
user_status: UserStatus::User_Offline,
about: None,
}
}
pub fn new(user_id: Uuid) -> Self { pub fn new(user_id: Uuid) -> Self {
Contact { Contact {
user_id: Some(user_id), user_id: Some(user_id),
user_name: None, user_name: None,
last_message_at: None, last_message_at: None,
user_status: UserStatus::User_Offline,
about: None,
} }
} }
pub fn set_last_message_at(&mut self, p0: i64) { pub fn set_last_message_at(&mut self, p0: i64) {
@ -74,12 +48,6 @@ impl Contact {
} }
obj obj
} }
pub fn from_string(s: &str) -> Contact {
let parsed: JsonValue = JsonValue::from(s);
Self::from_json(&parsed)
}
pub fn from_json(o: &JsonValue) -> Contact { pub fn from_json(o: &JsonValue) -> Contact {
let user_id = o["user_id"].as_str().and_then(|s| Uuid::parse_str(s).ok()); let user_id = o["user_id"].as_str().and_then(|s| Uuid::parse_str(s).ok());
@ -91,51 +59,6 @@ impl Contact {
user_id, user_id,
user_name, user_name,
last_message_at, last_message_at,
user_status: UserStatus::User_Offline, // default
about: None,
} }
} }
pub fn info(&self) -> JsonValue {
let mut obj = self.to_json();
if let Some(id) = &self.user_id {
obj["user_id"] = JsonValue::from(id.to_string());
}
if let Some(name) = &self.user_name {
obj["user_name"] = JsonValue::from(name.as_str());
}
obj
}
// getters & setters
pub fn get_about(&self) -> Option<&String> {
self.about.as_ref()
}
pub fn set_about(&mut self, about: String) {
self.about = Some(about);
}
pub fn get_user_id(&self) -> Option<Uuid> {
self.user_id
}
pub fn set_user_id(&mut self, id: Uuid) {
self.user_id = Some(id);
}
pub fn get_user_name(&self) -> Option<&String> {
self.user_name.as_ref()
}
pub fn set_user_name(&mut self, name: String) {
self.user_name = Some(name);
}
pub fn get_user_status(&self) -> &UserStatus {
&self.user_status
}
pub fn set_user_status(&mut self, status: UserStatus) {
self.user_status = status;
}
} }

View file

@ -75,13 +75,6 @@ pub fn get_users() -> Vec<UserProfile> {
USERS.lock().unwrap().clone() USERS.lock().unwrap().clone()
} }
pub fn add_user(up: UserProfile) {
let mut users = USERS.lock().unwrap();
users.retain(|u| u.user_id != up.user_id);
users.push(up);
*UNIQUE.lock().unwrap() = true;
}
pub fn remove_user(user_id: Uuid) { pub fn remove_user(user_id: Uuid) {
let mut users = USERS.lock().unwrap(); let mut users = USERS.lock().unwrap();
users.retain(|u| u.user_id != user_id); users.retain(|u| u.user_id != user_id);

View file

@ -45,11 +45,7 @@ impl ConfigUtil {
pub fn update(&mut self) { pub fn update(&mut self) {
if self.unique { if self.unique {
let _ = self.save();
}
}
pub fn save(&self) {
save_file("", "config.json", &self.config.to_string()); save_file("", "config.json", &self.config.to_string());
} }
} }
}